2013-06-25 2 views
2

У меня есть cv::Mat, который имеет следующий размер 480 x 640 x 32.Как получить доступ к данным из cv :: Mat

Не могли бы вы показать мне, как я могу получить доступ к данным в этой структуре? Предположим, что я хочу получить доступ к элементу с позиции [2, 2, 2]. Как я могу это сделать?

EDIT 1:

Я попытался с помощью этого template<typename T> const T& Mat::at(int i, int j, int k) const, но я получаю следующее сообщение об ошибке во время выполнения:

enter image description here

EDIT 2:

Вот как я используя код:

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

где toMat подробно описана ниже.

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; 
} 
+2

В чем вы определили/создали свой Мат? От этого зависит то, как вы должны называть функцию 'at'. Кроме того, разместите код, в котором вы вызываете функцию 'at' – Antonio

+0

cv :: Mat f (382,510,32); f = Utils :: toMat (функции); cout < (1,1,1); В основном, toMat, преобразовать mxArray в структуру cv :: mat – Simon

+0

Можете ли вы рассказать об этом 'Utils :: toMat'? Если вы можете опубликовать код, это еще лучше. Проблема там на 100%. – Antonio

ответ

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

Для начала, вы ошибались конструктор cv::Mathttp://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat: ваше значение 32 используется в качестве типа, ведущий к некоторому неопределенному поведению.

Вы должны использовать этот

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. 

Тогда ваши Utils::toMat функции выглядит очень сложным для отладки ... Я предлагаю вам прочитать немного больше о документации, и, возможно, что вы повторно реализовать инициализация (заполнение) вашей матрицы с использованием метода at:

f.at<double>(x,y,z) = ... 
+0

Почему этот метод не работает для простого изображения? Я пытаюсь прочитать простой образ, используя 'cv :: Mat image = imread (" D: \\ img.jpg ")', и я пытаюсь получить доступ к значению пикселя, используя следующую инструкцию: 'cout << image.at (1,1,1) << endl; 'Почему происходит сбой? Он возвращает ту же ошибку, что и в случае ошибки экрана печати из тела вопроса. – Simon

+0

@Simon Ответ очень прост: при использовании cv :: Mat :: at() вы должны иметь возможность правильно указать собственный тип cv :: Mat, который вы читаете.Для цветного изображения, 8-битовой глубины, вы должны использовать image.at (x, y), кстати: jpg-изображения имеют только 2 измерения. Это документация vec: http://docs.opencv.org/modules/core/doc/basic_structures.html#vec По теме «понимание родного типа внутри cv :: Mat», эта кулда будет интересной: http://stackoverflow.com/questions/10167534/how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv – Antonio

0

Вы можете использовать .at<element_type>(i,j,k);

с reference:

template<typename T> const T& Mat::at(int i, int j, int k) const