cornerSubPix

一、介绍

相机矫正中常用到角点或径向鞍点的亚像素精确位置: cornerSubPix,典型用法如下:

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        found, corners = cv2.findChessboardCorners(
            gray,
            grid_size,
            cv2.CALIB_CB_ADAPTIVE_THRESH +
            cv2.CALIB_CB_NORMALIZE_IMAGE +
            cv2.CALIB_CB_FILTER_QUADS
        )
        if found:
            term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.01)
            cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), term)
            cv2.drawChessboardCorners(img, grid_size, corners, found)

cornerSubPix opencv cornerSubPix说明

void cv::cornerSubPix	(	InputArray 	image,
InputOutputArray 	corners,
Size 	winSize,
Size 	zeroZone,
TermCriteria 	criteria 
)		
Python:
cv.cornerSubPix(	image, corners, winSize, zeroZone, criteria	) ->	corners

其原理来自于:
W FORSTNER. A fast operator for detection and precise location of distincs points, corners and center of circular features

cornerSubPix_第1张图片亚像素精确角点定位器基于,观察到从中心 q 到位于 q 邻域内的点 p 的每个向量都与 p 处的图像梯度正交,并受到图像和测量噪声的影响。
在这里插入图片描述其其中Dipi是q领域内点pi点处的图像梯度。因此需要找到一个q点,从而使ϵi最小。
在这里插入图片描述
其中梯度为q邻域内像素的梯度和。
该算法将邻域窗口的中心设置在这个新的中心 q 处,然后迭代直到中心保持在设定的阈值内。

疑问:
邻域内所有像素的梯度累加是否合理?

二、应用

要求:
(1)image 为单通道
(2)corner 要求N12 或N*2
(3)corner 值要求float32 不能为double

封装:
将该函数做一定的封装,如下:

def findCornerSubPix(gray,corner):
    corner = corner.astype(np.float32)

    corner=corner.copy()

    if gray.ndim==3:
        gray = cv2.cvtColor(gray,cv2.COLOR_BGR2GRAY)
    
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
    corner2 = cv2.cornerSubPix(gray,corner,(8,8),(-1,-1),criteria)

    return corner2

3 使用问题

报错1:

cv2.error: OpenCV(4.6.0) /io/opencv/modules/imgproc/src/cornersubpix.cpp:58: error: (-215:Assertion failed) count >= 0 in function 'cornerSubPix'

解决方案: corner 值要求float32 不能为double

你可能感兴趣的:(图像处理,计算机视觉,opencv,python)