文章目录
这是官方教程的第四篇,OpenCV之图像特征检测,继续学习opencv。
原教程花了很大篇幅介绍图像的特征是什么含义,如何描述他们,并用“拼图”游戏来解释它们。简单说图像的特征就是一些边边角角、变化非常明显的区域,能在图片中明显定位的元素,然后用一些数据去描述这些特征。
Harris角点检测
Harris角点检测是Chris Harris和Mike Stephens在1988年提出的。主要用于运动图像的追踪。当时的普遍想法是利用边缘进行追踪,但是当相机或物体运动时你不知道朝哪个方向,相机的几何变换也是未知的,所以边缘匹配很难达到预期的效果。即使是当时最优秀的边缘检测算子Canny算子,它的边缘检测也依赖于阈值的选取。所以Harris等人放弃了匹配边缘,转而寻找一些特殊的点来匹配,这些点是边缘线段的连接点,它们表征了图像的结构,代表了图像局部的特征。
Harris角点检测
- 函数原型:dst = cv.cornerHarris( src, blockSize, ksize, k[, dst[, borderType]] )
- src:输入图像,单通道8bit灰度图像或者float32型的图像
- dst:角点检测后图像,图像类型为CV_32FC1,尺寸与原图一致
- blockSize:邻域尺寸大小
- ksize:sobel边缘检测窗口大小
- k:系数值,通常取值范围为0.04 ~ 0.06之间
- borderType:边沿像素推断方法,即边沿类型
import numpy as np
import cv2 as cv
filename = 'chessboard.png'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
cv.imshow('dst',img)
if cv.waitKey(0) & 0xff == 27:
cv.destroyAllWindows()
Corner with SubPixel Accuracy
Harris角点检测存在很多缺陷,如角点是像素级别的,速度较慢,准确度不高等
- 函数原型:corners = cv.cornerSubPix( image, corners, winSize, zeroZone, criteria )
- image:输入图像
- corners:输入的初始角点坐标集合,通常是Harris角点检测的结果,输出时修改为精确检测的检点坐标
- winSize:计算亚像素角点时考虑的区域的大小,大小为NXN; N=(winSize*2+1);For example, if winSize=Size(5,5) , then a 5∗2+1×5∗2+1=11×11 search window is used.
- zeroZone:类似于winSize,搜索窗口中dead region大小的一半,Size(-1,-1)表示忽略,主要用于避免自相关矩阵中可能的奇点(自己翻译,不明所以)
- criteria:评判规则,表示计算亚像素时停止迭代的标准,可选的值有cv::TermCriteria::MAX_ITER 、cv::TermCriteria::EPS(可以是两者其一,或两者均选),前者表示迭代次数达到了最大次数时停止,后者表示角点位置变化的最小值已经达到最小时停止迭代。二者均使用cv::TermCriteria()构造函数进行指定
import numpy as np
import cv2 as cv
filename = 'chessboard2.jpg'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# find Harris corners
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
dst = cv.dilate(dst,None)
ret, dst = cv.threshold(dst,0.01*dst.max(),