3

I have a cv::Mat which hase to following size 480 x 640 x 32.

Can you please show me how can I access the data within this structure? Let's say that I want to access the element from position [2, 2, 2]. How can I do this?

EDIT 1:

I have tried using this template<typename T> const T& Mat::at(int i, int j, int k) const but I receive the following runtime error :

enter image description here

EDIT 2:

Here is how I am using the code :

cv::Mat f(382,510,32); 
f=Utils::toMat(features); 
cout<<f.at<double>(1,1,1); 

where toMat is detailed bellow.

cv::Mat Utils::toMat( mxArray* p_)
{
mwSize ndims_= mxGetNumberOfDimensions(p_);
const mwSize* dims=mxGetDimensions(p_);
std::vector<int> d(dims, dims+ndims_);
int ndims = (d.size()>2) ? d.size()-1 : d.size();
int nchannels = (d.size()>2) ? *(d.end()-1) : 1;
int depth=CV_64F;
std::swap(d[0], d[1]);
cv::Mat mat(ndims, &d[0], CV_MAKETYPE(depth, nchannels));
// Copy each channel.
std::vector<cv::Mat> channels(nchannels);
std::vector<mwSize> si(d.size(), 0); // subscript index
int type = CV_MAKETYPE(depth, 1); // Source type
for (int i = 0; i<nchannels; ++i)
{
    si[d.size()-1] = i;
    void *pd = reinterpret_cast<void*>(
            reinterpret_cast<size_t>(mxGetData(p_))+
            mxGetElementSize(p_)*mxCalcSingleSubscript(p_, si.size(), &si[0]));
    cv::Mat m(ndims, &d[0], type, pd);
    // Read from mxArray through m
    m.convertTo(channels[i], CV_MAKETYPE(depth, 1));
}
cv::merge(channels, mat);
return  mat;
}
Simon
  • 4,999
  • 21
  • 69
  • 97
  • 2
    In which why did you define/create your Mat? The way you have to call the `at` function strongly depend from that. Also, post the code in which you call the `at` function – Antonio Jun 25 '13 at 19:59
  • cv::Mat f(382,510,32); f=Utils::toMat(features); cout<(1,1,1); Basically, toMat, transform an mxArray to a cv::mat structure – Simon Jun 25 '13 at 21:24
  • Can you tell something more about this `Utils::toMat`? If you can post the code is even better. The problem is 100% located there. – Antonio Jun 25 '13 at 21:28
  • I have added the code in the body of the question – Simon Jun 25 '13 at 21:55
  • Hmmmmm To start with, you got wrong the constructor of cv::Mat http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat : the value 32 is used as type! – Antonio Jun 25 '13 at 22:04
  • You have to use this Mat::Mat(int ndims, const int* sizes, int type) – Antonio Jun 25 '13 at 22:06

2 Answers2

6
> cv::Mat f(382,510,32);

To start with, you got wrong the constructor of cv::Mat http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat : your value 32 is used as type, leading to some undefined behaviour.

You have to use this

 Mat::Mat(int ndims, const int* sizes, int type)

 const int[] mySizes = {382,510,32}; //I hope I have written this correctly...
 cv::Mat f(3,mySizes,CV_64F). // You find CV_64 in the same documentation page.

Then, your Utils::toMat functions looks really complicated to debug... I suggest that you read a little bit more about the documentation, and possibly that you re-implement the initialization (filling) of your matrix using the at method:

 f.at<double>(x,y,z) = ...
Antonio
  • 19,451
  • 13
  • 99
  • 197
  • Why isn't this method working for a plain image? I am trying to read a simple image using `cv::Mat image = imread("D:\\img.jpg")` and I am trying to access a pixel value using the following instruction : `cout<(1,1,1)< – Simon Jun 29 '13 at 10:13
  • 1
    @Simon The answer is very simple: when you use the cv::Mat::at() you have to be able to specify correctly the native type of the cv::Mat you are reading. For a color image, 8 bit depth, you have to use image.at(x,y) by the way: jpg images have only 2 dimensions. This is the documentation of vec: http://docs.opencv.org/modules/core/doc/basic_structures.html#vec On the subject "understanding native type inside a cv::Mat", this coudl be interesting reading: http://stackoverflow.com/questions/10167534/how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv – Antonio Jul 01 '13 at 06:40
0

You can use .at<element_type>(i,j,k);

with reference:

template<typename T> const T& Mat::at(int i, int j, int k) const
fatihk
  • 7,789
  • 1
  • 26
  • 48