错误:( - 5)图像为空或函数cv :: SIFT :: operator()中的深度不正确(!= CV_8U)

时间:2018-05-11 18:36:37

标签: python-2.7 numpy opencv sift

我正在尝试运行在对象检测教程中找到的基本脚本。我已尝试过我能在网上找到的所有内容,但未能解决。已经尝试了将图像转换为CV_U8的不同建议方法。也使用8位图像作为输入,仍然没有进展。这是代码:

import cv2
import numpy as np
MIN_MATCH_COUNT=30

detector=cv2.SIFT()

FLANN_INDEX_KDITREE=0
flannParam=dict(algorithm=FLANN_INDEX_KDITREE,tree=5)
flann=cv2.FlannBasedMatcher(flannParam,{})

trainImg=cv2.imread("TrainingData/TrainImg.jpeg",0)
trainKP,trainDesc=detector.detectAndCompute(trainImg,None)

cam=cv2.VideoCapture(0)
while True:
    ret, QueryImgBGR=cam.read()
    QueryImg=cv2.cvtColor(QueryImgBGR,cv2.COLOR_BGR2GRAY)
    queryKP,queryDesc=detector.detectAndCompute(QueryImg,None)
    matches=flann.knnMatch(queryDesc,trainDesc,k=2)

    goodMatch=[]
    for m,n in matches:
        if(m.distance<0.75*n.distance):
            goodMatch.append(m)
    if(len(goodMatch)>MIN_MATCH_COUNT):
        tp=[]
        qp=[]
        for m in goodMatch:
            tp.append(trainKP[m.trainIdx].pt)
            qp.append(queryKP[m.queryIdx].pt)
        tp,qp=np.float32((tp,qp))
        H,status=cv2.findHomography(tp,qp,cv2.RANSAC,3.0)
        h,w=trainImg.shape
        trainBorder=np.float32([[[0,0],[0,h-1],[w-1,h-1],[w-1,0]]])
        queryBorder=cv2.perspectiveTransform(trainBorder,H)
        cv2.polylines(QueryImgBGR,[np.int32(queryBorder)],True,(0,255,0),5)
    else:
        print "Not Enough match found- %d/%d"%(len(goodMatch),MIN_MATCH_COUNT)
    cv2.imshow('result',QueryImgBGR)
    if cv2.waitKey(10)==ord('q'):
        break
cam.release()
cv2.destroyAllWindows()

这是错误:

enter image description here

我目前正在使用带有opencv2.4.11的conda环境。

1 个答案:

答案 0 :(得分:1)

筛选功能(至少是.detectAndCompute()
仅接受具有8位整数值的图像。

在图像上使用sift之前,请先使用
将其转换为8bit image8bit = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype('uint8')

详细信息
void SIFT_Impl::detectAndCompute(InputArray _image, ... )的源代码 包含用于检查数据是否为8bit int的异常检查。

if( image.empty() || image.depth() != CV_8U )
    CV_Error( Error::StsBadArg, "image is empty or has incorrect depth (!=CV_8U)" );

if( !mask.empty() && mask.type() != CV_8UC1 )
    CV_Error( Error::StsBadArg, "mask has incorrect type (!=CV_8UC1)" );

第二个检查仅适用于可选的“ InputArray _mask”争论,并且此掩码只能为CV_8UC1,这意味着它必须为CV_8U深度,并且只有1个通道(因此灰度级很大)。 / em>

opencv page defining basic structure上,深度级别CV_8U被定义为

  

CV_8U-8位无符号整数(0..255)

这意味着输入图像必须由值0-255的8位整数定义。

筛选功能仅在灰度下有效,因此输入也应为1通道。如果输入具有3个或4个通道而不是1个通道(例如RGB或带alpha的RGB),则sift将在运行其算法之前将输入图像转换为灰度。您可以在使用sift之前将自己转换为灰度

有关here的详细信息,请参见opencv如何定义图像深度(CV_8U)或类型(CV_8UC1)。

P.S。我是stackoverflow的新手,请让我知道我的格式有任何问题/建议。谢谢!