OpenCV目标跟踪(一)-寻找角点
来源:互联网 发布:软件项目阶段性报告 编辑:程序博客网 时间:2024/06/02 02:12
这两天在看OpenCV中的跟踪与运动这一块,跟踪和运动是一个很大的课题,里面的涉及的内容有很多,按着自己的学习进度上,简要的做个总结。
在我们处理一段视频而非某张静止的图片时,我们往往会去关注画面中的一个或者几个物体。对运动的物体的关注,我们处理的方式往往不是将整个物体都作为关注对象,而是选取几个独特的特征点去跟踪,这样我们就引出了角点的概念。
(1)角点
角点在运动与跟踪的研究中,就是说可以拿来作为跟踪的特征点都被称为角点。通俗直观的解释就是,一类含有足够信息且能从当前帧和下一帧中都能提取出来的点。
(2)角点的具体描述
a.一阶导数的局部最大所对应的像素点;
b.两条及两条以上边缘的交点;
c.图像中梯度值和梯度方向的变化速率都很高的点;
d.角点处的一阶导数最大,二阶导数为0,指示物体边缘变化不连续的方向。
(3)Harris角点检测算法简述
Harris角点检测算子是依据自相关函数给出的,得出了矩阵M,矩阵M中的特征值是自相关函数的一阶曲率,如果一阶曲率都很高的话,那么就可以认为这个是特征点。
下面给出图来直观的解释下:
图(a)是窗口在图像的平滑区域滑动,窗口在各个方向上没有变化,图(b)窗口在边缘方向上没有变化,图(c)窗口在各个方向上有变化,此时即为角点。
Harris角点的检测,相对于一幅图像来看,主要和自相关函数的曲率特性有关。自相关函数描述了局部图像灰度的变化程度,主要可以表示为:
上式中,E是窗口平移产生的图像灰度变化,也即是自相关函数,w是窗口,I是图像灰度。对上式进行展开即有:
其中
而对于小的偏移:
其中即有:
为了更好的降低噪声,采用高斯窗口进行图像降噪,高斯窗口函数即为:
这样E就可以通过矩阵的形式表现出来:
其中:
为了避免求解M特征值(M特征值和自相关函数的极值曲率有关),定义:
给出角点的响应函数为:
上式中R的值越大,越有可能是角点。
以上的思想是Harris提出的响应函数,后来Shi和Tomasi发现,若两个特征值的较小的一个大于最小阈值,则会得到强角点。
后来又有学者提出了亚像素角点的概念,通俗的来说就是以一个角点作为初始点进行不停的迭代,直到满足预先设置的迭代阈值条件,具体的大家感兴趣的话可以参阅相关文献。
在OpenCV中,给出了一个这样的函数cvGoodFeaturesToTrack(),采用的即是Shi和Tomasi给出的算法,即先计算出二阶导数,再计算特征值,小特征值大于最小阈值,找出角点。
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 100int 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;}
运行结果如图:
大家从上面可以看得出来,角点已经基本检测出来,但似乎依旧不是特别理想,大家可以尝试着修改下函数cvGoodFeaturesToTrack()中的参数值,运行后观察角点的检测效果。
- OpenCV目标跟踪(一)-寻找角点
- OpenCv目标跟踪_cvGoodFeaturesToTrack()寻找角点
- OpenCv目标跟踪_cvGoodFeaturesToTrack()寻找角点
- 初九-目标跟踪-点跟踪
- Opencv学习笔记(十一)目标跟踪
- OpenCV目标跟踪(二)-LK光流法
- OpenCV目标跟踪(三)-camshift算法
- OpenCV目标跟踪(四)-运动模板
- OpenCV目标跟踪(五)-kalman滤波器
- 目标跟踪Camshift算法(Opencv实现)
- [OpenCV] Camshiftdemo 目标跟踪
- opencv彩色目标跟踪
- opencv目标跟踪:三帧差分法
- 【opencv】Camshift目标跟踪
- opencv单目标跟踪
- 寻找目标跟踪算法(1)
- 利用OpenCV实现——目标跟踪方法(一)
- 目标跟踪学习笔记_(opencv中kalman点跟踪例子)
- ELF文件解析
- Python学习001之HelloWorld
- The Swift Code之设置UIButton的不同方式创建,以及不同的状态和外观
- php 5.3新增的闭包语法介绍function() use() {}
- TerminateProcess终止进程失败
- OpenCV目标跟踪(一)-寻找角点
- PopupWindow的基础使用
- 进程和线程
- Android Wifi子系统(一)
- js鼠标单击和双击事件冲突问题的解决方法
- JavaScript的继承
- 关于LINUX权限-bash: ./startup.sh: Permission denied
- nginx源码分析之http解码实现
- android-进阶-黑盒测试