匹配问题

Harris角点检测是Chris Harris和Mike Stephens在1988年提出的。主要用于运动图像的追踪。当时的普遍想法是利用边缘进行追踪,但是当相机或物体运动时你不知道朝哪个方向,相机的几何变换也是未知的,所以边缘匹配很难达到预期的效果。即使是当时最优秀的边缘检测算子Canny算子,它的边缘检测也依赖于阈值的选取。所以Harris等人放弃了匹配边缘,转而寻找一些特殊的点来匹配,这些点是边缘线段的连接点,它们表征了图像的结构,代表了图像局部的特征。

例如不同时刻两幅建筑物图像,想要匹配它们,就是要找到它们有没有共同区域,一种方法就是——Patch Matching:

那么第二副图中哪一个窗口与红色窗是最佳匹配呢?人眼可以迅速判断出,怎么让计算机知道?

什么是角点

直观的说就是图像轮廓的连接点。不管视角怎么变换,这些点依然存在,是稳定的;它们与领域的点差别比较大。所以角点是一种优良的特征点。

如果你用一个小的加权窗口在角点的附近各个方向移动,将会出现一个大的变化!

Moravec角点检测

Harris角点检测来自于Moravec检点检测(1977,Moravec),并对它进行了改进和更强的数学建模。

Moravec角点检测用一个二值窗口在图像的某个像素点的所有方向上进行移动,并计算移动后和移动前像素强度变化的平均值,得到的最小的值定为该点的角点响应值。用公式表示,即为:

在移动时,会出现三种情况:

1.如果是在图像的平坦区域,shift的所有结果都很小;

2.如果是在图像的边缘,那么只有沿着边缘的方向shift时值比较小,其他方向都很大。

3.如果实在边缘的连接点处或者一个单独的点,无论什么方向怎么移动,值都很大。

最后设定一个阈值,大于这个阈值的判定为角点。

一般计算这个像素点水平、垂直、对角线、反对角线4个方向上的灰度差平方和。

Harris角点检测

Moravec角点有一些缺点,导致它的检测不精确,Harris改良了这些缺点。

1.相应是各向异性的,因为只考虑了45度倍数方向上的响应。Harris通过对shift region进行泰勒展开,覆盖所有方向的移动。

二元函数的一阶泰勒近似为:

所以,对于很小的shift,响应强度可以表示为:

将后面的平方项展开,

这里我们暂时把窗口去掉,考察一下移动(u,v)后,平方项的矩阵表示,便于后面的理解:

2.响应容易受到噪声的干扰,因为窗口是二值的,且为方形。Harris改用具有平滑效果的高斯圆形窗口。

3.对边缘、角点的判决过于简单,因为响应只考虑E的最小值。Harris重新设计了一种衡量边缘、角点的方式——利用E的方差。

M描述了原始区域的形状,实际上是泰勒展开的二次项。这个该怎么理解呢?

首先我们看一下,在三种情况下,Ix,Iy分别描述了什么:

如果把一阶导作为变量画出三种情况下一个小区域的一阶导分布图,你就会惊奇的发现一些规律:

怎么样来描述数据的分布呢?就是用一个椭圆去拟合一阶导的分布形状:

lamda1,lamda2代表了椭圆的长短轴:

这样三种情况可以用椭圆形状来描述,而且形状的大小可以表示属于那种情况的相似度:

我们知道椭圆的表达式是:ax^2+c*x*y+by^2=1,将坐标系旋转到椭圆长短轴所在方向,表达式变换为:a'*x^2+b'*y^2=1,称之为标准型。

结合矩阵二次型的知识:

进一步用矩阵表示:

可以看出,Harris得到的M就是这种形式的!

而椭圆的标准化实际上是中间的矩阵经过对角化,即标准化之后的椭圆的长短轴就是由A的特征值得来。

这样我们求得M的两个特征值α,β其实就得到了描述原始区域形状的信息!这也是前面提到Harris的方法考虑了窗口所有方向的移动的原因。不是人为去划定方向,而是通过泰勒展开,找到了数据分布,实际上就是得到了对我们有用的最佳移动方向。这个α,β与原始区域数据自相关函数的主曲率成正比。

现在我们知道了特征值的分布与该点属性的关系:

1.如果两个曲率都小,局部自相关函数就是平坦的,响应值也应当比较小;

2.如果曲率一个大一个小,局部自相关函数呈山脊型,只有沿着脊(边缘),响应值才大;

3.如果两个曲率都大,局部自相关函数成山峰状,有峰值,响应值大。

理想的边缘应该是α很大,β为0,但是实际因为噪声、像素化、强度量化等原因,β很小。另外,如果图像的像素灰度整体增大,乘了一个常数p,(α,β)原来是什么,(pα,pβ)也得是什么。

怎样保证这种关系呢?Harris给出了一种衡量方法,得到一个值,称为角点响应值:

利用二阶矩阵的秩行列式(Det)和迹(Trace)避开计算特征值α,β。利用响应函数R给该点一个score,衡量这个点的性质。R的好处在于:R>0,这个点位于corner region;R<0,这个点位于edge region,|R|比较小时是flat region。k大约取0.04-0.06。

