4

I used SIFT for all my other 24 bit JPEG images without any problems, however, the 8-bit one always give me the following error.

image is empty or has incorrect depth (!=CV_8U) in function cv::SIFT::operator ()

Does anyone know how to deal with it?

Here is my code:

import cv2 
import numpy as np 
import os 
import glob
import scipy.cluster
os.chdir('\mydirectory')
images = []

for infile in glob.glob('./*.jpg'):
  pic = cv2.imread(infile,0)
  images.append(pic)

my_set = images
descriptors = np.array([])
feaL=np.array([])

for pic in my_set:
  kp, des = cv2.SIFT().detectAndCompute(pic, None)
  feaL=np.append(feaL,des.shape[0])
  descriptors = np.append(descriptors, des)

Then the error "image is empty or has incorrect depth (!=CV_8U) in function cv::SIFT::operator ()" pops up.

Khashayar
  • 357
  • 3
  • 12
Joseph Yu
  • 133
  • 1
  • 2
  • 8

2 Answers2

4

EDIT: After typing this I just saw the grayscale flag on imread. Try printing the images as they are read in, it sounds like imread may be silently failing and leaving you with empty Mats.

cv2.SIFT.detectAndCompute never takes anything other than 8-bit grayscale, so I'm not sure that you actually did use SIFT on a 24-bit image without problems.

cv2.SIFT.detectAndCompute

Python: cv2.SIFT.detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]]) → keypoints, descriptors

So to change to 8 bit grayscale immediately prior to detection and extraction:

for pic in my_set:
    pic = cv2.cvtColor(pic, cv2.COLOR_BGR2GRAY)
    kp, des = cv2.SIFT().detectAndCompute(pic, None)

Of course that is a dumb place to put it, but it's up to you to figure out if you need to keep the BGR originals or not, etc.

nbro
  • 15,395
  • 32
  • 113
  • 196
Christopher Peterson
  • 1,570
  • 1
  • 10
  • 9
  • 1
    I double checked my code again. cv2.imread(infile,0) reads images in gray scale. It works good for 24 bit images. For 8 bit one, I couldn't even read them in. All I got is "None" or '[]'. – Joseph Yu Feb 19 '15 at 18:53
  • Ah, it sounded like you claimed to be running SIFT on 24 bit images. You should share samples of the images you are working with. – Christopher Peterson Feb 19 '15 at 19:17
  • Please see below dropbox link for 5 sample images. The images that I have problem with are named as "Bosses_pay_boost_beats_workers" and "High_oil_prices_boost_BPs_profit". Thank you again. https://www.dropbox.com/s/p19v81xzdmf7gq5/sample%20images.zip?dl=0 – Joseph Yu Feb 19 '15 at 19:54
  • 1
    Sorry I took a minute to get back. Those files are GIFs! It is failing because OpenCV relies on file extensions to know how to read a file, and they are misnamed as JPEGs. – Christopher Peterson Feb 21 '15 at 01:03
  • me@computermachine:~/sopython$ file High_oil_prices_boost_BPs_profit.jpg High_oil_prices_boost_BPs_profit.jpg: GIF image data, version 89a, 203 x 152 me@computermachine:~/sopython$ file Bosses_pay_boost_beats_workers.jpg Bosses_pay_boost_beats_workers.jpg: GIF image data, version 89a, 203 x 152 me@computermachine:~/sopython$ file 75-year-old_was_murdered_-_police_1843.jpg 75-year-old_was_murdered_-_police_1843.jpg: JPEG image data, JFIF standard 1.02 me@computermachine:~/sopython$ – Christopher Peterson Feb 21 '15 at 01:04
  • 1
    Thank you so much!!! I saved these GIFs as JPEG file and now everything is working! – Joseph Yu Feb 21 '15 at 18:48
  • 1
    Good answer, your link is broken BTW – DarkCygnus Oct 26 '17 at 23:57
  • @DarkCygnus just noticed this. better late than never I hope - fixed the link to go to the new docs! – Christopher Peterson Jan 29 '19 at 05:15
2

I answered a different user that encountered the same error while using cv2.SIFT().detectAndCompute() in-depth in this stackoverflow post.

The sift functions (at least specifically .detectAndCompute() )
ONLY accepts images with 8 bit integer values.

Before using sift on an image, convert it into 8bit using something like
image8bit = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype('uint8')

Alexander Mays
  • 276
  • 2
  • 6