0

I was making an image recognition application and I had an error in the image reduction operation (resize) and i work on google colab here is my code

train_dir = '/content/drive/My Drive/training_set/training_set'
test_dir = '/content/drive/My Drive/test_set/test_set'

train_cats = os.path.join(train_dir, 'cats')

train_dogs = os.path.join(train_dir, 'dogs')

test_cats_dir = os.path.join(test_dir, 'cats')

test_dogs_dir = os.path.join(test_dir, 'dogs')

train_cats = os.listdir(train_cats)

train_dogs = os.listdir(train_dogs)

test_cats = os.listdir(test_cats_dir)

test_dogs = os.listdir(test_dogs_dir)

An example of an element in the training game


train_cats[1:10] 
['cat.3910.jpg',
 'cat.3330.jpg',
 'cat.3288.jpg',
 'cat.582.jpg',
 'cat.3498.jpg',
 'cat.3744.jpg',
 'cat.355.jpg',
 'cat.3604.jpg',
 'cat.3807.jpg']

An example of an element in the test game

test_cats[1:10]
['cat.4001.jpg',
 'cat.4008.jpg',
 'cat.4003.jpg',
 'cat.4021.jpg',
 'cat.4013.jpg',
 'cat.4019.jpg',
 'cat.4018.jpg',
 'cat.4009.jpg',
 'cat.4022.jpg']

Modification of the training game

size=4000 
train_imgs = train_dogs[0:size] + train_cats[0:size]
random.shuffle(train_imgs) 
print(train_imgs)

train_imgs[1:8] 
['dog.1302.jpg',
 'cat.1396.jpg',
 'cat.3158.jpg',
 'cat.2907.jpg',
 'cat.1769.jpg',
 'dog.568.jpg',
 'dog.1743.jpg']


img_size = 150


#### On définit une fonction qui prend en entrée une liste d'image
def read_and_process_image(list_of_images):
    """
    La fonctionne renvoie trois tableaux (array): 
        X est le tableau des images redimentionné (resize) 
        y est le ableau des cible (label) 
        l_id est un tableau qui contient les nom (chien, chat) pour la soumission du script kaggle 
    """
    X = [] # On initialise une liste qui comprendras les images
    y = [] # On initialise une liste qui comprendras les abels
    l_id = [] # On initialise une liste qui comprendras les id (dog, cat)


    #### Pour chaque élement de la liste d'image
    for image in list_of_images:
        ### On ajoute dans la liste X les images redimensionnés 


        X.append(cv2.resize(cv2.imread(image, cv2.IMREAD_COLOR), (img_size,img_size), interpolation=cv2.INTER_CUBIC))  #Lecture et redimensionnement de l'image
        basename = os.path.basename(image)# On stocke le chemin de chaque image dans la variable basename
        img_num = basename.split('.')[0] # On extrait le nom de l'animal ie 'dog' ou 'cat'
        l_id.append(img_num) ### On ajoute ce nom dans la liste l_id

        ### On crée un vecteur de cible y pour les modalités "dog" et "cat"
        if 'cat' in image: ### Si la chaine de caractère "dog" est contenu dans la liste "image" alors on ajoute un 1 à la liste y
            y.append(1)
        #### Sinon 0    
        else:
            y.append(0)

    return X, y, l_id #### On retourne trois élements, les images redimentionnés, le vecteur cible et l_id