k的影响:增大k将减小响应值R,降低角点检测的灵敏度,减少检测到的角点数量;反之减小k,将增多角点数量。

由上述分析也可以看出,Harris角点没有尺度不变性,因为框的设计并没有考虑这一点。所以当图像尺寸变化时,框的大小不相应调整,就会出现错误的分类。

最后给出Harris角点检测的算法流程:

原始图像:

只经过阈值处理的图像,可以看出含有大量角点群:

经过非极大值抑制后的角点图,效果好了很多:

进一步改良,从响应最高的点开始,大于设定距离的点留下:

OpenCV代码来自Computer Vision Programming using the OpenCV Library. by Robert Laganiere, Packt Publishing, 2011.

头文件:

#pragma once
#if !defined HARRISD
#define HARRISD#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>class HarrisDetector {private:// 32-bit float image of corner strengthcv::Mat cornerStrength;// 32-bit float image of thresholded cornerscv::Mat cornerTh;// image of local maxima (internal)cv::Mat localMax;// size of neighbourhood for derivatives smoothingint neighbourhood; // aperture for gradient computationint aperture; // Harris parameterdouble k;// maximum strength for threshold computationdouble maxStrength;// calculated threshold (internal)double threshold;// size of neighbourhood for non-max suppressionint nonMaxSize; // kernel for non-max suppressioncv::Mat kernel;public:HarrisDetector() : neighbourhood(3), aperture(3), k(0.1), maxStrength(0.0), threshold(0.01), nonMaxSize(3) {setLocalMaxWindowSize(nonMaxSize);}// Create kernel used in non-maxima suppressionvoid setLocalMaxWindowSize(int size) {nonMaxSize= size;kernel.create(nonMaxSize,nonMaxSize,CV_8U);}// Compute Harris cornersvoid detect(const cv::Mat& image) {// Harris computationcv::cornerHarris(image,cornerStrength,neighbourhood,// neighborhood sizeaperture,     // aperture sizek);           // Harris parameter// internal threshold computationdouble minStrength; // not usedcv::minMaxLoc(cornerStrength,&minStrength,&maxStrength);// local maxima detectioncv::Mat dilated;  // temporary imagecv::dilate(cornerStrength,dilated,cv::Mat());cv::compare(cornerStrength,dilated,localMax,cv::CMP_EQ);}// Get the corner map from the computed Harris valuescv::Mat getCornerMap(double qualityLevel) {cv::Mat cornerMap;// thresholding the corner strengththreshold= qualityLevel*maxStrength;cv::threshold(cornerStrength,cornerTh,threshold,255,cv::THRESH_BINARY);// convert to 8-bit imagecornerTh.convertTo(cornerMap,CV_8U);// non-maxima suppressioncv::bitwise_and(cornerMap,localMax,cornerMap);return cornerMap;}// Get the feature points vector from the computed Harris valuesvoid getCorners(std::vector<cv::Point> &points, double qualityLevel) {// Get the corner mapcv::Mat cornerMap= getCornerMap(qualityLevel);// Get the cornersgetCorners(points, cornerMap);}// Get the feature points vector from the computed corner mapvoid getCorners(std::vector<cv::Point> &points, const cv::Mat& cornerMap) {// Iterate over the pixels to obtain all feature pointsfor( int y = 0; y < cornerMap.rows; y++ ) {const uchar* rowPtr = cornerMap.ptr<uchar>(y);for( int x = 0; x < cornerMap.cols; x++ ) {// if it is a feature pointif (rowPtr[x]) {points.push_back(cv::Point(x,y));}} }}// Draw circles at feature point locations on an imagevoid drawOnImage(cv::Mat &image, const std::vector<cv::Point> &points, cv::Scalar color= cv::Scalar(255,255,255), int radius=3, int thickness=2) {std::vector<cv::Point>::const_iterator it= points.begin();// for all cornerswhile (it!=points.end()) {// draw a circle at each corner locationcv::circle(image,*it,radius,color,thickness);++it;}}
};#endif

源文件:

#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>#include "harrisDetector.h"int main()
{// Read input imagecv::Mat image= cv::imread("church01.jpg",0);if (!image.data)return 0; // Display the imagecv::namedWindow("Original Image");cv::imshow("Original Image",image);// Detect Harris Cornerscv::Mat cornerStrength;cv::cornerHarris(image,cornerStrength,3,     // neighborhood size3,     // aperture size0.01); // Harris parameter// threshold the corner strengthscv::Mat harrisCorners;double threshold= 0.0001; cv::threshold(cornerStrength,harrisCorners,threshold,255,cv::THRESH_BINARY_INV);// Display the cornerscv::namedWindow("Harris Corner Map");cv::imshow("Harris Corner Map",harrisCorners);// Create Harris detector instanceHarrisDetector harris;// Compute Harris valuesharris.detect(image);// Detect Harris cornersstd::vector<cv::Point> pts;harris.getCorners(pts,0.01);// Draw Harris cornersharris.drawOnImage(image,pts);// Display the cornerscv::namedWindow("Harris Corners");cv::imshow("Harris Corners",image);// Read input imageimage= cv::imread("church01.jpg",0);// Compute good features to trackstd::vector<cv::Point2f> corners;cv::goodFeaturesToTrack(image,corners,500, // maximum number of corners to be returned0.01,    // quality level10);    // minimum allowed distance between points// for all cornersstd::vector<cv::Point2f>::const_iterator it= corners.begin();while (it!=corners.end()) {// draw a circle at each corner locationcv::circle(image,*it,3,cv::Scalar(255,255,255),2);++it;}// Display the cornerscv::namedWindow("Good Features to Track");cv::imshow("Good Features to Track",image);cv::waitKey();return 0;
}

