opencv学习(四十四)之图像角点检测Harris
2017-04-17 10:23
253 查看
1.概述
角点是图像很重要的特征,对图像图形的理解和分析有很重要的作用,在保留图像图形重要特征的同时,可以有效减少信息的数据量,使信息的含量很高,有效提高计算速度,有利于图像的可靠匹配,使得实时处理成为可能。在物体识别、图像匹配、视觉跟踪和三维重建等方面有很重要的应用。角点可以认为是窗口向任意方向的移动都导致图像灰度的明显变化。从图像分析的角度来定义角点可以有一下两种:
1.角点可以是两个边缘的角点
2.角点是邻域内具有两个主方向的特征点
前者往往需要对图像边缘进行编码,这在很大程度上依赖于图像的分割与边缘提取,具有相当大的难度和计算量,且一旦待检测目标局部发生变化,很可能导致操作的失败。
角点检测算法可以归纳为三类:基于灰度图像的角点检测、基于二值图像的角点检测、基于轮廓曲线的角点检测。基于灰度图像的检测又可细分为基于梯度、基于模板、基于模板梯度组合三类方法,其中基于模板的方法主要考虑像素邻域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测,Harris角点检测算法,KLT角点检测和SUSAN角点检测。本文主要介绍Harris角点检测。
2.Harris角点检测原理
Harris角点检测原理推导靠一篇博客讲清楚不太现实,这里介绍一个比较直观的概念而不是数学推导。Harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性高,尤其对L型角点检测精度高。
人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。如下图所示:
在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么久认为在窗口内遇到了角点,如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度发生了很大变化,而在另一些方向上没有发生变化,那么窗口内的图像可能就是一条直线的线段。
3.opencv API
opencv提供cornerHarris()提取Harris角点。cornerHarris函数对每一个像素在blockSize x blockSize邻域内,计算2 x 2梯度的协方差矩阵M(x,y),,接着它计算如下公式输出局部最大值,即为角点。
void cv::cornerHarris ( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType = BORDER_DEFAULT )
src:输入图像,Mat类型即可,必须为单通道8-bit或浮点型图像
dst:角点检测的输出结果,与原图像有相同的尺寸和类型
blockSize:邻域大小,可以查看cornerEigenValsAndVecs()得到更多关于blockSize的信息
ksize:表示Sobel()算子孔径大小
**k:**Harris参数,用于判断是否为角点
borderType:前面已多次介绍,为图像边界模式,有默认值BORDER_DEFAULT
4.示例代码
#include <iostream> #include <stdlib.h> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> using namespace std; using namespace cv; //定义全局变量 Mat srcImage, grayImage; int thresh = 100; const int threshMaxValue = 255; //声明回调函数 void cornerHarris_detect(int, void*); int main() { srcImage = imread("harris.jpg"); //判断文件是否加载成功 if (srcImage.empty()) { cout << "图像加载失败!"; return -1; } else cout << "图像加载成功..." << endl << endl; cvtColor(srcImage, grayImage, COLOR_BGR2GRAY); namedWindow("grayImage", WINDOW_AUTOSIZE); imshow("grayImage", grayImage); createTrackbar("Threshold:", "grayImage", &thresh, threshMaxValue, cornerHarris_detect); cornerHarris_detect(thresh, 0); waitKey(0); return 0; } void cornerHarris_detect(int, void*) { Mat dstImage, dst_norm_image, dst_norm_scaled; dstImage = Mat::zeros(srcImage.size(), CV_32FC1); //检测器参数设置 int blockSize = 2; //邻域尺寸 int apertureSize = 3; //Sobel算子孔径 double k = 0.04; //Harris参数 //角点检测 cornerHarris(grayImage, dstImage, blockSize, apertureSize, k, BORDER_DEFAULT); normalize(dstImage, dst_norm_image, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); convertScaleAbs(dst_norm_image, dst_norm_scaled); //强归一化后的图像线性变换为8位无符号整型 //绘制角点 for (int j = 0; j < dst_norm_image.rows; j++) { for (int i = 0; i < dst_norm_image.cols; i++) { if ((int)dst_norm_image.at<float>(j,i)>thresh) { circle(dst_norm_scaled, Point(i, j), 5, Scalar(0), 2, 8, 0); circle(grayImage, Point(i, j), 5, Scalar(0, 0, 255), 2, 8, 0); } } } namedWindow("cornerHarris", WINDOW_AUTOSIZE); imshow("cornerHarris", dst_norm_scaled); namedWindow("corner_grayImage", WINDOW_AUTOSIZE); imshow("corner_grayImage", grayImage); }
运行结果
5.参考文献
http://www.360doc.com/content/15/1212/23/20007814_519967668.shtml相关文章推荐
- OPENCV的学习:图像特征检测之Harris角点算法
- 【学习opencv】对图像缩放并进行边缘检测
- 【OpenCV学习笔记 004】 图像的缩放、Canny边缘检测和图像的二值化
- 【OpenCV图像处理入门学习教程四】基于LoG算子的图像边缘检测
- OpenCV学习:图像边缘检测
- OpenCV2学习笔记(十):特征点检测之Harris法
- OpenCV 用dnn深度学习模块检测图像
- opencv学习笔记1::访问图像中像素的三类方法(用指针,迭代器,动态地址)代码及用时检测
- Opencv学习笔记------Harris角点检测
- OpenCV关于视频处理的学习(VideoCapture类)-在检测中一些必要的图像操作
- opencv 学习之 图像色偏、清晰度、亮度检测
- opencv学习(二)图像模糊及canny边缘检测
- Opencv学习笔记(五)Harris角点检测
- 【OpenCV学习笔记】2.3图像的腐蚀、膨胀、模糊、边缘检测
- opencv学习(三十二)之图像边缘检测Soble_Laplace_Canny
- opencv学习(三十二)之图像边缘检测Soble_Laplace_Canny
- OpenCV学习笔记 图像腐蚀模糊和边缘检测
- opencv图像特征检测及匹配(harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher)
- openCV学习笔记(二)------图像平滑处理和边缘检测
- android openCV检测图像的基本特征,包括Canny边缘检测、Harris角点检测、霍夫直线检测-基于Android studio