简体   繁体   中英

How fast in Python change 3 channel rgb color image to 1 channel gray?

I have almost 40000 images in a 4D array containing raw pixel data - (number of examples, width, height, channels). Every image has width of 32 pixels, height of 32 pixels, and 3 channels for RGB colors. I want to change them to grayscale images (from 3 channels with rgb get 1 with intensity). How I can do it quite fast? My code:

import pickle
import cv2
training_file = "/train.p"

with open(training_file, mode='rb') as f:
train = pickle.load(f)
X_train = train['features']

def rgb2gray(rgb):
    r, g, b = rgb[0], rgb[1], rgb[2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
return gray

X_train_gray = X_train.copy()

for i in range (X_train_gray.shape[0]):
    for j in range (X_train_gray.shape[1]):
        for k in range (X_train_gray.shape[2]):
            rgb = X_train_gray[i,j,k]
            gray = rgb2gray(rgb)
            X_train_gray[i,j,k] = gray

print("X_train image data shape =", X_train.shape)
print("X_train_grey image data shape =", X_train_gray.shape)

Result:
X_train_grey image data shape = (40000, 32, 32, 3)
X_train_grey image data shape = (40000, 32, 32, 1)
It's good, but it takes a lot of time.

I also tried to use cv2:

X_train_gray = X_train[0].copy()
print("X_train_grey image data shape =", X_train_gray.shape)
X_train_gray = cv2.cvtColor(X_train_gray, cv2.COLOR_BGR2GRAY)
print("X_train_grey image data shape =", X_train_gray.shape)

Result:
X_train_grey image data shape = (32, 32, 3)
X_train_grey image data shape = (32, 32)
But I lose intensity and don't know how to get it.
So how in fast way I can change this images from 3 channel rgb to 1 channel gray?

if you can use PIL. It should be ok. I had RGB images and convert them:

from PIL import Image
img = Image.open("image_file_path") #for example image size : 28x28x3
img1 = img.convert('L')  #convert a gray scale
print(img1.size)
>> (28,28)

But the image doesn't have a channel

y = np.expand_dims(img1, axis=-1)
print(y.shape)
>> (28,28,1)

I had this Problem before.This is the Best way: Your code is correct but needs some more changes to be suitable for a grayscaled image. Here is the Code:

ii = cv2.imread("0.png")
gray_image = cv2.cvtColor(ii, cv2.COLOR_BGR2GRAY)
print(gray_image)
plt.imshow(gray_image,cmap='Greys')
plt.show()

and this is the result:

[[196 196 197 195 195 194 195 197 196 195 194 194 196 194 196 189 188 195 195 196 197 198 195 194 194 195 193 191] . . . [194 194 193 193 191 189 193 193 192 193 191 194 193 192 192 191 192 192 193 196 199 198 200 200 200 201 200 199]]

在此处输入图片说明 .

尝试使用:

cv::cvtColor(gray_img,color_img,CV_GRAY2BGR)

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