Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert image to grayscale with custom luminosity formula

Tags:

opencv

I have images containing gray gradations and one another color. I'm trying to convert image to grayscale with opencv, also i want the colored pixels in the source image to become rather light in the output grayscale image, independently to the color itself.

The common luminosity formula is smth like 0.299R+0.587G+0.114B, according to opencv docs, so it gives very different luminosity to different colors.

I consider the solution is to set some custom weights in the luminosity formula. Is it possible in opencv? Or maybe there is a better way to perform such selective desaturation?

I use python, but it doesnt matter

like image 828
allchemist Avatar asked Apr 22 '14 16:04

allchemist


People also ask

How do you convert an image to grayscale in image processing?

I = rgb2gray( RGB ) converts the truecolor image RGB to the grayscale image I . The rgb2gray function converts RGB images to grayscale by eliminating the hue and saturation information while retaining the luminance.

How is grayscale calculated from RGB?

The RGB scale is calibrated so that when a color's three red/green/blue numbers are equal, the color is a shade of gray. E.g. red=50 green=50 blue=50 is gray, without any bias towards red, green, or blue hue.

How do I convert RGB pixels to grayscale?

RGB images are converted to grayscale using the formula gray=(red+green+blue)/3 or gray=0.299red+0.587green+0.114blue if "Weighted RGB to Grayscale Conversion" is checked in Edit>Options>Conversions.

How do I convert an image to grayscale in OpenCV?

Method 1: Using the cv2.Import the OpenCV and read the original image using imread() than convert to grayscale using cv2. cvtcolor() function.


2 Answers

This is the perfect case for the transform() function. You can treat grayscale conversion as applying a 1x3 matrix transformation to each pixel of the input image. The elements in this matrix are the coefficients for the blue, green, and red components, respectively since OpenCV images are BGR by default.

im = cv2.imread(image_path)
coefficients = [1,0,0] # Gives blue channel all the weight
# for standard gray conversion, coefficients = [0.114, 0.587, 0.299]
m = np.array(coefficients).reshape((1,3))
blue = cv2.transform(im, m)
like image 155
Aurelius Avatar answered Jun 22 '23 19:06

Aurelius


So you have custom formula,

Load source,

Mat src=imread(fileName,1);

Create gray image,

Mat gray(src.size(),CV_8UC1,Scalar(0));

Now in a loop, access BGR pixel of source like,

Vec3b bgrPixel=src.at<cv::Vec3b>(y,x); //gives you the BGR vector of type cv::Vec3band will be in row, column order

bgrPixel[0]= Blue//
bgrPixel[1]= Green//
bgrPixel[2]= Red//

Calculate new gray pixel value using your custom equation.

Finally set the pixel value on gray image,

 gray.at<uchar>(y,x) = custom intensity value // will be in row, column order
like image 24
Haris Avatar answered Jun 22 '23 18:06

Haris