user18725848
user18725848

Reputation: 1

Python grayscaling rgb image with percentage

I can find many codes that help to convert RGB image to a grayscale image. But none of them shows me how to grayscaling with adjustable percentage like CSS supports. https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/grayscale

img {
  filter: grayscale(25%);
}

Could you please guide me to build a function in python to return a grayscale image in rgb mode:

rgb_image = rgb_to_gray(rgb_img, percent = 0.25)

Thank you in advance!

Upvotes: 0

Views: 547

Answers (2)

fmw42
fmw42

Reputation: 53089

Here is another way to do that in Python/OpenCV. This example is 75% gray (and 25% original).

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread("firefox.jpg")

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# make gray into 3 channels
gray = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)

# blend gray with original
result = cv2.addWeighted(gray, 0.75, img, 0.25, 0)

# save results
cv2.imwrite('firefox_75pct_gray.jpg',result)

# show results
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

enter image description here

Upvotes: 0

Jeru Luke
Jeru Luke

Reputation: 21203

The idea provided by @fmw42 is the best way. However, you cannot use the grayscaled image as is in the function cv2.addWeighted(). Both the images used within the function must of the same dimensions. Since a grayscale converted image is of single dimension, it will throw an error Sizes of input arguments do not match.

So first lets create a possible grayscale image in three dimensions, it can be done as follows:

img = cv2.imread(image_path)

# split the image into three channels
b,g,r = cv2.split(img) 

# Formula for converting to grayscale single channel
#0.2989 * R + 0.5870 * G + 0.1140 * B 

r= 0.2989 * r 
g = 0.5870 * g 
b = 0.1140 * b 

res = b+g+r
# grayscale single channel image
res = res.astype(np.uint8)

# to obtain 3-channel grayscale image repeat res across 3 channels
gray = cv2.merge((res, res, res))

Now as mentioned we use cv2.addWeighted() function as follows:

# the percentage of gray ranges from 0 to 1.0
for i in np.arange(0.0, 1.1, 0.1):
    modified_img = cv2.addWeighted(gray, i, img, 1.0-i, 0)
    cv2.imshow('Toned image', modified_img) 

Results

Percentage: 0

enter image description here

Percentage: 30

enter image description here

Percentage: 70

enter image description here

Percentage :100

enter image description here

Upvotes: 1

Related Questions