OpenCV RGB 单通道颜色调节

Posted

技术标签:

【中文标题】OpenCV RGB 单通道颜色调节【英文标题】:OpenCV RGB single channel color regulation 【发布时间】:2014-02-01 08:41:28 【问题描述】:

输入图像是完整的 RGB 图像, 输出 B 图像是相同的图像,但具有“调整”的 R 值

我需要将 RGB 值重新缩放到 128 到 255 之间,以便将小于 128 的较小值缩放到较高值。

RMAX = 127

img = cv2.imread(filename)         # load img
blue, green, red = cv2.split(img)  # get single color

red = red*RMAX/255+128             # scale the color as I need 

但这总是得到错误的值:

如果红色值为 255 = 255*127/255+128 应该输出 255 但返回 128

为什么会这样?

编辑:

颜色值不需要每次都重新计算,是不是最好先准备一个数组,把值的范围,然后用数组中的那个替换当前值?

ValuesForRed = [0]*255

for i in range(0,255):
    ValuesForRed[i]=i*127 / 255 + 128

如何替换数组中的值现在是问题...

应该用对应的索引替换对应的值

i.e. red[45]= 0 
     ValuesForRed[0] = 128
     red[45]= 128

开始新问题 Python Opencv cv2.LUT() how to use

【问题讨论】:

您可以使用我第二个答案中的建议。它显示了如何在 C++ 中解决问题的分步方法。 Python 中的方法将是类似的。主要思想是使用inRange()函数(可用于Python OpenCV)来获取指定像素的图像的掩码,其值在129到255(含)之间。有关详细信息,请参阅第二个答案。 【参考方案1】:

发生这种情况是因为红色是 unsigned char,它是 0 到 255 范围内的数字。但是,您希望 red 表现得像整数。

所以考虑到

red = 255
red = red*127/255 + 128

当程序乘以 red*127 时,结果会溢出,因为它的值将大于 255,因此答案将是 0(因为 255*127 模 255 = 0)。因此你得到red = red*127/255 + 128 = (255*127 modulo 255) / 255 + 128 = 0 /255 + 128 = 128

要解决此问题,您可以在对其进行算术运算时将red 转换为浮点数,例如:

red = (float)red * 127 / 255

编辑 正如威廉red 所指出的那样,cv::Mat 类型为CV_8U。您可以将图像转换为CV_32F 类型进行计算,然后再将其转换回来。例如(这是 C++ 代码):

 Mat red_float;   
 red.convertTo(red_float,CV_32F);
 red_float = red_float*RMAX/255+128;
 red_float.convertTo(red,CV_8U);

【讨论】:

同意。还可以使用类型为 CV_32FC3 的辅助 cv::Mat 进行计算,然后使用 convertTo(,CV_8UC3) 将其转换为 uchar。 我使用的是 Python 2.7,我尝试过使用 int(red * 127 / 255 + 128) 但得到:TypeError:只有长度为 1 的数组可以转换为 Python 标量,所以我我试过用 abs(red * 127 / 255 + 128) 但它没有做转换仍然得到 128。 @user2239318 red 是一个矩阵。因此,您需要将矩阵转换为 CV_32F 类型,如答案第二部分所述(对于 C++)。由于您使用的是 Python,this answer 可能会有所帮助。 reds = np.int16(red) red= reds* 127 / 255 + 128 正确计算,但是当我合并新颜色时,我得到:cv2.error: /build/ opencv-Ai8DTy/opencv-2.4.6.1+dfsg/modules/core/src/convert.cpp:286: 错误:(-215) mv[i].size == mv[0].size && mv[i]。 depth() == 函数合并的深度 @user2239318 您的问题是“为什么会发生这种情况?”。我回答了。请更详细地告诉我您要达到的目标,或编辑您的问题,以便我可以更好地为您提供帮助。您也可以将其作为新问题发布。【参考方案2】:

OP 的另一个问题是“如何最好地解决这个问题?”。这就是我将如何处理它。这是 C++ 代码,但您应该能够轻松地将其转换为 Python。这种方式速度很快,无需将矩阵转换为CV_32F类型。

将输入图像分割成通道

Mat input_image; //input image
vector<Mat> split_image(3);
split(input_image, split_image);
Mat red = split_image[2];

获取mask_red,如果red中的对应位置在129和255之间(包括边界),则将mask_red中的位置设置为255,否则设置为0。这可以通过以下方式实现inRange()函数。

Mat mask_red;
inRange(red, Scalar(129), Scalar(255), mask_red);

现在将 setTo() 函数应用到 red 以将所有蒙版像素设置为 255。

red.setTo(Scalar(255), mask_red);

合并通道以形成最终图像。

Mat output_image;   // output image
merge(split_image, output_image);

【讨论】:

实际上我需要执行比例缩放,如果 inRange 在范围内,它似乎返回 255,如果经过验证,则类似于 true,而不是比例缩放,如果 0:128,如果 3:129 等...

以上是关于OpenCV RGB 单通道颜色调节的主要内容,如果未能解决你的问题,请参考以下文章

opencv图像混合,分离颜色通道多通道图像混合

学习 opencv--- 分离颜色通道 && 多通道混合

python-opencv-像素操作

opencv-python——2(颜色分割(RGBHSV)读取摄像头和视频并保存)

图像颜色--opencv scalar

opencv目标识别——HSV颜色识别