Ask Your Question
1

how to access matrix with unknown number of channels ?

asked 2017-02-23 01:14:26 -0600

Nbb gravatar image

suppose i have this matrix

int nbChannels=48;
cv::Mat image2(cv::Size(480,640), CV_32FC(nbChannels))

i can access it this way i think

cv::Vec<float,48> data = image2.at<cv::Vec<float, 48> >(row,col)

but how do i access a certain row,col IF i am unaware of the number of channels it has ?

int channels = image2.channels();
cv::Vec<float,channels > data = image2.at<cv::Vec<float, channels > >(row,col)
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2017-02-23 02:24:36 -0600

LBerger gravatar image

May be I miss something in opencv. I didn't find a simple way to access data :

// 4 rows and 3 columns and 10 channels
vector<Mat> ch;
for (int c = 0; c< 10; c++)
{
    ch.push_back(Mat::zeros(4,3,CV_32FC1));
    for (int i=0;i<ch[c].rows;i++)
        for (int j=0;j<ch[c].cols;j++)
            ch[c].at<float>(i,j)=c*(i+j);
}

Mat w;
merge(ch,w);
//  w 4 rows and 3 columns and 10 channel
cout<<"Channels = "<<w.channels()<<"\n";
cout<<"w = "<<w<<"\n";
// I want row 1 column 2 and channel 3
cout<<"w((1,2) channels 3 = "<<w.ptr<float>(1)[2*w.channels()+3]<<endl;
edit flag offensive delete link more
2

answered 2017-02-23 03:26:49 -0600

kbarni gravatar image

updated 2017-02-23 03:53:26 -0600

The number of channels can be considered as a third dimension of your matrix; so you can treat it just like any other dimension (width, depth). With 3D Mat variables, your code becomes:

int dims[]={640,480,48};
Mat image2(3,dims,CV_32F);

Accessing an element (let's say, channel 30 of pixel 10,10):

float ch30=image2.at<float>(10,10,30);

As the matrix lines are continuous, you can also use line/element pointers. It's faster when you do an operation on the whole image or you want to access all the channels of a pixel. The following code gets a pointer to the line 10, the pixel (10,10) and the channel 30 of this pixel:

float *line10=(float*)image2.ptr(10);
float *pixel10=line10+10*image2.channels;
float ch30=pixel10[30];

[EDIT] Processing a whole image and a pixel in 3D Mat is pretty straightforward, but I put it here to give a complete answer (the multidimensional Mat isn't well detailed in the docs):

for(y=0;y<image2.rows;y++) {
    float *p=(float*)image2.ptr(y);
    for(pos=0;pos<image2.cols*image2.channels;pos++)
        p[pos]=1-p[pos];
}

And a pixel:

float *p=(float*)image2.ptr(y)+x*image2.channels;
for(c=0;c<image2.channels;c++) p[c]=1-p[c];
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-02-23 01:14:26 -0600

Seen: 3,657 times

Last updated: Feb 23 '17