Harris 角点检测(Harris Corner Detection)(OpenCV实现)相关推荐

  1. Python+OpenCV:图像Harris角点检测(Harris Corner Detection)

    Python+OpenCV:图像Harris角点检测(Harris Corner Detection) 理论 corners are regions in the image with large v ...

  2. OpenCV —— 角点检测之 Harris 角点检测、Shi-Tomasi 角点检测、FAST 角点检测

    角点检测 Harris 角点检测 实现原理 OpenCV 函数 优化 Shi-Tomasi 角点检测 实现原理 OpenCV 函数 FAST 角点检测 实现原理 OpenCV 函数 优化 在图像处理和 ...

  3. 图像局部特征(二)--Harris角点检测子

     一.角点定义 有定义角点的几段话: 1.角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测.图像匹配.视频跟踪.三维建模和目标识别等领域 ...

  4. Harris 角点检测原理详解

    var html = document.getElementById("artContent").innerHTML; document.getElementById(" ...

  5. 模式识别与图像处理课程实验一:图像处理实验(颜色算子实验、Susan、Harris角点检测实验、 sobel边缘算子检测实验)

    模式识别与图像处理课程实验一:图像处理实验-->> 颜色算子实验.Susan.Harris角点检测实验. sobel边缘算子检测实验 一. 实验内容 二. 颜色算子实验 2.1. 提取红色 ...

  6. harris角点检测和SIFT

    Harris角点检测 #harris角点检测就是利用模板来找出像素值突变的部分 一般利用自相似性来表示模板移动后的差异 对于图像l(x,y),当再点(x,y)处平移(Δx,Δy)后的自相似性: c(x ...

  7. OpenCV角点检测之Harris角点检测

    本篇文章中,我们一起探讨了OpenCV中Harris角点检测相关的知识点,学习了OpenCV中实现Harris角点检测的cornerHarris函数的使用方法.此博文一共有两个配套的麻雀虽小但五脏俱全 ...

  8. OpenCV中的Harris角点检测

    OpenCV中的Harris角点检查 1. 效果图 2. 原理 3. 源码 3.1 Harris角点检测 3.2 精细角点检测 参考 这篇博客将了解什么是特征,角点,哈里斯角点检测(Harris Co ...

  9. 【OpenCV十六新手教程】OpenCV角检测Harris角点检测

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...

最新文章

  1. 用ASP.Net(C#)连接Oracle数据库的方法
  2. Python字符串截取值
  3. Jquery中获取选中的select的值
  4. Java中static关键字有什么用?
  5. 贵州大学java期末考试_CONTRIBUTING.md
  6. outlook存档邮件_如何在Outlook 2013中存档电子邮件
  7. 物联网IoT接入技术分类以及华为OC平台特性
  8. 数据卡片_E015 如何批量汇总工作簿数据,形成独立工作簿信息卡片
  9. ajax跨浏览器初始化,使用Ajax的jQuery localStorage的跨浏览器
  10. python路径规划仿真实验_【python实战】批量获得路径规划——高德地图API
  11. 新款iPhone SE发布日期曝光:小屏果粉早已按捺不住
  12. macOS Monterey 12.0 Beta版 With Clover 5136 and OC 0.7.0 and PE 三EFI分区原版黑苹果镜像
  13. 细胞自动机 通用计算机,科学网—《走近混沌》-27-初级细胞自动机 - 张天蓉的博文...
  14. 通用单目标跟踪综述《Handcrafted and Deep Trackers: A Review of Recent Object Tracking Approaches》
  15. nyoj 543 遥控器 第五届河南省程序设计大赛
  16. qnap备份文件服务器,完整的数据备份方案
  17. html如何实现在线客服,在线客服.html
  18. actuator微服务信息完善
  19. Python爬虫实战之哔哩哔哩二维码登录申请
  20. 量化交易中,如何使用Python画K线、成交量、买卖点【邢不行】

热门文章

  1. 物联网安全-动态口令TOTP
  2. ip,pv,uv分别是什么?有什么用?
  3. do while计算阶乘与阶乘之和
  4. Fortify--安装与使用
  5. CPU、内存与分布式
  6. github克隆代码加速
  7. django+whoosh
  8. 新版的 CorelDraw X6
  9. 各种深度学习模型与框架的文件后缀名
  10. 云原生下的DevOps与持续交付