Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV RGB single channel color regulation

Input A image is a full RGB image, Output B image is a the same image but with "adjusted" R values

I need to rescale the RGB value to be between 128 and 255, so that minor values than 128 are scaled to an upper value.

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 

but this keep getting a wrong value:

if red value is 255 = 255*127/255+128 should output 255 but return 128

Why this happen?

EDIT:

The color values don't need to be recalculated every time, Would it be better to prepare an array at the start with the range of values, then replace the current value with the one from the array?

ValuesForRed = [0]*255

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

how to replace the values in the array is now the problem...

should replace the corresponding value with the corresponding index

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

started new question at Python Opencv cv2.LUT() how to use

like image 918
user2239318 Avatar asked Jan 13 '14 14:01

user2239318


1 Answers

The other question that OP has is "how best to solve this problem?". This is how I would approach it. This is C++ code but you should be able to translate it to Python easily. This approach is fast and there is no need to convert matrices to CV_32F type.

  • Split input image into channels

    Mat input_image; //input image
    vector<Mat> split_image(3);
    split(input_image, split_image);
    Mat red = split_image[2];
    
  • Obtain mask_red, such that a location in mask_red is set to 255 if the corresponding location in red is between 129 and 255 (inclusive bounds), otherwise it is set to 0. This can be achieved with inRange() function.

    Mat mask_red;
    inRange(red, Scalar(129), Scalar(255), mask_red);
    
  • Now apply setTo() function to red to set all masked pixels to 255.

    red.setTo(Scalar(255), mask_red);
    
  • Merge the channels to form the final image.

    Mat output_image;   // output image
    merge(split_image, output_image);
    
like image 180
Alexey Avatar answered Oct 18 '22 11:10

Alexey