使用OpenCV给灰度图像上色

5
我正在使用OpenNI和Kinect传感器进行某个项目。我想要给深度图中的用户像素上色。现在我的像素从白色到黑色,但我想要从红色到黑色。我尝试了alpha混合,但结果只是得到了从粉色到黑色的像素,因为我用addWeight函数将红色和白色相加得到了粉色。
这是我的实际代码:
layers = device.getDepth().clone();
cvtColor(layers, layers, CV_GRAY2BGR);

Mat red = Mat(240,320, CV_8UC3, Scalar(255,0,0));
Mat red_body; // = Mat::zeros(240,320, CV_8UC3);
red.copyTo(red_body, device.getUserMask());

addWeighted(red_body, 0.8, layers, 0.5, 0.0, layers);

设备的getDepth()函数返回深度图cv::Mat,getUserMask()函数返回用户像素cv::Mat(仅为白色像素)

有什么建议吗?

编辑: 还有一件事: 感谢sammy answer的回答,我已经做到了。但实际上,我的值不是从0到255,而是从(例如)123-220。

我将通过简单的for循环找到最小值和最大值(是否有更好的方法?),如何将我的值从min-max映射到0-255?


你取消选择了Sammy的答案吗?那是一个非常好的答案。我之前没有理解你想要如何给灰度图像上色。Mul是一个不错的解决方案。我认为在问题已经有正确答案的情况下,再添加另一个部分并等待更多回答是非常粗鲁的行为。更不用说最大值和最小值以及缩放都可以在参考资料中轻松查找了。 - Bobbi Bennett
2个回答

5

首先,OpenCV 的默认颜色格式是 BGR 而不是 RGB。因此,创建红色图像的代码应该如下:

Mat red = Mat(240,320, CV_8UC3, Scalar(0,0,255));

红黑色地图可以使用元素乘法而不是 alpha 混合。
Mat out = red_body.mul(layers, 1.0/255);

您可以使用以下方法找到矩阵M的最小值和最大值:
double minVal, maxVal;
minMaxLoc(M, &minVal, &maxVal, 0, 0);

您可以通过减去最小值并乘以一个因子来进行缩放。
double factor = 255.0/(maxVal - minVal);    
 M = factor*(M -minValue)

我也对BGR感到困惑。但nkint说结果是粉色的。真是让人费解。 - Bobbi Bennett
是的,我正在使用cv::Mat,但我将它们包装在gl纹理中进行绘制...嗯...实际上,我使用的框架自己做了这件事。 - nkint

3

有点笨拙且慢,但也许可以分割层,将 red_body 复制(使其成为一个单通道的 Mat,而不是 3 个),粘贴到红色通道,再将它们合并回层?

使用 reshape 可以更快地(就地)获得相同的效果:

layers = device.getDepth().clone();
cvtColor(layers, layers, CV_GRAY2BGR);

Mat red = Mat(240,320, CV_8UC1, Scalar(255)); // One channel
Mat red_body; 
red.copyTo(red_body, device.getUserMask());

Mat flatLayer = layers.reshape(1,240*320); // presumed dimensions of layer
red_body.reshape(0,240*320).copyTo(flatLayer.col(0));

// layers now has the red from red_body

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接