我已经提供了一个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 < colorizedMat.cols*2
,则完整的Mat会被着色,但是,图像会非常拉伸 .
如何使用自定义色彩图正确地着色灰度垫?任何帮助是极大的赞赏!
图像很小,因为我收到的相机具有80x60的分辨率 .
3 回答
我看到的一些问题 .
您的
matGreyScale
被声明为CV_16UC1 . 但是,您尝试使用matGreyScale.at<uchar>(cv::Point(col,row));
访问其元素 . 这是不正确的,因为应使用matGreyScale.at<unsigned short>(...)
访问CV_16UC1 . 这很令人困惑,因为CV_16UC1
听起来像"unsigned char"但它确实是"16-bit, unsigned, channels = 1)" . 见: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问题是您声明
colorizedMat
的深度不正确:它应该是
CV_8UC3
而不是CV_16UC3
. 由于Vec3b
与Vec<uchar, 3>
相同,因此只能使用命令更新colorizedMat.data
的一半另外,为了安全起见,将颜色贴图声明为
uchar
(或unsigned char
)类型:你的电话Point()我错了订单Point()
更改您的代码,如:
可能有帮助,可能不会 .