# Reinventing BGR to Grayscale OpenCV convert function in Python

For academic purposes I want to reinvent Blue Green Red to Grayscale function in Python. I am new to Python so I believe my code below can still be optimized.

import cv2
import numpy as np

data = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]], [
[0, 0, 0], [128, 128, 128], [255, 255, 255], ]], dtype=np.uint8)

rows = len(data)
cols = len(data)

grayed = []
for i in range(rows):
row = []
for j in range(cols):
blue, green, red = data[i, j]
gray = int(0.114 * blue + 0.587 * green + 0.299 * red)
row.append(gray)
grayed.append(row)
grayed = np.array(grayed, dtype=np.uint8)

print(data)
print(grayed)

wndData = "data"
wndGrayed = "greyed"

cv2.namedWindow(wndData, cv2.WINDOW_NORMAL)
cv2.imshow(wndData, data)
cv2.namedWindow(wndGrayed, cv2.WINDOW_NORMAL)
cv2.imshow(wndGrayed, grayed)
cv2.waitKey()


Could you review my code above and make it much better?

• How is 0.114 * blue + 0.587 * green + 0.299 * red grey? I would expect grey to be blue/3 + green/3 + red/3 Jun 9, 2021 at 10:39
• @Reinderien: There are many algorithms to convert one color space to others. Jun 9, 2021 at 14:08

It appears that you are calculating linear combinations. If you are already using numpy, then the same can be achieved by broadcasting the dot product (with @):
import numpy as np

• Just another note that grayed = np.round(data @ coefficients).astype(np.uint8) will make the result identical to one produced by cv2.cvtColor function. Kevin from Phyton chat room found this solution. :-) Jun 9, 2021 at 15:22