5

输入 A 图像是完整的 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() 如何使用开始新问题

4

2 回答 2

5

发生这种情况是因为 red 是unsigned char0 到 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);
于 2014-01-13T14:58:54.783 回答
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_redmask_red如果对应的位置在red129 和 255 之间(包括边界),则将位置设置为 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);
    
于 2014-01-14T14:54:45.160 回答