问题
Trying to convert image from RGB color space to YDbDr color space according to the formula:
Y = 0.299R + 0.587G + 0.114B
Db = -0.45R - 0.883G +1.333B
Dr = -1.333R + 1.116G + 0.217B
With the following code I'm trying to show only Y channel which should be grayscale image but I keep getting image all in blue color:
import numpy as np
from PIL import Image
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("./pics/Slike_modela/Test/Proba/1_Color.png")
new_img = []
for row in img:
new_row = []
for pixel in row:
Y = 0.299*pixel[2]+0.587*pixel[1]+0.114*pixel[0]
Db = -0.45*pixel[2]-0.883*pixel[1]+1.333*pixel[0]
Dr = -1.333*pixel[2]+1.116*pixel[1]+0.217*pixel[0]
new_pixel = [Y, Db, Dr]
new_row.append(new_pixel)
new_img.append(new_row)
new_img_arr = np.array(new_img)
new_img_arr_y = new_img_arr.copy()
new_img_arr_y[:,:,1] = 0
new_img_arr_y[:,:,2] = 0
print (new_img_arr_y)
cv2.imshow("y image", new_img_arr_y)
key = cv2.waitKey(0)
When printing the result array I see correct numbers according to formula and correct shape of the array.
What is my mistake? How to get Y channel image i.e. grayscale image?
回答1:
When processing images with Python, you really, really should try to avoid:
treating images as lists and appending millions and millions of pixels, each of which creates a whole new object and takes space to administer
processing images with
for
loops, which are very slow
The better way to deal with both of these is through using Numpy
or other vectorised code libraries or techniques. That is why OpenCV, wand
, scikit-image
open and handle images as Numpy arrays.
So, you basically want to do a dot product of the colour channels with a set of 3 weights:
import cv2
import numpy as np
# Load image
im = cv2.imread('paddington.png', cv2.IMREAD_COLOR)
# Calculate Y using Numpy "dot()"
Y = np.dot(im[...,:3], [0.114, 0.587, 0.299]).astype(np.uint8)
That's it.
来源:https://stackoverflow.com/questions/64892808/python-convert-image-from-rgb-to-ydbdr-color-space