着色16位灰度垫仅产生图像的一半

时间:2017-03-16 01:14:33

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

我已经提供了一个16位灰度矩阵(Mat type = 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仅被填充大约一半,而另一半完全变黑,如下所示。图像似乎也略微伸展。

原始灰度图像:OriginalGreyScale彩色图像:Colorized

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

如何使用自定义色彩图正确地着色灰度垫?非常感谢任何帮助!

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

3 个答案:

答案 0 :(得分:3)

我看到的一些问题。

  1. 您的matGreyScale被声明为CV_16UC1。但是,您尝试使用matGreyScale.at<uchar>(cv::Point(col,row));访问其元素。这是不正确的,因为应使用matGreyScale.at<unsigned short>(...)访问CV_16UC1。这令人困惑,因为CV_16UC1听起来像#34; unsigned char&#34;但它真的&#34; 16位,无符号,通道= 1)&#34;。请参阅: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

答案 1 :(得分:1)

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

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

应该是CV_8UC3而不是CV_16UC3。由于Vec3bVec<uchar, 3>相同,因此您只需使用命令

更新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};

答案 2 :(得分:-1)

我不熟悉OpenCV。但是当我打电话Point()

时,我认为这是错误的顺序
Point_ (_Tp _x, _Tp _y)    
Template class for 2D points specified by its coordinates x and y.

更改您的代码,如:

Point(row,col)

可能有帮助,可能没有。