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:
grayimg = img
in Python does not create a copy of img
(the result is that grayimg
referencing img
). 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.