python-3.x - 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.
解决方案
这很难理解,但我想我发现了这个问题:
你正在传递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
转换。
您还可以转换image
为uint8
如下:
kp, corners = orb.detectAndCompute(image.astype(np.uint8), None)
推荐阅读
- google-chrome - GWT:Chrome 浏览器中的某些屏幕太宽
- powershell - 如何使用 powershell 从服务器获取数据库备份路径?
- php - 无法在 000webhost 中使用会话变量
- php - 下载图片虽然.php - Wordpress
- python - Python 中的定义方法
- java - 为什么 ObjectOutputStream 用 DataOutputStream 写入 14 个字节而不是 8 个字节?
- java - 将现有活动添加到 TabActivity Android
- .net - vb.net中的货币值计算错误
- debugging - 调试 webOS TV 服务
- r - 在R中的列表中查找最接近的值