#### On crée trois nouvelles variables qui correspondent aux images redimentionnégges, à la cible et a la liste de modalité kaggle
X, y, l_id = read_and_process_image(train_imgs)`

and here is the error that i get

 20 
     21 
---> 22         X.append(cv2.resize(cv2.imread(image, cv2.IMREAD_COLOR), (img_size,img_size), interpolation=cv2.INTER_CUBIC))  #Lecture et redimensionnement de l'image
     23         basename = os.path.basename(image)# On stocke le chemin de chaque image dans la variable basename
     24         img_num = basename.split('.')[0] # On extrait le nom de l'animal ie 'dog' ou 'cat'

error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/resize.cpp:3720: error: (-215:Assertion failed) !ssize.empty() in function 'resize'
op
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Neo
  • 43
  • 1
  • 2
  • 7

2 Answers2

1

Add a check to see if your image is empty:

Referece: https://stackoverflow.com/a/21596507/5671364

 Image = cv2.imread(image, cv2.IMREAD_COLOR)
 if (Image is not None and Image.size == 0):
     print("Error reading file")
     return -1

 X.append(cv2.resize(Image , (img_size,img_size), interpolation=cv2.INTER_CUBIC)) # Continue your work
Ganesh Kathiresan
  • 2,068
  • 2
  • 22
  • 33
  • `Image.cols` is from the C++ API of OpenCV. The Python interface uses NumPy arrays. Please change `Image.cols == 0` to what it's supposed to be. This code will crash upon running. – rayryeng Apr 28 '20 at 06:40
  • Please note that sometimes `cv2.imread` can return `None`, so `Image.size` will throw an error because there is no `size` attribute for a `None` type. I've removed my downvote, but be cognisant of this fact too. – rayryeng Apr 28 '20 at 09:10
  • Agreed, I think you have covered it pretty well in your answer, thanks. Upvoted yours – Ganesh Kathiresan Apr 28 '20 at 09:11
  • No problem at all. Have a vote from me. Thanks for the discussion! – rayryeng Apr 28 '20 at 09:12
  • Thank you for your reply I checked and it turned out that it is in the process of finding it empty the image list or when I list the contents of the list I find the images as indicated in the question above – Neo Apr 28 '20 at 11:01
1

What is most likely happening here is that you are referencing an image that does not exist, so what is returned from cv2.imread is None. You need to either correct the path to the affected file, or the image itself is corrupted thus returning None. You can simply check the image to see if it's None after you load it in. If it's None, skip the image and continue. Also note that sometimes if the image is corrupted, it can return a NumPy array of size 0, so check for None and check to see if it's a NumPy array of size 0:

    #### Pour chaque élement de la liste d'image
    for image in list_of_images:
        ### On ajoute dans la liste X les images redimensionnés 
        # Vérifiez si l'image fonctionne
        # Nouveau logique
        im = cv2.imread(image, cv2.IMREAD_COLOR)
        if type(im) is np.ndarray:
            if im.size == 0:
                continue
        if im is None:
            continue

        X.append(cv2.resize(im, (img_size,img_size), interpolation=cv2.INTER_CUBIC))  #Lecture et redimensionnement de l'image

        ....

Perhaps a more stringent check is to see if the file actually exists:

import os
...
...
    #### Pour chaque élement de la liste d'image
    for image in list_of_images:
        ### On ajoute dans la liste X les images redimensionnés 
        # Vérifiez si l'image fonctionne
        # Nouveau logique
        if not os.path.isfile(image):
            continue

        im = cv2.imread(image, cv2.IMREAD_COLOR)
        X.append(cv2.resize(im, (img_size,img_size), interpolation=cv2.INTER_CUBIC))  #Lecture et redimensionnement de l'image

        ....

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • None is not particularly right as well: https://stackoverflow.com/a/23628409/5671364 – Ganesh Kathiresan Apr 28 '20 at 08:33
  • @GaneshKathiresan Thanks - however sometimes `cv2.imread` can return `None` so checking for `im.size == 0` can still fail. I would suggest using both. Or even better is to check for the existence of the file too. – rayryeng Apr 28 '20 at 09:04
  • Yeah good point, I think checking if file is present is better. – Ganesh Kathiresan Apr 28 '20 at 09:10
  • thank you for your reply , I checked and it turned out that it is in the process of finding it empty the image list or when I list the contents of the list I find the images as indicated in the question above – Neo Apr 28 '20 at 11:01