Reputation: 971
I wanted to code this RGB to grayscale convertor without any inbuilt Open-CV function. This is how my code looks like
import cv2 , numpy
def GrayConvertor(img):
rows , cols , layers = img.shape
matrix = numpy.zeros((rows , cols))
for i in range(rows):
for j in range(cols):
val = 0.114 * (img[i][j][0]) + 0.587 * (img[i][j][1]) + 0.299 * (img[i][j][2])
fraction = val - int(val)
if fraction >= 0.5:
matrix[i][j] = (int(val) + 1)
else:
matrix[i][j] = int(val)
cv2.imshow("gray" , matrix)
cv2.waitKey(0)
However it shows a blank image , Any ideas?
Upvotes: 3
Views: 2063
Reputation: 67497
When you create your matrix
array with np.zeros
it is, by default, assigned dtype=float
. So even though you round and convert your values to int
, when writing them into matrix
they get stored as float
s. If you read the docs for cv.imshow
you will find the following:
- If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].
So everything in your image is getting multiplied by 255, thus messing up your final result.
You can do two things:
matrix
, skip all the rounding, and divide your values by 255.matrix
with dtype='uint8'
and leave everything unchanged.There is also the fact that you are doing a very poor use of numpy's capabilities. The two options I gave you above, you can code with no loops or matrix assignments, as
rgb2k = np.array([0.114, 0.587, 0.299])
matrix_int = np.round(np.sum(img * rgb2k, axis=-1)).astype('uint8')
matrix_float = np.sum(img * rgb2k, axis=-1) / 255
Upvotes: 5
Reputation: 17025
try:
import cv2 , numpy
def GrayConvertor(img):
rows , cols , layers = img.shape
matrix = numpy.zeros((rows , cols))
for i in range(rows):
for j in range(cols):
val = 0.114 * (img[i][j][0]) + 0.587 * (img[i][j][1]) + 0.299 * (img[i][j][2])
matrix[i][j] = round(val)
cv2.imshow("gray" , matrix)
cv2.waitKey(0)
Upvotes: 0