关于C#:使用OpenCV cv::Mat.at函数时如何使用正确的类型名

How to use the correct type name when using OpenCV cv::Mat.at function

描述情况可能比描述问题容易得多。我使用 OpenCV 在 C 中使用以下两行代码:

1
2
std::cout <<"value near i,j:" << myMat(Rect(i,j,2,2)) << std::endl;
std::cout <<"value at i,j:" << myMat.at<double>(i,j) << std::endl;

我得到以下结果:

1
2
3
value near i,j: [34, 42;
  39, 44]
value at i,j: 24

我认为第一个值 (24) 中的第一个数字和第二行 (34) 中的值应该相等。 myMat 中的数据类型目前应定义为 CV_64F。我的结论是,从 OpenCV 数据类型转换为 C 原始类型时我做错了,因为我最初使用 CV_16S 时的值要差得多。那么我需要做什么样的更正才能正确访问 cv::Mat 构造中的值?

P.S: myMat 的创建和分配如下:

1
2
3
Mat yourMat, myMat;
[... yourMat is assigned ...]
Sobel(yourMat, myMat, CV_64F, 1, 0, 3, 1, 0, BORDER_DEFAULT);

P.S.2:我在这里发现了一个类似的问题,但那里的答案似乎只是分配中的一种解决方法。


你应该在第二行切换i,jmyMat.at<double>(j,i)

myMat(Rect(i,j,2,2)) 中,您正在使用 Rect 构造函数:

1
x, y, width, height

所以你的 Rect 的左上角在 (x,y) = (i, j) 中。但是,当您使用 .at 访问一个值时,您会使用 .at<Tp>(row, col) 访问它,这是 (x,y) 的倒数,因为 row = ycol = x.

所以你正在有效地读取位置 (y, x) = (j, i).

的值

使用 CV_16U 类型的矩阵时,您需要使用 .at<Tp> 访问它:

  • CV_16UC1 : m.at<ushort>
  • CV_16UC2 : m.at<Vec2w>
  • CV_16UC3 : m.at<Vec3w>
  • CV_16UC4 : m.at<Vec4w>

或者你可以使用:

  • Mat1w
  • Mat2w
  • Mat3w
  • Mat4w

并在没有 .at 的情况下访问矩阵,但只使用括号:m(r,c)