OpenCV——⾓点检测原理分析(Harris,Shi-Tomasi、亚像
素级⾓点检测)
⼀、⾓点(corner)
⾓点通常被定义为两条边的交点,或者说,⾓点的局部邻域应该具有两个不同区域的不同⽅向的边界。⾓点检测(Corner Detection)是计算机视觉系统中获取图像特征的⼀种⽅法,⼴泛应⽤于运动检测、图像匹配、视频跟踪、三维重建和⽬标识别等,也可称为特征点检测。
1、⾓点的类型
酒酿饼的家常做法
水工专业
2、⾓点检测算法的基本思想:
使⽤⼀个固定窗⼝在图像上进⾏任意⽅向上的滑动,⽐较滑动前与滑动后两种情况,窗⼝中的像素灰度变化程度,如果存在任意⽅向上的滑动,都有着较⼤灰度变化,那么我们可以认为该窗⼝中存在⾓点。
⽬前,⾓点检测算法还不是⼗分完善,许多算法需要依赖⼤量的训练集和冗余数据来防⽌和减少错误的特征的出现。对于⾓点检测算法的重要评价标准是:其对多幅图像中相同或者相似特征的检测能⼒,并且能够应对光照变化、或者图像旋转等影响。
关于⾓点的具体描述可以有⼏种:
⼀阶导数(即灰度的梯度)的局部最⼤所对应的像素点;
两条及两条以上边缘的交点;
图像中梯度值和梯度⽅向的变化速率都很⾼的点;
⾓点处的⼀阶导数最⼤,⼆阶导数为零,指⽰物体边缘变化不连续的⽅向。
三类⾓点检测算法:
基于⼆值图像的⾓点检测;
基于轮廓曲线的⾓点检测;
基于灰度图像的⾓点检测:基于梯度、基于模板和基于模板和梯度组合三类⽅法;常见的基于模板的⾓点检测算法有:Kitchen-Ronfeld⾓点检测算法,Harris⾓点检测算法,KLT⾓点检测算法及SUSAN⾓点检测算法。基于模板的⽅法主要是考虑像素领域点灰度的变化,即亮度的变化。
1、Harris⾓点检测
1.1 原理分析
1.1.1 算法思想
⾓点原理来源于⼈对⾓点的感性判断,即图像在各个⽅向灰度有明显变化。算法的核⼼是利⽤局部窗⼝在图像上进⾏移动判断灰度发⽣较⼤的变化,所以此窗⼝⽤于计算图像的灰度变化为(3*3的窗⼝,这和计算梯度变化算⼦⼀样):[-1,0,1;-1,0,1;-1,0,1][-1,-1,-
1;0,0,0;1,1,1]。根据下⾯三幅图可以清晰理解⾓点检测的过程:当⼀个窗⼝在图像上移动,如图(a),窗⼝在各个⽅向上都没有变化,则认为窗⼝区域为平滑区域。如图(b),窗⼝在某个⽅向上没有变化,
另⼀个⽅向上有明显变化,那么,这块区域可能存在边缘。如图(c),窗⼝在各个⽅向上灰度发⽣了较⼤的变化,那么,这块区域可能存在⾓点。Harris⾓点检测正是利⽤了这个直观的物理现象,通过窗⼝在各个⽅向上的变化程度,决定是否为⾓点。
1.1.2 数学表⽰
根据算法思想,构建数学模型,计算移动窗⼝的的灰度差值。
为了减⼩计算量,利⽤泰勒级数进⾏简化公式:
上图中W函数表⽰窗⼝函数,M矩阵为偏导数矩阵。对于矩阵可以进⾏对称矩阵的变化,假设利⽤两个特征值进⾏替代,其⼏何含义类似下图中的表达。在⼏何模型中通过判断两个特征值的⼤⼩,来判定像素的属性。
M为梯度的协⽅差矩阵 ,在实际应⽤中为了能够应⽤更好的编程,定义了⾓点响应函数R,通过判定R⼤⼩来判断像素是否为⾓点。R 取决于M的特征值,对于⾓点|R|很⼤,平坦的区域|R|很⼩,边缘的R为负值。Harris⾓点检测算法就是对⾓点响应函数R进⾏阈值处理:R > threshold,即提取R的局部极⼤值。
OpenCV⾥⾯的API:
C++:void cornerHarris( InputArray src, //输⼊8bit单通道灰度Mat矩阵
OutputArray dst, //⽤于保存Harris⾓点检测结果,32位单通道,⼤⼩与src相同
int blockSize, //滑块窗⼝的尺⼨
严助
int ksize, //Sobel边缘检测滤波器⼤⼩
double k, //Harris中间参数,经验值0.04~0.06
int borderType=BORDER_DEFAULT //插值类型
);
⼆、Shi-Tomasi⾓点检测
Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的⾏列式值与 M 的迹相减,再将差值同预先给定的阈值进⾏⽐较。后来Shi 和Tomasi 提出改进的⽅法,若两个特征值中较⼩的⼀个⼤于最⼩阈值,则会得到强⾓点。
Shi 和Tomasi 的⽅法⽐较充分,并且在很多情况下可以得到⽐使⽤Harris 算法更好的结果。
OpenCV⾥⾯的API:
月经期间同房会怀孕吗C++:void goodFeaturesToTrack( InputArray image, OutputArray corners,
int maxCorners, double qualityLevel, double minDistance,
InputArray mask=noArray(), int blockSize=3,
bool uHarrisDetector=fal, double k=0.04 );
参数详解:
第⼀个参数image:8位或32位单通道灰度图像;
第⼆个参数corners:位置点向量,保存的是检测到的⾓点的坐标;
第三个参数maxCorners:定义可以检测到的⾓点的数量的最⼤值;
第四个参数qualityLevel:检测到的⾓点的质量等级,⾓点特征值⼩于qualityLevel*最⼤特征值的点将被舍弃;
第五个参数minDistance:两个⾓点间最⼩间距,以像素为单位;
第六个参数mask:指定检测区域,若检测整幅图像,mask置为空Mat();
第七个参数blockSize:计算协⽅差矩阵时窗⼝⼤⼩;
第⼋个参数uHarrisDetector:是否使⽤Harris⾓点检测,为fal,则使⽤Shi-Tomasi算⼦;
第九个参数k:留给Harris⾓点检测算⼦⽤的中间参数,⼀般取经验值0.04~0.06。第⼋个参数为fal时,该参数不起作⽤;
三、亚像素级⾓点检测
当我们想要进⾏⼏何测量或者标定的时候势必要⽐⽬标识别需要更⾼的精度的特征点。⽽上⾯的goodFeaturesToTrack()只能得到整数的坐标值,这时候我们就需要亚像素级的⾓点检测来得到实数坐标值来满⾜精度需求。
亚像素级⾓点检测的位置摄像机标定,跟踪并重建摄像机的轨迹或者重建被跟踪⽬标的三维结构时,是⼀个基本的测量值。下⾯是将⾓点位置精确到亚像素精度的过程:
压腿的正确方法
⼀个向量与其正交的向量的点积为0,⾓点满⾜上图所⽰情况。其中(a)点p附近的图像是均匀的,其梯度为0;(b)边缘的梯度与沿边缘⽅向的q-p向量正交。在图中两种情况下,p点梯度与q-p向量的点积均为0。
展馆设计上图中,我们假设起始⾓点q在实际亚像素⾓点的附近。检测所有的q-p向量。若点p位于⼀个均匀区域,则点p的梯度为0。若q-p向量的⽅向与边缘的⽅向⼀致,则此边缘上p点处的梯度与q-p向量正交,在这两种情况下,p点处的梯度与q-p向量的点积为0.我们可以在p点周围找到很多组梯度以及相关的向量q-p,令其点集为0,然后可以通过求解⽅程组,⽅程组的解即为⾓点q的亚像素级精度的位置,
即精确的⾓点位置。
OpenCV的API介绍:
C++:void cornerSubPix(
InputArray image, //输⼊图像
InputOutputArray corners,//输⼊⾓点的初始坐标和为输出的精确坐标
Size winSize, //搜索窗⼝边长的⼀半
Size zeroZone,//搜索区域中间的死区⼤⼩的⼀半,(-1,-1)表⽰没有这样的⼤⼩。
TermCriteria criteria //终⽌⾓点优化迭代的条件
);
⽰例程序:
血糯米的做法//代码⾥⾯有三种程序
#include "stdafx.h"
双鱼座性格特点
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
int main(int argv, char** argc)
{
Mat srcImage = imread("C:/Urs/zhj/Desktop/image/template.bmp");
if (pty())
{
printf("could not load image..\n");
return fal;
}
Mat srcgray, dstImage, normImage,scaledImage;
cvtColor(srcImage, srcgray, CV_BGR2GRAY);
Mat srcbinary;