角点检测

角点的特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系。点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(keypoint feature),或“兴趣点”(interest point),或“角点”(conrner)。

关于角点的具体描述可以有几种:

一阶导数(即灰度的梯度)的局部最大所对应的像素点;
两条及两条以上边缘的交点;
图像中梯度值和梯度方向的变化速率都很高的点;
角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

Harris算子和ShiTomasi算子

Harris角点检测推导:https://blog.csdn.net/lql0716/article/details/52628959

角点检测的Harris算子和ShiTomasi算子非常好的解释:https://blog.csdn.net/xiaowei_cqu/article/details/7805206

  • Harris算子

OpenCV中定义了 cornerHarris 函数:

void cornerHarris( InputArray src, OutputArray dst, int blockSize,int ksize, double k,int borderType=BORDER_DEFAULT );

可以结合 convertScaleAbs 函数,通过阈值取角点。

  • Shi-Tomasi算子

由于Shi-Tomasi算子与1994年在文章 Good Features to Track [1]中提出,OpenCV 实现的算法的函数名定义为 goodFeaturesToTrack:

void goodFeaturesToTrack( InputArray image, OutputArray corners,int maxCorners, double qualityLevel, double minDistance,InputArray mask=noArray(), int blockSize=3,bool useHarrisDetector=false, double k=0.04 );

代码例子

编译环境: Qt 5.5.1+opencv3.2.0+cmake3.5.1


#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>using namespace cv;
using namespace std;Mat image, image_gray;int thresh = 200;
int max_thresh = 255;char* source_window = "Source image";
char* corners_window = "Harris Courners detected";int maxCorners = 23;
int maxTrackbar = 100;RNG rng(12345);Mat myHarris_dst;
Mat myHarris_copy;
Mat Mc;
Mat myShiTomasi_dst;
Mat myShiTomasi_copy;int myShiTomasi_qualityLevel = 50;
int myHarris_qualityLevel = 50;
int max_qualityLevel = 100;double myHarris_minVal;
double myHarris_maxVal;
double myShiTomasi_minVal;
double myShiTomasi_maxVal;const char* myHarris_window = "my harris corner detector";
const char* myShiTomasi_window = "my Shi Tomasi corner detector";// Function header
void cornerHarris_demo(int, void*);
void goodFeaturesToTrack_demo(int, void*);
void myShiTomasi_function(int, void*);
void myHarris_function(int, void*);int main(int argc, char** argv)
{image = imread(argv[1],1);if(image.empty())return 0;cvtColor(image, image_gray, COLOR_BGR2GRAY);int blockSize = 3;int apertureSize = 3;// my harris matrix -- usin cornerEigenValsAndVecsmyHarris_dst = Mat::zeros(image_gray.size(), CV_32FC(6));Mc = Mat::zeros(image_gray.size(), CV_32FC1);cornerEigenValsAndVecs(image_gray, myHarris_dst, blockSize, apertureSize, BORDER_DEFAULT);/* calculate Mc */for( int j=0; j<image_gray.rows; j++){for(int i=0; i<image_gray.cols; i++){float lambda_1 = myHarris_dst.at<Vec6f>(j,i)[0];float lambda_2 = myHarris_dst.at<Vec6f>(j,i)[1];Mc.at<float>(j,i) = lambda_1*lambda_2-0.04f*pow((lambda_1+lambda_2),2);}}minMaxLoc(Mc, &myHarris_minVal, &myHarris_maxVal, 0, 0, Mat());// create window and trackbarnamedWindow( myHarris_window, WINDOW_AUTOSIZE);createTrackbar("Quality Level:", myHarris_window, &myHarris_qualityLevel, max_qualityLevel, myShiTomasi_function);myHarris_function(0,0);/// My Shi-Tomasi -- Using cornerMinEigenValmyShiTomasi_dst = Mat::zeros( image_gray.size(), CV_32FC1 );cornerMinEigenVal( image_gray, myShiTomasi_dst, blockSize, apertureSize, BORDER_DEFAULT );minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal, 0, 0, Mat() );/* Create Window and Trackbar */namedWindow( myShiTomasi_window, WINDOW_AUTOSIZE );createTrackbar( " Quality Level:", myShiTomasi_window, &myShiTomasi_qualityLevel, max_qualityLevel, myShiTomasi_function );myShiTomasi_function( 0, 0 ) ;// create windownamedWindow(source_window, WINDOW_AUTOSIZE);createTrackbar("Threshold:", source_window, &thresh, max_thresh, cornerHarris_demo);createTrackbar("Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_demo);imshow(source_window, image);cornerHarris_demo(0,0);goodFeaturesToTrack_demo(0,0);waitKey(10000);return (0);
}void cornerHarris_demo(int, void*)
{Mat dst, dst_norm, dst_norm_scaled;dst = Mat::zeros(image.size(), CV_32FC1);int blockSize = 2;int apertureSize = 3;double k = 0.04;//detecting cornerscornerHarris(image_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT);//normalizingnormalize(dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat());convertScaleAbs(dst_norm, dst_norm_scaled);//draw a circlefor(int j=0; j<dst_norm.rows; j++){for(int i = 0; i < dst_norm.cols; i++){if((int)dst_norm.at<float>(j,i) > thresh){circle(dst_norm_scaled, Point(i,j), 5, Scalar(0), 2, 8, 0);}}}namedWindow(corners_window, WINDOW_AUTOSIZE);imshow(corners_window, dst_norm_scaled);}void goodFeaturesToTrack_demo(int, void*)
{if (maxCorners < 1){maxCorners = 1;}/// parameters for shi-tomasi algorithmvector<Point2f> corners;double qualityLevel = 0.01;double minDistance = 10;int blockSize = 3;bool useHarrisDetector = false;double k = 0.04;Mat copy;copy = image.clone();// apply corner detectiongoodFeaturesToTrack(image_gray,corners,maxCorners,qualityLevel,minDistance,Mat(),blockSize,useHarrisDetector,k);// draw corners detectedcout<<"** Number of corners detected:"<<corners.size()<<endl;int r=4;for(int i = 0; i<corners.size(); i++){circle(copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0);}// shownamedWindow(source_window, WINDOW_AUTOSIZE);imshow(source_window, copy);}void myShiTomasi_function(int, void *)
{myShiTomasi_copy = image.clone();for( int j=0; j<image_gray.rows; j++ ){for( int i = 0; i<image_gray.cols; i++ ){if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal+(myShiTomasi_maxVal-myShiTomasi_minVal)*myShiTomasi_qualityLevel/max_qualityLevel){circle(myShiTomasi_copy, Point(i,j), 4, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0);}}}imshow(myShiTomasi_window, myShiTomasi_copy);}void myHarris_function(int, void *)
{myHarris_copy = image.clone();if( myHarris_qualityLevel < 1){myHarris_qualityLevel = 1;}for( int j=0; j<image_gray.rows; j++){for(int i=0; i<image_gray.cols; i++){if(Mc.at<float>(j,i) > myHarris_minVal+(myHarris_maxVal-myHarris_minVal)*myHarris_qualityLevel/max_qualityLevel){circle( myHarris_copy, Point(i,j), 4, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0);}}}imshow( myHarris_window, myHarris_copy);
}

参考及更多阅读

openCV高斯模糊、边缘检测、灰度化、二值化、闭运算、绘制边缘
https://cloud.tencent.com/developer/article/1106887

角点检测的数学原理: https://www.cnblogs.com/riddick/p/7645904.html

OpenCV角点检测: Harris算子, ShiTomasi算子相关推荐

  1. OpenCV角点检测源代码分析(Harris和ShiTomasi角点)

    OpenCV中常用的角点检测为Harris角点和ShiTomasi角点. 以OpenCV源代码文件 .\opencv\sources\samples\cpp\tutorial_code\Trackin ...

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

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

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

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

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

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

  5. opencv角点检测学习总结

    学习opencv 角点检测 如果一个点在两个正交方向上都有明显的导数,则我们认为此点更倾向于是独一无二的,所以许多可跟踪的特征点都是角点. 一下为角点检测中用到的一些函数 cvGoodFeatures ...

  6. 计算机视觉(角点检测)- 2 - Shi-Tomasi 角点检测

    计算机视觉(角点检测)- 2 - Shi-Tomasi 角点检测 学习前言 一.Shi-Tomasi 角点检测 二.OpenCV中API介绍    ```corners = cv2.goodFeatu ...

  7. OpenCV角点检测

    角点检测 Harris 角点检测算法 1. 角点 2. 流程 3. 实现 Harris 角点检测算法 1. 角点 角点是水平方向.垂直方向变化都很大的像素. 2. 流程 (1)找出角点 用高斯算子求出 ...

  8. OpenCV——角点检测原理分析(Harris,Shi-Tomasi、亚像素级角点检测)

    一.角点(corner) 角点通常被定义为两条边的交点,或者说,角点的局部邻域应该具有两个不同区域的不同方向的边界.角点检测(Corner Detection)是计算机视觉系统中获取图像特征的一种方法 ...

  9. opencv——角点检测

    一:角点检测 什么是角点,难道是角落里面的点?我们知道,比如说墙角,他有往左延申的边缘,又有往右延申的边缘,那么这样的概念同样可以帮助我们理解图像的角点检测. 其实我们人眼对于角点的识别是通过一个小窗 ...

最新文章

  1. 【神经网络】(18) EfficientNetV2 代码复现,网络解析,附Tensorflow完整代码
  2. 好多Javascript日期选择器呀-7
  3. 网页素材大宝库:50套非常精美的图标素材
  4. cocos2d-x自制工具03:AnimatePacker for Mac/Win32 v1.1 Build1发布!
  5. 机器学习算法--无监督学习--聚类
  6. CVPR 2020 三篇有趣的论文解读
  7. codeforces 361 D. Levko and Array(dp+二分)
  8. 如果conda找不到想要安装的库怎么办PackagesNotFoundError: The following packages are not available from current
  9. 三种方法实现二分查找
  10. Ubuntu Apache 不同端口监听不同站点
  11. 数学建模——模糊数学
  12. java文件下载文件损坏_java上传并下载以及解压zip文件有时会报文件被损坏错误分析以及解决...
  13. 网站挂马检测 php,Python实现的检测网站挂马程序
  14. 初二年级男生厌学家长应该怎么应对
  15. 数字图像处理:像素间的一些基本关系
  16. 系统的零点、极点物理含义
  17. CentOS7.4下安装Oracle 11gR2
  18. C++-c语言词法分析器
  19. android 8.0发布直播,安卓版微信8.0内测版来了
  20. 哪个计算机软件可以探究小孔成像,探究小孔成像实验报告.doc

热门文章

  1. word 2019 深黑色背景如何改成白色(已解决)
  2. C语言反汇编 - 多维数组与指针
  3. JavaScript——模拟自动饮料机
  4. php循环26个英文字母,有趣的真人字母操,形象生动容易学,帮孩子瞬间搞定26个英文字母,效果满分!...
  5. UAF—metasequoia_2020_summon
  6. 一种基于STM32F1 MCU的增量型编码器测速的方法
  7. linux 机器无法访问网络
  8. ictclas linux 64 java 下载,Ubuntu下ICTCLAS JNI的使用
  9. 关于hive on spark的distribute by和group by使用以及小文件合并问题
  10. 【Qualcomm】浏览器无法登录高通网站的修改方法