我已经提供了一个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
仅被填充大约一半,而另一半完全变黑,如下所示。图像似乎也略微伸展。
原始灰度图像:彩色图像:
如果我将内部for循环的边界更改为col < colorizedMat.cols*2
,则整个Mat会被着色,但是图像会非常拉伸。
如何使用自定义色彩图正确地着色灰度垫?非常感谢任何帮助!
图像很小,因为我收到的相机的分辨率为80x60。
答案 0 :(得分:3)
我看到的一些问题。
您的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/
如果您将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
。由于Vec3b
与Vec<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)
可能有帮助,可能没有。