为什么在使用Python的OpenCV中,SIFT算法不能处理8位图像(JPEG)?

4

我对于其他所有24位的JPEG图像使用SIFT都没有任何问题,但是8位的图片总是给出以下错误。

在函数cv::SIFT::operator ()中,图像为空或深度不正确(!=CV_8U)

有人知道如何处理吗?

这是我的代码:

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)

出现错误:“在函数cv::SIFT::operator()中,图像为空或深度不正确(! = CV_8U)。”


1
SIFT通常在灰度图像上执行,这些图像是8位的。您能发布代码吗? - chris
我刚刚添加了代码,非常感谢你的帮助。 - Joseph Yu
2个回答

4

编辑:在撰写本文时,我刚刚看到了imread中的灰度标志。尝试在读取图像时打印图像,因为听起来imread可能会悄悄失败并留下空的Mats。

cv2.SIFT.detectAndCompute只接受8位灰度图像,所以我不确定您是否真正在24位图像上使用SIFT而没有问题。

cv2.SIFT.detectAndCompute

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

所以在检测和提取之前,将图像转换为 8 位灰度:

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

当然那是一个愚蠢的位置,但你需要自己想清楚是否需要保留BGR原始文件等等。


1
我再次仔细检查了我的代码。cv2.imread(infile,0)以灰度模式读取图像。对于24位图像,它的效果很好。但对于8位图像,我甚至无法读取它们。我得到的只是“None”或“[]”。 - Joseph Yu
啊,听起来你声称在24位图像上运行SIFT。你应该分享一些你正在处理的图像样本。 - Christopher Peterson
1
抱歉让您等了一会儿。那些文件是GIF格式的!它失败了,因为OpenCV依赖于文件扩展名来知道如何读取文件,而它们被错误地命名为JPEG格式。 - Christopher Peterson
1
非常感谢!我将这些GIF文件保存为JPEG文件,现在一切都正常了! - Joseph Yu
1
好的回答,顺便提一下,你的链接已经失效了。 - DarkCygnus
显示剩余3条评论

2

我已经在这个stackoverflow帖子中对遇到相同错误的不同用户使用cv2.SIFT().detectAndCompute()代码进行了详细解答。

sift函数(至少是特别是.detectAndCompute()
只接受具有8位整数值的图像。

在对图像使用sift之前,可以使用以下内容将其转换为8位:
image8bit = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype('uint8')


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接