C++ 访问“中的矩阵元素”;垫;OpenCV C++;

C++ 访问“中的矩阵元素”;垫;OpenCV C++;,c++,matrix,opencv,C++,Matrix,Opencv,如何在OpenCV 2.0的新“Mat”类中按行、列访问元素?文档链接如下,但我无法理解它。 关于文档: 它说: (…)如果你知道矩阵元素 输入,例如,它是float,然后您可以 使用at()方法 也就是说,您可以使用: Mat M(100, 100, CV_64F); cout << M.at<double>(0,0); matm(100100,CV_64F); coutOCV不遗余力地确保您在不知道元素类型的情况下无法执行此操作,但是如果您想要一种易于编码但不是非

如何在OpenCV 2.0的新“Mat”类中按行、列访问元素?文档链接如下,但我无法理解它。

关于文档:

它说:

(…)如果你知道矩阵元素 输入,例如,它是float,然后您可以 使用at()方法

也就是说,您可以使用:

Mat M(100, 100, CV_64F);
cout << M.at<double>(0,0);
matm(100100,CV_64F);

coutOCV不遗余力地确保您在不知道元素类型的情况下无法执行此操作,但是如果您想要一种易于编码但不是非常有效的方式来不可知地读取它的类型,您可以使用

double val=mean(someMat(Rect(x,y,1,1)))[channel];

要做好这件事,你必须知道它的类型。at方法是一种安全的方法,但是如果正确地执行,直接访问数据指针通常会更快。

上面提供的想法很好。为了快速访问(如果您想制作实时应用程序),您可以尝试以下方法:

//suppose you read an image from a file that is gray scale
Mat image = imread("Your path", CV_8UC1);
//...do some processing
uint8_t *myData = image.data;
int width = image.cols;
int height = image.rows;
int _stride = image.step;//in case cols != strides
for(int i = 0; i < height; i++)
{
    for(int j = 0; j < width; j++)
    {
        uint8_t val = myData[ i * _stride + j];
        //do whatever you want with your value
    }
}
//假设从灰度文件中读取图像
Mat image=imread(“您的路径”,CV_8UC1);
//…做一些处理
uint8_t*myData=image.data;
int width=image.cols;
int高度=image.rows;
int _stride=image.step//以防感冒!=跨步
对于(int i=0;i

指针访问比Mat.at访问快得多。希望有帮助

根据@J.Calleja所说,你有两个选择

方法1-随机存取 如果您想随机访问Mat的元素,只需使用

Mat.at<data_Type>(row_num, col_num) = value;

for(int行=0;行
如果您在理解方法2的工作原理方面有任何困难,我可以从文章中的一篇博文中借用图片,这更直观、更容易理解

见下图

对于
cv::Mat_uumat
只需使用
Mat(行、列)
访问具有指定类型的矩阵元素更方便,因为您可以跳过模板规范。这一点也在报告中指出

代码:

cv::Mat1d mat0 = cv::Mat1d::zeros(3, 4);
std::cout << "mat0:\n" << mat0 << std::endl;
std::cout << "element: " << mat0(2, 0) << std::endl;
std::cout << std::endl;

cv::Mat1d mat1 = (cv::Mat1d(3, 4) <<
    1, NAN, 10.5, NAN,
    NAN, -99, .5, NAN,
    -70, NAN, -2, NAN);
std::cout << "mat1:\n" << mat1 << std::endl;
std::cout << "element: " << mat1(0, 2) << std::endl;
std::cout << std::endl;

cv::Mat mat2 = cv::Mat(3, 4, CV_32F, 0.0);
std::cout << "mat2:\n" << mat2 << std::endl;
std::cout << "element: " << mat2.at<float>(2, 0) << std::endl;
std::cout << std::endl;
mat0:
[0, 0, 0, 0;
 0, 0, 0, 0;
 0, 0, 0, 0]
element: 0

mat1:
[1, nan, 10.5, nan;
 nan, -99, 0.5, nan;
 -70, nan, -2, nan]
element: 10.5

mat2:
[0, 0, 0, 0;
 0, 0, 0, 0;
 0, 0, 0, 0]
element: 0

@sumit at()方法返回对元素的引用。您可以使用:M.at(0,0)=值;我敢肯定这个例子是有缺陷的。我相信at在内部执行不安全的强制转换,因此在uint矩阵上使用at和double将产生不希望的/损坏的结果。建议改正。@Catskul你是对的。文本很好,但是示例应该是CV_64F。我已经更正了。如果我不知道
Mat
的类型怎么办?@nn0p您可以使用Mat::type()方法来获取类型。指针访问成本与Mat.at完全相同(在发行版中编译时)。唯一的区别是断言,除非代码在调试模式下编译,否则断言是活动的。为什么指针访问要比
Mat.at
版本快得多?
cv::Mat1d mat0 = cv::Mat1d::zeros(3, 4);
std::cout << "mat0:\n" << mat0 << std::endl;
std::cout << "element: " << mat0(2, 0) << std::endl;
std::cout << std::endl;

cv::Mat1d mat1 = (cv::Mat1d(3, 4) <<
    1, NAN, 10.5, NAN,
    NAN, -99, .5, NAN,
    -70, NAN, -2, NAN);
std::cout << "mat1:\n" << mat1 << std::endl;
std::cout << "element: " << mat1(0, 2) << std::endl;
std::cout << std::endl;

cv::Mat mat2 = cv::Mat(3, 4, CV_32F, 0.0);
std::cout << "mat2:\n" << mat2 << std::endl;
std::cout << "element: " << mat2.at<float>(2, 0) << std::endl;
std::cout << std::endl;
mat0:
[0, 0, 0, 0;
 0, 0, 0, 0;
 0, 0, 0, 0]
element: 0

mat1:
[1, nan, 10.5, nan;
 nan, -99, 0.5, nan;
 -70, nan, -2, nan]
element: 10.5

mat2:
[0, 0, 0, 0;
 0, 0, 0, 0;
 0, 0, 0, 0]
element: 0