Converting an image to grayscale using numpy

13,249

Solution 1

Here is a working code:

def grayConversion(image):
    grayValue = 0.07 * image[:,:,2] + 0.72 * image[:,:,1] + 0.21 * image[:,:,0]
    gray_img = grayValue.astype(np.uint8)
    return gray_img

orig = cv2.imread(r'C:\Users\Jackson\Desktop\drum.png', 1)
g = grayConversion(orig)

cv2.imshow("Original", orig)
cv2.imshow("GrayScale", g)
cv2.waitKey(0)
cv2.destroyAllWindows()

Solution 2

You can use a dot product:

gray_image = image.dot([0.07, 0.72, 0.21])

Or even just do the whole operation manually:

b = image[..., 0]
g = image[..., 1]
r = image[..., 2]
gray_image = 0.21 * r + 0.72 * g + 0.07 * b

Don't forget to convert back to 0-255:

gray_image = np.min(gray_image, 255).astype(np.uint8)
Share:
13,249
thesamiroli
Author by

thesamiroli

Curious about almost everything

Updated on June 07, 2022

Comments

  • thesamiroli
    thesamiroli almost 2 years

    I have an image represented by a numpy.array matrix nxm of triples (r,g,b) and I want to convert it into grayscale, , using my own function.

    My attempts fail converting the matrix nxmx3 to a matrix of single values nxm, meaning that starting from an array [r,g,b] I get [gray, gray, gray] but I need gray.

    i.e. Initial colour channel : [150 246 98]. After converting to gray : [134 134 134]. What I need : 134

    How can I achieve that?

    My code:

    def grayConversion(image):
        height, width, channel = image.shape
        for i in range(0, height):
            for j in range(0, width):
                blueComponent = image[i][j][0]
                greenComponent = image[i][j][1]
                redComponent = image[i][j][2]
                grayValue = 0.07 * blueComponent + 0.72 * greenComponent + 0.21 * redComponent
                image[i][j] = grayValue
        cv2.imshow("GrayScale",image)
        return image
    
  • thesamiroli
    thesamiroli almost 6 years
    so, the result variable should be a grayscale image right ? or am i missing something because when I try to display it, it only shows white pixels everywhere.
  • Luca Cappelletti
    Luca Cappelletti almost 6 years
    Yes, but he asked for using his own custom function.
  • thesamiroli
    thesamiroli almost 6 years
    The image is still a 3-dimensional array.
  • Eric
    Eric almost 6 years
    You mean gray_image.ndim == 3? It's 2 on my machine
  • Eric
    Eric almost 6 years
    Your comment gives the misleading impression that this is better because it avoids a python loop - but a python loop is exactly what apply_along_axis does.
  • Luca Cappelletti
    Luca Cappelletti almost 6 years
    Eric Comment removed, you are right.
  • Luca Cappelletti
    Luca Cappelletti almost 6 years
    @thesamiroli I believe so. What does it happen when using the cv2 grayscale loading cv2.imread('smalltext.jpg',0)?
  • Jeru Luke
    Jeru Luke almost 6 years
    @LucaCappelletti This is not the point of the question. The OP wants to use numpy to convert an image to grayscale.