0

I want to read every images in a folder into one list and then greyscale every image. All the greyscale images should be in one list as well. Currently, I am able to read images to one list, but I am not able to put all the greyscale images into one list.

Here is my code:

import cv2
import numpy as np
from os import listdir
from os.path import isfile, join

mypath = 'jpl_thomas' 
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath,f)) ] 

images = np.empty(len(onlyfiles), dtype=object) 
for n in range(0, len(onlyfiles)):  
    images[n] =cv2.imread(join(mypath,onlyfiles[n]))

frames = np.zeros(len(images)) 
for i in range(0, len(images)):
    frames[i] = cv2.cvtColor(images[i],cv2.COLOR_BGR2GRAY)

The error i get is as the following:

File "main.python", line 21, in <module>
    frames[i] = cv2.cvtColor(images[i],cv2.COLOR_BGR2GRAY) 
    cv2.error: /Users/jenkins/miniconda/1/x64/conda-bld/conda_1486588158526/work/opencv-3.1.0/modules/imgproc/src/color.cpp:7456: 
    error: (-215) scn == 3 || scn == 4 in function ipp_cvtColor

I tried to debug small parts. frames[0] = cv2.cvtColor(images[0],cv2.COLOR_BGR2GRAY) returns the right value. But if I use for loop, the error above occurs.

thewaywewere
  • 8,128
  • 11
  • 41
  • 46
Judie
  • 81
  • 3
  • 10

1 Answers1

1

The following code reads all the color image files in mypath and converts them to gray scale images at the same time. color_images[] and gray_images[] are the two list holding the color and gray images.

from os import listdir
from os.path import isfile, join
import numpy as np
import cv2

mypath = './imageFiles/' 
onlyfiles = [fname for fname in listdir(mypath) if isfile(join(mypath,fname))] 

color_images = np.empty(len(onlyfiles), dtype=object)
gray_images = np.empty(len(onlyfiles), dtype=object)

for n in range(0, len(onlyfiles)):  
    color_images[n] =cv2.imread(join(mypath,onlyfiles[n]))
    gray_images[n] =cv2.imread(join(mypath,onlyfiles[n]),0)

# plot images in list[] for checking
for i in range(len(color_images)):
    plt.figure(i)
    plt.subplot(121), plt.imshow(color_images[i][:,:,::-1]), plt.title('color') 
    plt.subplot(122), plt.imshow(gray_images[i], cmap='gray'), plt.title('grayscale')
plt.show()

The sample plots below are the image files put into _images[] which consist of the famous "Lena" and "Scenetext" image files under mypath.

enter image description here

Take note that, with OpenCV:

  1. Color image is stored in numpy as (height[0:n], width[0:m], channels[B,G,R]) and
  2. Gray scale image is only with one channel as (height[0:n], width[:0:m]).
  3. cv2.imread(filename[,flags]) converts color image to gray scale if the flags is set to 0. For more flags, see "read an image".

Hope this help.

thewaywewere
  • 8,128
  • 11
  • 41
  • 46
  • Your code works! Thank you for your detailed explanation. I have a further question. Why frames[i] = cv2.cvtColor(images[i],cv2.COLOR_BGR2GRAY) does not work in the 'for loop'? Why cvColor function works when I test one image separately, but does not work when I tried to put them in one list? What is the meaning of the error I got? Thank you! – Judie Apr 30 '17 at 03:40
  • @Judie The error tells the input image `image[i]` should have 3`[B,G,R]` or 4`[B,G,R,A]` channels before applying the function `cv2.cvtColor()`. You may check the image shape to ensure the input type is correct before applying the function by `height, width, channels = image[i].shape`. – thewaywewere Apr 30 '17 at 10:14
  • Thanks, I see. When I checked the image shape, I get ''NoneType' object has no attribute 'shape''. So I know that image[i] are nontype objects. I could not apply cvtColor function directly to image[i]. – Judie Apr 30 '17 at 15:58