8

So I am trying to create a Python Program to detect similar details in two images using Python's OpenCV. I have the two images and they are in my current directory, and they exist (see the code in lines 6-17). But I am getting the following error when I try running it.

import numpy as np
import matplotlib.pyplot as plt
import cv2
import os

path1 = "WIN_20171207_13_51_33_Pro.jpg"
path2 = "WIN_20171207_13_51_43_Pro.jpg"

if os.path.isfile(path1):
    img1 = cv2.imread('WIN_20171207_13_51_33_Pro.jpeg',0)
else:
    print ("The file " + path1 + " does not exist.")

if os.path.isfile(path2):
    img2 = cv2.imread('WIN_20171207_13_51_43_Pro.jpeg',0)
else:
    print ("The file " + path2 + " does not exist.")

orb = cv2.ORB_create()

kpl1, des1 = orb.detectAndCompute(img1,None)
kpl2, des2 = orb.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x:x.distance)

img3 = cv2.drawMatches(img1,kpl1,img2,kpl2,matches[:10],None, flags=2)

plt.imshow (img3)
plt.show()

Here is the error I keep on getting...

Traceback (most recent call last):


File "C:\Users\jweir\source\repos\BruteForceFeatureDetection\BruteForceFeatureDetection\BruteForceFeatureDetection.py", line 31, in <module>
    plt.imshow (img3)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\pyplot.py", line 3080, in imshow
    **kwargs)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\__init__.py", line 1710, in inner
    return func(ax, *args, **kwargs)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\axes\_axes.py", line 5194, in imshow
    im.set_data(X)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\image.py", line 600, in set_data
    raise TypeError("Image data cannot be converted to float")
TypeError: Image data cannot be converted to float

Can someone please explpain to me why I am getting this error, what it means, and how to fix it.

1
  • I cannot reproduce your error, so I deleted my answer that I believed was the cause. Why is it that you check isfile(path1) and then you don't actually read path1? The extension is different on the images, why is that? What version of mpl are you using? Commented Dec 7, 2017 at 23:41

2 Answers 2

14

You're not actually reading in an image.

Check out what happens if you try to display None in matplotlib:

plt.imshow(None)
Traceback (most recent call last):  

 File ".../example.py", line 16, in <module>  
   plt.imshow(None)  
 File ".../matplotlib/pyplot.py", line 3157, in imshow  
   **kwargs)  
 File ".../matplotlib/__init__.py", line 1898, in inner  
   return func(ax, *args, **kwargs)  
 File ".../matplotlib/axes/_axes.py", line 5124, in imshow  
   im.set_data(X)  
 File ".../matplotlib/image.py", line 596, in set_data  
   raise TypeError("Image data can not convert to float")  

TypeError: Image data can not convert to float  

You're reading WIN_20171207_13_51_33_Pro.jpeg but you're checking if WIN_20171207_13_51_33_Pro.jpg exists. Note the different extensions. Why do you have the filename written twice (and differently)? Just simply write:

if os.path.isfile(path1):
    img1 = cv2.imread(path1, 0)
else:
    print ("The file " + path1 + " does not exist.")

Note that even if you put a bogus file into cv2.imread(), the resulting image will just be None, which doesn't error in any of the subsequent function calls until matplotlib tries to draw it. If you print(img1) after reading, you'll see it's None and not reading properly.

Sign up to request clarification or add additional context in comments.

6 Comments

Good catch, You probably should report this on opencv-python. +1
@user1767754 what do you mean? opencv-python is a pip package, but regardless, this isn't anything wrong with OpenCV (or matplotlib, which is the library issuing the exception here), it's user error. Python's model of execution is specifically to not check types, lengths, and so on and just try to do what the user wants. IMO this matplotlib error is very consistent with how Python is generally implemented. For e.g., see this excellent answer on Stack discussing exceptions in Python.
Code should be hard to break and easy to debug. When Code fails, it should give a good hint what went wrong, which isn't happening in OpenCV's case. I'm not saying that it isn't a user error, but the error is misleading. Pythons open method f = open('blub', 'r') checks for existence as well.
@user1767754 So you are saying that you think cv2.imread('some_bogus_file.ext') should error instead of returning None? That's something you can take up with the authors on a GitHub issue, but it is intended behavior. From the docs for imread() "The function imread loads an image from the specified file and returns it. If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function returns an empty matrix (Mat::data==NULL)."
@user1767754 and it's common in the OpenCV Python bindings to return None in those cases. I'm not trying to argue for/against either cause here but OpenCV is a C++ library, and when you call a function it passes through to the C++ functions. You should not expect Python errors to propagate through when these are just bindings to a library in another language. OpenCV chooses to not give an error when reading a file that doesn't exist as the documentation shows---again, if you want to raise that as an issue on their GitHub, feel free, but idk why we're talking about it, I didn't write it.
|
1

I do not know whether it is relevant with your case but since we assigning the file path in string type like cv2.imread("filepathHere"), if arguments like "\b" or "\r" occurs in the file path it causes program to pop an error such as this.

When I encountered such an error before, I changed the file name from file / brick.png to ibrick.png and the problem was resolved.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.