简体   繁体   中英

Replacement of grayscale color with rgb color with open cv

I want to replace grayscale color with rgb color for each pixel. I am new to open cv.
GrayScale val = 25 replace by rgb value = 0,0,255

This is how to do it with a LUT:

I create some dummy image with grayscale values:

cv::Mat input = cv::Mat(512,512,CV_8UC1, cv::Scalar(0));
for(int j=0; j<input.rows; ++j)
    for(int i=0; i<input.cols; ++i)
    {
        input.at<unsigned char>(j,i) = i/2;
    }

Then I set up the LUT:

// create replacement look-up-table:
// 1. basic => gray values of given intensity
cv::Mat lookUpTable(1, 256, CV_8UC3);

for( int i = 0; i < 256; ++i)
    lookUpTable.at<cv::Vec3b>(0,i) = cv::Vec3b(i,i,i);

// 2. replace whatever colors you want:
lookUpTable.at<cv::Vec3b>(0,25) = cv::Vec3b(25,0,0);

lookUpTable.at<cv::Vec3b>(0,100) = cv::Vec3b(0,255,0); // means to replace each gray == (100) value by a (0,255,0) color value after LUT call
lookUpTable.at<cv::Vec3b>(0,115) = cv::Vec3b(255,0,0);
lookUpTable.at<cv::Vec3b>(0,200) = cv::Vec3b(0,100,255);

afterwards: convert input to COLOR and call LUT:

// unfortunately, we have to convert to color, because OpenCV doesnt allow LUT from single channel to 3 channel directly. (LUT must have same number of channels as input)
cv::Mat input_3channels;
cv::cvtColor(input, input_3channels, CV_GRAY2BGR);

cv::Mat output;
cv::LUT(input_3channels, lookUpTable, output);

Giving me that output for this input:

在此处输入图片说明

在此处输入图片说明

In your comments you like to replace "black" color by "red" color. You have to define what you mean by "black". In theory, black color is intensity = 0 and everything > 0 is just a very dark gray. So here I show how to set some ranges to a color:

cv::Mat lookUpTable(1, 256, CV_8UC3);

for( int i = 0; i < 256; ++i)
    lookUpTable.at<cv::Vec3b>(0,i) = cv::Vec3b(i,i,i);

// 2. replace "black color" by red:
// you have to define what black means. If you mean pure black (intensity == 0) then use this:
//lookUpTable.at<cv::Vec3b>(0,0 /* intensity == 0 */) = cv::Vec3b(0,0,255);

// if you mean something that appears mostly black for a human eye, use something like this:
unsigned char startIntensity = 0; // start at intensity 0 (black)
unsigned char endIntensity = 20; // the higher this value, the more "dark grey" will be replaced by red too
cv::Vec3b replacementColor = cv::Vec3b(0,0,255); // red
for(int i=startIntensity ; i < endIntensity ; ++i)
    lookUpTable.at<cv::Vec3b>(0,i) = replacementColor;

for example giving this result:

在此处输入图片说明

Here you have a small test code (the key is inRange ):

  1. create a rectangle in a gray image (with value of 25)
  2. create a mask where the 25 values are ( inRange )
  3. transform the gray image into color image
  4. change the value of the pixels where the mask is

     cv::Mat image = cv::Mat::zeros(cv::Size(200,200), CV_8U); //create zero image cv::rectangle(image, cv::Rect(50, 50, 100, 100), cv::Scalar::all(25), -1); //write a rectangle cv::imshow("image", image); //show image cv::Mat mask; cv::inRange(image,25,25,mask); //mask the 25 values cv::cvtColor(image, image, CV_GRAY2BGR); //convert gray image to BGR cv::Scalar red(0,0,255); image.setTo(red,mask); //change all 25 values into red color cv::imshow("colorImage", image); //show result image cv::waitKey(0); //wait until you press a key 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM