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

谁说我不能喝 提交于 2019-12-25 01:18:40

问题


I am trying to run basic script found on a tutorial for object detection. I have tried everything I could find on web but failed to solve it. Already tried different suggested methods to convert image to CV_U8. Also used 8 bit images as input, still without progress. Here is the code:

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()

Here is the error:

I am currently using conda environment with opencv2.4.11.


回答1:


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')

DETAILS
The source code of void SIFT_Impl::detectAndCompute(InputArray _image, ... ) contains exception checks that verifies the data is 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)" );

The second check only applies to the optional "InputArray _mask" arguement, and this mask can only be CV_8UC1 which means it must be CV_8U depth and only 1 channel (so much be greyscale).

On the opencv page defining basic structure , the depth level CV_8U is defined as

CV_8U - 8-bit unsigned integers ( 0..255 )

This means the input image must be defined by 8-bit integers with values 0-255.

The sift function only works in greyscale, so the input should be 1 channel as well. If the input has 3 or 4 channels instead of 1 (such as RGB, or RGB with alpha) , sift will convert the input image into greyscale before running its algorithm. You can convert to greyscale yourself before using sift with

More info on how opencv defines image depths (CV_8U) or types (CV_8UC1) can be found here.

P.S. I am new on stackoverflow, please let me know any problems/suggestions with my formatting. Thank you!



来源:https://stackoverflow.com/questions/50298329/error-5-image-is-empty-or-has-incorrect-depth-cv-8u-in-function-cvsift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!