31运动与跟踪-角点检测
特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系。点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(keypoint feature),或“兴趣点”(interest point),或“角点”(conrner)。
关于角点的具体描述可以有几种:
一阶导数(即灰度的梯度)的局部最大所对应的像素点;
两条及两条以上边缘的交点;
图像中梯度值和梯度方向的变化速率都很高的点;
角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。
Harris角点检测
当一个窗口在图像上移动,在平滑区域如图(a),窗口在各个方向上没有变化。在边缘上如图(b),窗口在边缘的方向上没有变化。在角点处如图(c),窗口在各个方向上具有变化。Harris角点检测正是利用了这个直观的物理现象,通过窗口在各个方向上的变化程度,决定是否为角点。
相关接口代码:
void cvGoodFeaturesToTrack(
const CvArr* image,//输入的图像,须为8位或32位单通道图像
CvArr* eigImage,
CvArr* tempImage,//这两个参数都是和输入图像相同的32位单通道图像
CvPoint2D32f* corners,//为函数的输出,得到的是个角点数组
int* corner_count,//表示可以返回的最大角点数目,程序结束后返回角点数目
double quality_level,//这个参数常用值为0.1或者0.01
double min_distance,//保证角点的距离不能小于此参数值
const CvArr* mask=NULL,//选择整幅图像
int block_size=3;//计算导数的自相关矩阵时指定点的邻域
int use_harris=0;//此参数值非0时,用Harris角点定义,为
0时则用Shi-Tomasi定义
double k=0.4;//用于设置Hessian自相关矩阵即对Hessian行列式的相对权重的权重系数,这里可以回看上文的公式
);
相关示例代码:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
#define MAX_CORNERS 100
int main()
{
int cornersCount = MAX_CORNERS;
CvPoint2D32f corners[MAX_CORNERS];
IplImage *srcImage = 0, *grayImage = 0, *corners1 = 0, *corners2 = 0;
int i;
CvScalar color = CV_RGB(255, 0, 0);
char *filename = "3.jpg";
cvNamedWindow("image", 1);
srcImage = cvLoadImage(filename, 1);
grayImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
cvCvtColor(srcImage, grayImage, CV_BGR2GRAY);//转换为灰度图
corners1 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_32F, 1);
corners2 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_32F, 1);//先创立两个图像,在函数中药包含这两个参数
cvGoodFeaturesToTrack(grayImage, corners1, corners2, corners, &cornersCount, 0.05, 30, 0, 3, 0, 0.4);//调用OpenCV函数
cout << "num corners found: " << cornersCount << endl;
if (cornersCount > 0)
{
for (i = 0; i < cornersCount; ++i)
{
cvCircle(srcImage, cvPoint((int)(corners[i].x), (int)(corners[i].y)),2,color,2,CV_AA,0);
}
}//将认为是角点的画出来
cvShowImage("image", srcImage);
cvSaveImage("imagedst.png", srcImage);
cvReleaseImage(&srcImage);
cvReleaseImage(&grayImage);
cvReleaseImage(&corners1);
cvReleaseImage(&corners2);
cvWaitKey(0);
return 0;
结果如下: