遍历 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&lt;number of channels&gt;。详情见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);

然后用这个标量做任何你想做的事。 例如,如果您的 depthCV_8UC3 类型,距离编码在前两个字节(MSB 优先)中,您可以通过以下方式获得距离:

float distance = depthValue[0] * 255 + depthValue[1];

【讨论】:

以上是关于遍历 Mat的主要内容,如果未能解决你的问题,请参考以下文章

遍历 Mat

Opencv遍历Mat的方式

OpenCV学习C++接口 Mat像素遍历详解

OpenCV Mat遍历的方法

OpenCV Mat遍历的方法

遍历 arma::mat 并检索元素位置