【问题标题】:Colorizing 16 bit Greyscale Mat produces only half of image着色 16 位灰度垫仅产生一半的图像
【发布时间】:2017-08-07 00:13:44
【问题描述】:

我得到了一个 16 位灰度矩阵(Mat 类型 = CV_16UC1),我想使用 OpenCV 和存储在整数数组中的自定义颜色图渐变对其进行着色。颜色图包含 256 种 RGB 颜色,格式如下:

const int colormap[] = {R0, G0, B0, R1, G1, B1, ..., R255, G255, B255};

灰度矩阵的每个像素点包含一个无符号字符(0 到 255 之间),我将其用作索引以在 colormap 数组中查找相应的 RGB 颜色。

新的彩色 Mat 初始化为全黑,尺寸与灰度 Mat 相同,只是它是一个 3 通道矩阵。

cv::Mat colorizedMat = cv::Mat::zeros(matGreyScale.rows, matGreyScale.cols, CV_16UC3);

然后我使用下面的代码循环遍历colorizedMat 的每个像素,并使用从colormap 获得的 RGB 值更新它:

for (int row = 0; row < colorizedMat.rows; row++){
    for (int col = 0; col < colorizedMat.cols; col++) {
        int pixelVal = matGreyScale.at<uchar>(cv::Point(col,row));
        cv::Vec3b color(colormap[pixelVal*3+2],colormap[pixelVal*3+1],colormap[pixelVal*3]);
        colorizedMat.at<cv::Vec3b>(cv::Point(col,row)) = color;
    }
}

但是,这导致colorizedMat 仅填充了大约一半,而另一半则完全黑色,如下所示。图像也似乎有些拉伸。

原始灰度图: 彩色图:

如果我将内部 for 循环的边界更改为 col &lt; colorizedMat.cols*2,则整个 Mat 会被着色,但是,图像会被拉伸。

如何使用自定义颜色图正确为灰度 Mat 着色?非常感谢任何帮助!

图像很小,因为我接收它们的相机的分辨率为 80x60。

【问题讨论】:

    标签: c++ objective-c opencv image-processing colors


    【解决方案1】:

    我看到了一些问题。

    1. 您的 matGreyScale 被声明为 CV_16UC1。但是,您尝试使用matGreyScale.at&lt;uchar&gt;(cv::Point(col,row)); 访问其元素。这是不正确的,因为应该使用 matGreyScale.at&lt;unsigned short&gt;(...) 访问 CV_16UC1。这很令人困惑,因为CV_16UC1 听起来像“无符号字符”,但实际上是“16 位、无符号、通道 = 1)”。见:http://dovgalecs.com/blog/opencv-matrix-types/

    2. 如果您将colorizedMat 声明为CV_16UC3,您应该创建Vec3s 类型的向量来填充此矩阵。或者,您可以使用 Q.H.上面建议并将colorizedMat 声明为CV_8UC3 并坚持创建Vec3b 类型的向量(这更有意义,因为您的颜色映射数据缩放为0-255)。看: http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#vec

    【讨论】:

    • 感谢您的提示和链接。我使用 Vec3s 声明了向量并以这种方式填充了矩阵并接收了全宽矩阵
    【解决方案2】:

    问题是您声明 colorizedMat 的深度不正确:

    cv::Mat colorizedMat = cv::Mat::zeros(matGreyScale.rows, matGreyScale.cols, CV_16UC3);
    

    应该是CV_8UC3 而不是CV_16UC3。由于Vec3bVec&lt;uchar, 3&gt; 相同,因此您只需使用命令更新colorizedMat.data 的一半

    colorizedMat.at<cv::Vec3b>(cv::Point(col,row)) = color;
    

    另外,为了安全起见,将颜色映射声明为uchar(或unsigned char)类型:

    const uchar colormap[] = {R0, G0, B0, R1, G1, B1, ..., R255, G255, B255};
    

    【讨论】:

      【解决方案3】:

      我不熟悉 OpenCV。但是我觉得你打电话Point()时顺序不对

      Point_ (_Tp _x, _Tp _y)    
      Template class for 2D points specified by its coordinates x and y.
      

      更改您的代码,例如:

      Point(row,col)
      

      可能有帮助,也可能没有。

      【讨论】:

      • x 坐标将是列号,y 坐标将是行,因此 OP 代码中参数的顺序是正确的。此外,如果这两个交换,图像将被转置,而不是简单地切成两半。
      猜你喜欢
      • 2017-07-31
      • 2020-05-02
      • 2011-11-23
      • 2019-07-30
      • 2015-06-29
      • 2020-05-15
      • 1970-01-01
      • 2015-07-01
      相关资源
      最近更新 更多