Python cv2 ORB detectandcompute возвращает недопустимое количество каналов во входном изображении

Я пытаюсь извлечь и сопоставить функции из двух разных изображений, но по какой-то причине метод detectAndCompute не работает с моим объектом orb: orb = cv2.ORB_create () kp, corners = orb.detectAndCompute (image, None Я передаю одно изображение в градациях серого (возврат функции np.float32 (cv2.cvtColor (image, cv2.COLOR_BGR2GRAY))). По какой-то причине программа возвращает следующую ошибку: Traceback (последний вызов последнего): File 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, corners = 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: error: (-2: Unspecified er ror) в функции '__cdecl cv :: impl :: _ 1_anonymous namespace' :: 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.




person Лев Белый    schedule 11.04.2021    source источник


Ответы (1)


Сложно понять, но я думаю, что определил проблему:
Вы передаете orb.detectAndCompute изображение типа 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.
Вы также можете преобразовать image в uint8 следующим образом:

kp, corners = orb.detectAndCompute(image.astype(np.uint8), None)
person Rotem    schedule 11.04.2021