输入图像是完整的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
答案 0 :(得分:5)
这是因为红色是unsigned char
,这是0到255范围内的数字。但是,您希望red
的行为类似于整数。
所以给出了
red = 255
red = red*127/255 + 128
当程序乘以红色* 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);
答案 1 :(得分: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
,如果mask_red
中的相应位置在129到255之间(包括边界),则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);