0
votes

I have a code for predicting dog breed after training on CNN model, I get the class index from the below function. I want to display an random image from the class idx folder obtained from the function.

    class_name = [item for item in loaders['train'].dataset.classes]

      def predict_dog_breed(img,model,class_names):
           image = Image.open(img).convert('RGB')
           transform = transforms.Compose([
                          transforms. RandomResizedCrop(224),
                          transforms.ToTensor(),
                         transforms.Normalize(mean=[0.485,0.456,0.406],
                         std=[0.229, 0.224, 0.225])])
           image = transform(image)
           test_image = image.unsqueeze(0)
           net.eval()
           output = net(test_image)
          idx = torch.argmax(output)
          a = random.choice(os.listdir("./dogImages/train/{}/".format (class_name[idx])))
          imshow(a)
          return class_name[idx]

When I tried to display the random image, I am getting the below error:

TypeError Traceback (most recent call last) in 1 for img_file in os.listdir('./images'): 2 image = os.path.join('./images', img_file) ----> 3 dog_or_human(image)

in dog_or_human(img) 5 plt.show() 6 if dog_detector(img) == True: ----> 7 predict_dog = predict_dog_breed(img, net, class_name) 8 print("Dog Detected!The breed is {}".format(predict_dog)) 9 elif face_detector(img) > 0:

in predict_dog_breed(img, model, class_name) 18 a = random.choice(os.listdir("./dogImages/train/{}/".format(class_name[idx]))) 19 print(a) ---> 20 imshow(a) 21 #subdir = ''.join(["/dogImages/train/", class_name[idx]]) 22 #print(file)

~/Library/Python/3.7/lib/python/site-packages/matplotlib/pyplot.py in imshow(X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, origin, extent, shape, filternorm, filterrad, imlim, resample, url, data, **kwargs) 2697 filternorm=filternorm, filterrad=filterrad, imlim=imlim, 2698 resample=resample, url=url, **({"data": data} if data is not -> 2699 None else {}), **kwargs) 2700 sci(__ret) 2701 return __ret

~/Library/Python/3.7/lib/python/site-packages/matplotlib/init.py in inner(ax, data, *args, **kwargs) 1808 "the Matplotlib list!)" % (label_namer, func.name), 1809 RuntimeWarning, stacklevel=2) -> 1810 return func(ax, *args, **kwargs) 1811 1812 inner.doc = _add_data_doc(inner.doc,

~/Library/Python/3.7/lib/python/site-packages/matplotlib/axes/_axes.py in imshow(self, X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, origin, extent, shape, filternorm, filterrad, imlim, resample, url, **kwargs) 5492 resample=resample, **kwargs) 5493 -> 5494 im.set_data(X) 5495 im.set_alpha(alpha) 5496 if im.get_clip_path() is None:

~/Library/Python/3.7/lib/python/site-packages/matplotlib/image.py in set_data(self, A) 632 if (self._A.dtype != np.uint8 and 633 not np.can_cast(self._A.dtype, float, "same_kind")): --> 634 raise TypeError("Image data cannot be converted to float") 635 636 if not (self._A.ndim == 2

TypeError: Image data cannot be converted to float

Any help on this would be appreciated!

1
can you please add imshow(a) and yeah, one more thing, is the output of a = random.choice(os.listdir("./dogImages/train/{}/".format (class_name[idx]))) is just an image name, like dog1.jpg or dog1.png ? - Anubhav Singh
Yes the output is an image name like /dogImages/train/Golden_retriever/Golden_retriever_067.jpg - user11619814
So this is an image path rather than an image file and is it because of this the error is popping up? - user11619814
I think it's just Golder_retriever_067.png, not full path to the image. Or, Am I wrong ? - Anubhav Singh
I don't yet. I will have to see imshow(a). Will you please update your above code to include imshow() function ? - Anubhav Singh

1 Answers

2
votes

So, I tried to reproduced the error in your code here and was successful in doing that. You are getting error because of these lines in your code:

a = random.choice(os.listdir("./dogImages/train/{}/".format(class_name[idx])))
imshow(a)

random.choice(os.listdir("./dogImages/train/{}/".format(class_name[idx]))) basically returns an image filename, which is a string. You are not reading the image, just passing the filename to imshow function, which is incorrect. Check below figures for clarification.

Code with error:

enter image description here

Code without error:

enter image description here

Hence, change your predict_do_breed function to following:

def predict_dog_breed(img,model,class_name):
    image = Image.open(img).convert('RGB')
    transform = transforms.Compose([transforms.RandomResizedCrop(224),
                                        transforms.ToTensor(),
                                        transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                                            std=[0.229, 0.224, 0.225])])
    image = transform(image)
    test_image = image.unsqueeze(0)
    net.eval()
    output = net(test_image)
    idx = torch.argmax(output)
    a = random.choice(os.listdir("./dogImages/train/{}/".format(class_name[idx])))
    print(a)
    img = cv2.imread("./dogImages/train/{}/".format(class_name[idx])+a)
    imshow(img)
    return class_name[idx]

In the above code, cv2.imread function has been used to read the image filename, outputted by random.choice(os.listdir("./dogImages/train/{}/".format(class_name[idx]))).