cornersubpix.cpp:58: error: (-215:Assertion failed) count >= 0 in function 'cv::cornerSubPix'

参考文章:https://blog.csdn.net/weixin_43837871/article/details/89296462

前言:

我也是刚开始要做关于OpenCV+Python实现照相机标定,也不是很理解,在网上找了很多关于照相机标定、棋盘标定、张正友标定法,才实现了相对应的功能,但是在过程当中也遇到到了一些问题,下面就是对这段代码遇到的相关解析。

运行环境:pyhton3.7、opencv-python-3.4.2.16、IDLE编译器

 测试条件:手机拍照、打印棋盘纸张(图像16张,建议15~20张内)、手机型号DIG-AL00

完整代码:

#coding:utf-8
import cv2
import numpy as np
import glob

# 找棋盘格角点
# 阈值
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#棋盘格模板规格
w = 9
h = 6
# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点

images = glob.glob('calib/*.png')
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    # 找到棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
    # 如果找到足够点对,将其存储起来
    if ret == True:
        cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        objpoints.append(objp)
        imgpoints.append(corners)
        # 将角点在图像上显示
        cv2.drawChessboardCorners(img, (w,h), corners, ret)
        cv2.imshow('findCorners',img)
        cv2.waitKey(1)
cv2.destroyAllWindows()

# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

# 去畸变
img2 = cv2.imread('calib/00169.png')
h,  w = img2.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # *比例参数
dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
# 根据前面ROI区域裁剪图片
#x,y,w,h = roi
#dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)

# 反投影误差
total_error = 0
for i in xrange(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
    total_error += error
print "total error: ", total_error/len(objpoints)
--------------------- 
作者:sylvester0510 
来源:CSDN 
原文:https://blog.csdn.net/u010128736/article/details/52875137 
版权声明:本文为博主原创文章,转载请附上博文链接!

以下是我做实验遇到错误的总结:

问题1.Traceback (most recent call last):
  File "E:\Python37_course\test5\mian.py", line 38, in <module>
    corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
cv2.error: OpenCV(3.4.2) C:\projects\opencv-python\opencv\modules\imgproc\src\cornersubpix.cpp:58: error: (-215:Assertion failed) count >= 0 in function 'cv::cornerSubPix'

这是因为我的角点个数超出范围,棋盘格大小为8*8,棋盘格焦点数应该为7*7,而我写成了8*8,所以数组超出以致于报错。

问题2:Traceback (most recent call last):
  File "E:\Python37_course\test5\mian.py", line 58, in <module>
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
cv2.error: OpenCV(3.4.2) C:\projects\opencv-python\opencv\modules\calib3d\src\calibration.cpp:3143: error: (-215:Assertion failed) ni == ni1 in function 'cv::collectCalibrationData'

这是因为objpoints和imgpoints中的条目数必须相同。创建一组8 * 8 = 64个objpoints,用于8x8交叉的棋盘,但你的实际棋盘有7 * 7= 49个交叉点。因此,在处理图像时,会出现objpoints和imgpoints列表会有不同的长度。需要修改objp的创建/初始化,使其具有7 * 7 = 49个点,其坐标对应于棋盘上的实际物理坐标。如果还出现同样的报错,就看一下代码这段:是否有加对ret进行角点判断。


cornersubpix.cpp:58: error: (-215:Assertion failed) count >= 0 in function 'cv::cornerSubPix'