简体   繁体   中英

Greyscale Image python Implementation

I try to convert a RGB image to grayscale using python as a function but the problem is I give it a RGB image that have height, width and channel but after the code I should have an image with just height and width but it gives me an image with height, width and channel why?

def RGBtoGRAY(img):
    height, width, channels = img.shape
    grayimg = img
    for i in range(height):
        for j in range(width):
            grayimg[i,j] = 0.3 * image[i,j][0] + 0.59 * image[i,j][1] +  0.11 * image[i,j][2]
    return grayimg

the size of the input image is

image.shape 
(533, 541, 3)

the size of the output image is

grayimage.shape 
(533, 541, 3)

normally I want to find in the size of the output image

(533, 541)

You should avoid using for loops when performing image processing since it is very slow. Instead you can use Numpy which is highly optimized for vector operations. Using this grayscale conversion formula :

gray = R * .299 + G * .587 + B * .114

Method #1: apply_along_axis :

import cv2
import numpy as np

def grayscale(colors):
    r, g, b = colors
    return 0.299 * r + 0.587 * g + 0.114 * b

# Create image of size 100x100 of random pixels
# Convert to grayscale
image = np.random.randint(255, size=(100,100,3),dtype=np.uint8)
gray = np.apply_along_axis(grayscale, 2, image)

# Display
cv2.imshow('image', image)
cv2.imshow('gray', gray)
cv2.waitKey()

Before -> After

在此处输入图片说明 在此处输入图片说明

Method #2: cv2.cvtColor

You could use OpenCV directly and read in the image as grayscale with cv2.imread by passing in the cv2.IMREAD_GRAYSCALE or 0 flag to load the image as grayscale.

image = cv2.imread('img.png', cv2.IMREAD_GRAYSCALE) # OR
# image = cv2.imread('img.png', 0)

If you already have the image loaded, you can convert the RGB or BGR image to grayscale using cv2.cvtColor

image = cv2.imread('img.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Assuming you are using a for loop, because you intent to solve it "manually" (like C code), there are number of issues with your implementation:

  • The assignment grayimg = img in Python does not create a copy of img (the result is that grayimg referencing img ).
    You meant to use: grayimg = img.copy() .
  • img has 3 dimensions, so when using grayimg = img , grayimg also has 3 dimensions.
    You need to create grayimg with two dimensions.
    Example for creating grayimg and initialize to zeros:

     grayimg = np.zeros((height, width), img.dtype)
  • Inside the for loop, you are using image instead of img .

Here is a corrected version of RGBtoGRAY :

def RGBtoGRAY(img):
    height, width, channels = img.shape
    #grayimg = img
    # Create height x width array with same type of img, and initialize with zeros.
    grayimg = np.zeros((height, width), img.dtype)
    for i in range(height):
        for j in range(width):
            grayimg[i,j] = 0.3 * img[i,j][0] + 0.59 * img[i,j][1] +  0.11 * img[i,j][2]
    return grayimg

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM