首页 > 解决方案 > Python cv2 ORB检测和计算返回“输入图像中的通道数无效”

问题描述

我正在尝试从两个不同的图像中提取和匹配特征,但由于某种原因,“detectAndCompute”方法不适用于我的 orb 对象:orb = cv2.ORB_create() kp,corners = orb.detectAndCompute(image,None I正在传递单个灰度图像(函数 np.float32(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)) 的返回)。由于某种原因,程序返回以下错误: Traceback(最近一次调用最后一次):文件“ C:\Users\levxr\Desktop\Visual-positioning-bot-main\alloverlay.py",第 37 行,在 cv2.imshow("camera"+str(i),corn1.updateanddisplay()) 文件 "C:\ Users\levxr\Desktop\Visual-positioning-bot-main\features.py”,第 33 行,在 updateanddisplay dst = self.update(image=self.image) 文件“C:\Users\levxr\Desktop\Visual-positioning -bot-main\features.py",第 23 行,在更新 kp 中,角 = orb.detectAndCompute(image,None) cv2.error: OpenCV(4.4.0) c:\users\appveyor\appdata\local\temp\1\pip-req-build-95hbg2jt\opencv\modules\imgproc\src \color.simd_helpers.hpp:92:错误:(-2:未指定的错误)在函数'__cdecl cv::impl::anonymous-namespace'::CvtHelper<struct cv::impl::匿名命名空间'::Set<3,4,-1>,struct cv::impl::A0x2980c61a::Set<1,-1,-1>,struct cv::impl::A0x2980c61a::Set<0, 2,5>,2>::CvtHelper(const class cv::_InputArray &,const class cv::_OutputArray &,int)'

输入图像中的通道数无效:“VScn::contains(scn)”,其中“scn”为 1

该程序分为3个文件,alloverlay.py(主文件):

import sys
import cv2
import numpy as np
import features as corn
import camera as cali
cv2.ocl.setUseOpenCL(False)
#videoname = input("enter input")
videoname = "camera10001-0200.mkv"
try:
    videoname = int(videoname)
    cap = cv2.VideoCapture(videoname)
except:
    cap = cv2.VideoCapture(videoname)
videoname2 = "camera 20000-0200.mkv"
try:
    videoname = int(videoname)
    cap2 = cv2.VideoCapture(videoname)
except:
    cap2 = cv2.VideoCapture(videoname)
if cap.isOpened()and cap2.isOpened():
    ret1, image1 = cap.read()
    ret2, image2 = cap2.read()
    ret = [ret1, ret2]
    image = [np.float32(cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)), np.float32(cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY))]
    cali1 = cali.Calibrator()
    corn1 = corn.Corner_detector(image)
while cap.isOpened() and cap2.isOpened():
    ret[0], image[0] = cap.read()
    ret[1], image[1] = cap2.read()
    if ret:
        backupimg = image
        for i, img in enumerate(image):
            if cali1.calibrated:
                backupimg[i] = corn1.image = cali1.undistort(np.float32(cv2.cvtColor(image[i], cv2.COLOR_BGR2GRAY)), cali1.mtx, cali1.dist)
            else:
                backupimg[i] = corn1.image = np.float32(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
            cv2.imshow("camera "+str(i), corn1.updateanddisplay())
        image = backupimg
        print(ret, image)
        #cv2.imshow("test", image)
        key = cv2.waitKey(1)
        if key == ord("c"):
            cali1.calibrate(cali1.image)
        if cv2.waitKey(25) & 0xFF == ord("q"):
            break
    else:
        print("capture not reading")
        break
cap.release()

,camera.py(用于校准和不扭曲相机并三角测量点的相对位置的模块(此项目的不同部分,与此问题无关)):

import sys
import cv2
#import glob
import numpy as np
cv2.ocl.setUseOpenCL(False)
class Missing_calibration_data_error(Exception):
    def __init__():
        pass
class Calibrator():
    def __init__(self, image=None, mtx=None, dist=None, camera_data={"pixelsize":None, "matrixsize":None, "baseline":None, "lens_distance":None}, criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001), calibrated = False):
        self.criteria = criteria
        self.objpoints = []
        self.imgpoints = []
        self.objp = np.zeros((6*7,3), np.float32)
        self.objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
        self.image = image
        self.mtx = mtx
        self.dist = dist
        self.calibrated = calibrated
        self.pixelsize = camera_data["pixelsize"]
        self.matrixsize = camera_data["matrixsize"]
        self.baseline = camera_data["baseline"]
        self.lens_distance = camera_data["lens_distance"]
    def calibrate(self, image):
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, (7,6),None)
        if ret == True:
            self.objpoints.append(self.objp)
            corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),self.criteria)
            self.imgpoints.append(corners2)
            h,  w = image.shape[:2]
            ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
            self.mtx = mtx
            self.dist = dist
            self.calibrated = True
            return mtx, dist
    def undistort(self, image, mtx, dist):
        if dist == None or mtx == None or image == None:
            raise Missing_calibration_data_error
            h,  w = image.shape[:2]
        newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
        dst = cv2.undistort(image, mtx, dist, None, newcameramtx)
        x,y,w,h = roi
        dst = dst[y:y+h, x:x+w]
        return image
    def calculate_point_relative_position(self, point_location2d):
        angle = self.baseline/(point_location2d[left][x]-point_location2d[right][x])
        x = angle * (point_location2d[left][x]-self.matrixsize[0]/2)
        y = angle * (point_location2d[left][y]-self.matrixsize[1]/2)
        z = self.lens_distance * (1-angle/self.pixelsize)
        return [x, y, z]
