3

I currently have a numpy array 'images' containing 2000 photos. I am looking for an improved way of converting all the photos in 'images' to gray scale. The shape of the images is (2000, 100, 100, 3). This is what I have so far:

# Function takes index value and convert images to gray scale 
def convert_gray(idx):
  gray_img = np.uint8(np.mean(images[idx], axis=-1))
  return gray_img

#create list
g = []
#loop though images 
for i in range(0, 2000):
  #call convert to gray function using index of image
  gray_img = convert_gray(i)
  
  #add grey image to list
  g.append(gray_img)

#transform list of grey images back to array
gray_arr = np.array(g)

I wondered if anyone could suggest a more efficient way of doing this? I need the output in an array format

J French
  • 187
  • 7
  • 1
    Does this answer your question? [How can I convert an RGB image into grayscale in Python?](https://stackoverflow.com/questions/12201577/how-can-i-convert-an-rgb-image-into-grayscale-in-python) – scleronomic Aug 31 '20 at 12:59

1 Answers1

4

With your mean over the last axis you do right now:

Gray = 1/3 * Red + 1/3 * Green + 1/3 * Blue

But actually another conversion formula is more common (See this answer):

Gray = 299/1000 * Red + 587/1000 * Green + 114/1000 * Blue

The code provided by @unutbu also works for arrays of images:

import numpy as np

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])

rgb = np.random.random((100, 512, 512, 3))
gray = rgb2gray(rgb)
# shape: (100, 512, 512)
scleronomic
  • 4,392
  • 1
  • 13
  • 43
  • You don't need the weird index. Just `rgb.dot(weights)` is fine. The original code just happens to use `np.ones(3) / 3`, which likely isn't properly normalized. – Mad Physicist Aug 31 '20 at 11:57
  • Also, given that your function is a verbatim copy of https://stackoverflow.com/a/12201744/2988730, I strongly suggest that you give proper attribution or vote to close as a duplicate. – Mad Physicist Aug 31 '20 at 11:59