opencv多渠道元素访问
我正在尝试学习如何使用openCV的新c ++接口。
如何访问多通道matrix的元素。 例如:
Mat myMat(size(3, 3), CV_32FC2); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { //myMat_at_(i,j) = (i,j); } }  什么是最简单的方法来做到这一点? 就像旧接口的cvSet2D一样 
 什么是最有效的方法? 类似于在旧界面中使用直接指针。 
谢谢
 typedef struct elem_ { float f1; float f2; } elem; elem data[9] = { 0.0f }; CvMat mat = cvMat(3, 3, CV_32FC2, data ); float f1 = CV_MAT_ELEM(mat, elem, row, col).f1; float f2 = CV_MAT_ELEM(mat, elem, row, col).f2; CV_MAT_ELEM(mat, elem, row, col).f1 = 1212.0f; CV_MAT_ELEM(mat, elem, row, col).f2 = 326.0f; 
更新:适用于OpenCV2.0
  1.select一种types来表示元素 
 垫(或CvMat)有3个维度:行,列,通道。 
 我们可以通过指定行和列来访问matrix中的一个元素(或像素)。 
  CV_32FC2表示该元素是具有2个通道的32位浮点值。 
 所以上面代码中的CV_32FC2是CV_32FC2一个可接受的表示。 
您可以使用其他表示方式。 例如 :
 typedef struct elem_ { float val[2]; } elem; typedef struct elem_ { float x;float y; } elem; 
OpenCV2.0增加了一些新的types来表示matrix中的元素,如:
 template<typename _Tp, int cn> class CV_EXPORTS Vec // cxcore.hpp (208) 
 所以我们可以使用Vec<float,2>来表示CV_32FC2 ,或者使用: 
 typedef Vec<float, 2> Vec2f; // cxcore.hpp (254) 
 查看源代码以获取更多可以表示元素的types。 
 这里我们使用Vec2f 
2.访问元素
 访问Mat类中元素的最简单有效的方法是Mat :: at。 
 它有4个重载: 
 template<typename _Tp> _Tp& at(int y, int x); // cxcore.hpp (868) template<typename _Tp> const _Tp& at(int y, int x) const; // cxcore.hpp (870) template<typename _Tp> _Tp& at(Point pt); // cxcore.hpp (869) template<typename _Tp> const _Tp& at(Point pt) const; // cxcore.hpp (871) // defineded in cxmat.hpp (454-468) // we can access the element like this : Mat m( Size(3,3) , CV_32FC2 ); Vec2f& elem = m.at<Vec2f>( row , col ); // or m.at<Vec2f>( Point(col,row) ); elem[0] = 1212.0f; elem[1] = 326.0f; float c1 = m.at<Vec2f>( row , col )[0]; // or m.at<Vec2f>( Point(col,row) ); float c2 = m.at<Vec2f>( row , col )[1]; m.at<Vec2f>( row, col )[0] = 1986.0f; m.at<Vec2f>( row, col )[1] = 326.0f; 
3.与旧界面交互
Mat提供了2个转换function:
 // converts header to CvMat; no data is copied // cxcore.hpp (829) operator CvMat() const; // defined in cxmat.hpp // converts header to IplImage; no data is copied operator IplImage() const; // we can interact a Mat object with old interface : Mat new_matrix( ... ); CvMat old_matrix = new_matrix; // be careful about its lifetime CV_MAT_ELEM(old_mat, elem, row, col).f1 = 1212.0f; 
维克你必须使用Vec3b而不是Vec3i:
 for (int i=0; i<image.rows; i++) { for (int j=0; j<image.cols; j++) { if (someArray[i][j] == 0) { image.at<Vec3b>(i,j)[0] = 0; image.at<Vec3b>(i,j)[1] = 0; image.at<Vec3b>(i,j)[2] = 0; } } } 
您可以直接访问底层数据数组:
 Mat myMat(size(3, 3), CV_32FC2); myMat.ptr<float>(y)[2*x]; // first channel myMat.ptr<float>(y)[2*x+1]; // second channel 
它取决于你正在使用的Mat的数据types,如果它是像CV_32FC1那样的数字,你可以使用:
 myMat.at<float>(i, j) 
如果它是一个uchartypes,那么你可以使用访问一个元素
 (symb.at<Vec3b>(i, j)).val[k] 
其中k是通道,灰度图像为0,彩色为3
使用c ++ api访问多通道数组的最好方法是使用ptr方法创build指向特定行的指针。
例如;
 type elem = matrix.ptr<type>(i)[N~c~*j+c] 
哪里
- 键入 :数据types(float,int,char ect ..)
- 我 :你感兴趣的行
- Nc :通道数
- j :你感兴趣的专栏
- c :你感兴趣的专栏(0-3)
有关其他C – > C + +转换信息检查出这个链接: 来源