Reputation: 1432
I know that in memory opencv represents Mat objects as one big array. So if I have 3 channels mat of dimension 200x200 then In memory it will store this mat in an array of size 3x200x200. Or more generally any Mat in memory will be stored as channels*rows*cols
. We can get such array as
double *array = (double)mat.data;
assuming that matrix is of type double
Now my question is what is the way to index this array for instance if I want to access element at channel ch, row r and col c is following is valid indexing
array[ch*rows*cols + c * rows + r]
or
array[ch*rows*cols + r * cols + c]
Regards Ahsan
Upvotes: 11
Views: 12074
Reputation: 518
I found other answers a bit confusing: mat.step
is the size of a row in bytes, not in (double) elements, and it does already take into consideration the number of channels. To access val you should use:
double* array = (double*) mat.data; // was (double) mat.data in the question
double value = array[ ((mat.step)/mat.elemSize1())*c+mat.channels()*r+ch]; // (mat.step)/mat.elemSize1() is the actual row length in (double) elements
You can verify this and other approaches comparing them with the .at<>
operator as follows:
#include <iostream>
#include <opencv2/core.hpp>
using namespace cv;
using namespace std;
int main()
{
const int w0=5;
const int h=3;
const int w=4;
double data[w0*h*3];
for (int y=0; y<h; y++)
for (int x=0; x<w0; x++)
for (int ch=0; ch<3; ch++)
data[3*(x+w0*y)+ch]=1000+100*(y)+10*(x)+ch;
Mat m0(h,w0,CV_64FC3, data);
Rect roi(0,0,w,h);
Mat mat=m0(roi);
int c=3, r=2, ch=1;
Vec3d v = mat.at<Vec3d>(r,c);
cout<<"the 3 channels at row="<<r<<", col="<<c<<": "<<v<<endl;
double* array= (double*) mat.data;
double expect = 1000+100*r+10*c+ch;
double value= array[ ((mat.step)/mat.elemSize1())*r+mat.channels()*c+ch];
cout<<"row="<<r<<", col="<<c<<", ch="<<ch<<": expect="<<expect<<", value="<<value<<endl;
return 0;
}
Upvotes: 1
Reputation: 41765
As you can see in the data layout reported on the documentation, you can access the values like:
for(int r=0; r<rows; ++r){
for(int c=0; c<cols; ++c){
for(int ch=0; ch<nchannels; ++ch){
double val = array[(nchannels*mat.step*r) + (nchannels*c) + ch];
}
}
}
Upvotes: 10
Reputation: 41
You can get values in array like this:
double val = array+ (r*mat.step)+c*mat.channels()+ch;
Upvotes: 1