遍历 Mat
Posted
技术标签:
【中文标题】遍历 Mat【英文标题】:Iterating through Mat 【发布时间】:2016-10-14 11:31:20 【问题描述】:我在遍历 OpenCV Mat
的坐标时遇到问题:
cv::Mat picture = cv::Mat(depth.rows, depth.cols, CV_32F);
for (int y = 0; y < depth.rows; ++y)
for (int x = 0; x < depth.cols; ++x)
float depthValue = (float) depth.at<float>(y,x);
picture.at<float>(y, x) = depthValue;
cv::namedWindow("picture", cv::WINDOW_AUTOSIZE);
cv::imshow("picture", picture);
cv::waitKey(0);
结果图片:
之前(深度)
之后(图片)
好像是 1. 缩放和 2.停在宽度的三分之一左右。有什么想法吗?
【问题讨论】:
深度也是 cv_32f 吗?请告诉我们它的定义 另外CV_32F
在此处无效。你应该使用CV_32FC<number of channels>
。详情见here
【参考方案1】:
看起来您的深度图像有 3 个通道。
BW 图像(B=G=R)
的所有通道值都相同,因此您使用BGRBGRBGR
而不是GrayGrayGray
,并且您尝试访问它,因为它是 1 个通道,这就是图像水平拉伸 3 倍的原因。
在运行循环之前尝试cv::cvtColor(depth,depth,COLOR_BGR2GRAY)
。
【讨论】:
大多数深度传感器返回 3 通道图像,深度编码为两个字节。转换色彩空间肯定会丢失一些数据,甚至更糟糕的是,会导致不再表示深度的奇怪结果。 正确的深度通道通常用 16 或 32 位通道(CV_16S 或 CV_32S)编码。但是这里我们有 CV_32F 所以,我们可以认为它是之前预处理过的。【参考方案2】:您的迭代代码是正确的。
问题在于 cv::Mat depth
类型假设。
如建议的那样,根据失真,这可能是CV_U8C3
。
要获取此类CV_8UC3
矩阵的像素值,您可以使用:
cv::Vec3i depthValue = depth.at<cv::Vec3i>(y,x);
然后用这个标量做任何你想做的事。
例如,如果您的 depth
是 CV_8UC3
类型,距离编码在前两个字节(MSB 优先)中,您可以通过以下方式获得距离:
float distance = depthValue[0] * 255 + depthValue[1];
【讨论】:
以上是关于遍历 Mat的主要内容,如果未能解决你的问题,请参考以下文章