´´´
, and features.py(module to detect and match the features, aparently where the issue happens):
´´´
import sys
import cv2
import numpy as np
cv2.ocl.setUseOpenCL(False)
class Unknown_algorythm_error(Exception):
    def __init__(self):
        pass
class No_image_passed_error(Exception):
    def __int__ (self):
        pass
class Corner_detector():
    def __init__(self, image, detectortype="ORB", corners=[]):
        self.corners = corners
        self.image = image
        self.detectortype = detectortype
    def update(self, image=None):
        if self.detectortype == "Harris":
            self.corners = cv2.cornerHarris(image, 3, 3, 0, 1)
        elif self.detectortype == "Shi-Tomasi":
            self.corners = cv2.goodFeaturesToTrack(image, 3, 3, 0, 1)
        elif self.detectortype == "ORB":
            orb = cv2.ORB_create()
            kp, corners = orb.detectAndCompute(image,None)
        elif self.detectortype == "SURF":
            minHessian = 400
            detector = cv2.features2d_SURF(hessianThreshold=minHessian)
            keypoints1, descriptors1 = detector.detectAndCompute(img1, None)
            keypoints2, descriptors2 = detector.detectAndCompute(img2, None)
        else:
            raise Unknown_algoryth_error
        return self.corners
    def updateanddisplay(self):
        dst = self.update(image=self.image)
        self.image[dst>0.01*dst.max()] = 0
        return self.image
class Feature_matcher():
    def __init__(self, matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_FLANNBASED)):
        self.matcher = matcher

´´´
Does anyone know how to fix this? I've been looking for the answer for quite a while but i only find the answer for when you're converting the image to grayscale and it doesnt work for me.



标签: python-3.xnumpycomputer-visioncv2orb

解决方案


这很难理解,但我想我发现了这个问题:
你正在传递orb.detectAndCompute一个 type 的图像np.float32

  • orb.detectAndCompute不支持类型的图像np.float32

重现问题:

以下“简单测试”重现了该问题:
代码示例将黑色(零)图像传递给orb.detectAndCompute

以下代码无异常通过(图像类型为np.uint8):

# image type is uint8:
image = np.zeros((100, 100), np.uint8)
orb = cv2.ORB_create()
kp, corners = orb.detectAndCompute(image, None)

以下代码引发异常,因为图像类型为np.float32

# image type is float32:
image = np.float32(np.zeros((100, 100), np.uint8))
orb = cv2.ORB_create()
kp, corners = orb.detectAndCompute(image, None)

引发异常:

输入图像中的通道数无效:


解决方案:

尽量避免np.float32转换。
您还可以转换imageuint8如下:

kp, corners = orb.detectAndCompute(image.astype(np.uint8), None)

推荐阅读