前言:

  • 我们知道,在OpenCV中已经为我们提供了相关函数——cornerHarris() 函数和 goodFeaturesToTrack()函数,来实现Harris角点检测和Shi-Tomasi角点检测,
  • 除此之外,其实我们也可以根据算法的原理和需求来制作角点检测的函数。例如:
    使用cornerEigenValsAndVecs()函数和minMaxLoc()函数结合来模拟Harris角点检测,
    或者使用cornerMinEigenVal()函数和minMaxLoc()函数结合来模拟Shi-Tomasi角点检测,
    最后特征点选取的判断条件要根据实际情况进行选择。

自定义角点检测器

  • 基于 Harris 与 Shi-Tomasi 角点检测
  • 首先通过计算矩阵 M 得到 λλλ1 λλλ2 两个特征值根据他们得到角点响应值
  • 然后自己设置阈值实现计算出阈值得到有效响应值的角点位置

相关API说明

1. cornerEigenValsAndVecs()函数
cornerEigenValsAndVecs()函数用来求解输入图像矩阵的特征向量与特征值,其函数原型如下:

void cornerEigenValsAndVecs(InputArray src,       --单通道输入8位或浮点图像OutputArray dst,    --输出图像,同源图像或CV_32FC(6)int blockSize,         --邻域大小值int apertureSize,    --Sobel算子当中的核大小int borderType=BORDER_DEFAULT --像素外插方法
)//对应于Harris

其中:第二个参数 dst:输出矩阵,即用来存储结果的图像,大小与输入图像一致并且为CV_32FC(6)类型。计算自相关矩阵M的特征值和特征向量,并将它们以(λ1, λ2, x1, y1, x2,y2)的形式存储在目标图像dst中。其中λ1, λ2是M未经过排序的特征值;x1, y1是对应于λ1的特征向量;x2, y2是对应于λ2的特征向量。因此是6通道的矩阵。

2. cornerMinEigenVal()函数
功能与cornerEigenValsAndVecs()函数相似,但是它只计算导数协方差矩阵(即自相关矩阵)的最小特征值,其函数原型如下:

void cornerMinEigenVal(InputArray src,     --单通道输入8位或浮点图像OutputArray dst,  --图像存储的最小特征值。类型为CV_32FC1int blockSize,       --邻域大小值int apertureSize=3,   --Sobel算子的参数int borderType=BORDER_DEFAULT  --像素外插方法
}//对应Shi-Tomasi

3.minMaxLoc()函数介绍

  • minMaxLoc(): minMaxLoc()函数寻找输入矩阵(在c++中就是Mat对象)中的最小值和最大值,同时可以其相应值的位置(Point对象)。其函数声明如下:

    –minMaxLoc()的API介绍来自:https://blog.csdn.net/sinat_36264666/article/details/78754897

1. cornerEigenValsAndVecs()函数、自定义角点检测器_harris

程序代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;const char* harris_win = "Custom Harris Corners Detector";
Mat src, gray_src;
Mat harris_dst, harrisRspImg;
double harris_min_rsp;// harris 角度响应最小值
double harris_max_rsp;// harris 角度响应最大值
// quality level
int qualityLevel = 30;
int max_count = 100;void CustomHarris_Demo(int, void*);int main(int argc, char** argv) {src = imread("E:/Experiment/OpenCV/Pictures/cornerHarrisTest.jpg");if (src.empty()) {printf("could not load image...\n");return -1;}namedWindow("input image", CV_WINDOW_AUTOSIZE);namedWindow(harris_win, CV_WINDOW_AUTOSIZE);imshow("input image", src);cvtColor(src, gray_src, COLOR_BGR2GRAY);// 计算特征值 eigon values λ1 λ2int blockSize = 3;// blockSize取2或取3,会导致计算出来的角度响应的最大最小值不一样,下面的阈值需要适当调整int ksize = 3;double k = 0.04;harris_dst = Mat::zeros(src.size(), CV_32FC(6));// 深度为 CV_32F 通道数为6 ,通道数不一定要6 大于等于2就行harrisRspImg = Mat::zeros(src.size(), CV_32FC1);cornerEigenValsAndVecs(gray_src, harris_dst, blockSize, ksize, 4);// 计算 λ1 λ2// 计算角度响应for (int row = 0; row < harris_dst.rows; row++) {for (int col = 0; col < harris_dst.cols; col++) {double lambda1 =harris_dst.at<Vec6f>(row, col)[0]; // λ1double lambda2 = harris_dst.at<Vec6f>(row, col)[1]; // λ2// harris角度响应计算,公式 R = det(M) - k*(trace(M))^2,  det(M)=λ1*λ2, trace(M)=λ1+λ2harrisRspImg.at<float>(row, col) = lambda1*lambda2 - k*pow((lambda1 + lambda2), 2);}}//寻找harrisRspImg中角度响应最大值,最小值,及它们所在的位置,位置参数传0表示不管minMaxLoc(harrisRspImg, &harris_min_rsp, &harris_max_rsp, 0, 0, Mat());printf("harris_min_rsp=%f, harris_max_rsp=%f\n", harris_min_rsp, harris_max_rsp); //harris_min_rsp=-0.016178, harris_max_rsp=0.047225createTrackbar("harris thresh:", harris_win, &qualityLevel, max_count, CustomHarris_Demo);CustomHarris_Demo(0, 0);waitKey(0);return 0;
}void CustomHarris_Demo(int, void*) {// 自定义harris角点检测,与harris函数计算的结果差不多if (qualityLevel < 10) {qualityLevel = 10;}Mat resultImg = src.clone(); // 完全拷贝//定义阈值, 以 thresh_v_harris / thresh_max_harris 的比例显示角点float t = harris_min_rsp + (((double)qualityLevel) / max_count)*(harris_max_rsp - harris_min_rsp);for (int row = 0; row < src.rows; row++) {for (int col = 0; col < src.cols; col++) {float v = harrisRspImg.at<float>(row, col);if (v > t) {// 角度响应大于阈值,在当前位置显示出来,当角度响应阈值设的很低时,因为绘制的多,所以绘制速度会很慢circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);}}}imshow(harris_win, resultImg);
}

运行截图:

2. cornerMinEigenVal()函数、自定义角点检测器_ShiTomasi

程序代码

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;const char* shitomasi_win = "Custom Shi-Tomasi Corners Detector";
Mat src, gray_src, shiTomasiRsp;
double shitomasi_min_rsp;// tomasi 角度响应最小值
double shitomasi_max_rsp;// tomasi 角度响应最大值
int sm_qualitylevel = 30;
int max_count = 100;void CustomShiTomasi_Demo(int, void*);int main(int argc, char** argv) {src = imread("E:/Experiment/OpenCV/Pictures/ShiTomasiTest.jpg");if (src.empty()) {printf("could not load image...\n");return -1;}namedWindow("input image", CV_WINDOW_AUTOSIZE);namedWindow(shitomasi_win, CV_WINDOW_AUTOSIZE);imshow("input image", src);cvtColor(src, gray_src, COLOR_BGR2GRAY);// 计算特征值int blockSize = 3;int ksize = 3;double k = 0.04;shiTomasiRsp = Mat::zeros(src.size(), CV_32FC1);//计算最小特征值,即ShiTomasi角度响应值 R = min(λ1, λ2)cornerMinEigenVal(gray_src, shiTomasiRsp, blockSize, ksize, BORDER_DEFAULT);minMaxLoc(shiTomasiRsp, &shitomasi_min_rsp, &shitomasi_max_rsp, 0, 0, Mat());//寻找tomasiRspImg中角度响应最大值,最小值,及它们所在的位置,位置参数传0表示不管printf("tomasi_min_rsp=%f, tomasi_max_rsp=%f\n", shitomasi_min_rsp, shitomasi_max_rsp);//tomasi_min_rsp=-0.000000, tomasi_max_rsp=0.192643createTrackbar("Quality:", shitomasi_win, &sm_qualitylevel, max_count, CustomShiTomasi_Demo);CustomShiTomasi_Demo(0, 0);waitKey(0);return 0;
}void CustomShiTomasi_Demo(int, void*) {if (sm_qualitylevel < 20) {sm_qualitylevel = 20;}Mat resultImg = src.clone();//定义阈值, 以 thresh_v_tomasi / thresh_max_tomasi 的比例显示角点float t = shitomasi_min_rsp + (((double)sm_qualitylevel) / max_count)*(shitomasi_max_rsp - shitomasi_min_rsp);for (int row = 0; row < src.rows; row++) {for (int col = 0; col < src.cols; col++) {float v = shiTomasiRsp.at<float>(row, col);// shiTomasi角点检测出的角度响应值有很多为0,所以减少了circle绘制,所以程序速度比harris要快if (v > t) {circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);}}}imshow(shitomasi_win, resultImg);
}

运行截图

参考博客

  1. https://blog.csdn.net/weixin_41695564/article/details/79979784
  2. https://www.cnblogs.com/long5683/p/9692969.html
  3. https://blog.csdn.net/huanghuangjin/article/details/81263320
  4. https://blog.csdn.net/huanghuangjin/article/details/81263778

OpenCV-特征提取与检测(03、自定义角点检测器)相关推荐

  1. OpenCV + CPP 系列(卅三)图像特征提取(Harris角点检测、Shi-Tomasi角点检测、自定义角点检测)

    文章目录 一.常用图像特征描述 二.Harris角点检测 演示Harris角点检测 三.Shi-Tomasi角点检测 四.自定义角点检测器 一.常用图像特征描述 SIFT.SURF.HOG.Haar. ...

  2. 人脸检测实战进阶:使用 OpenCV 进行活体检测

    使用 OpenCV 进行活体检测 在本篇博文中,您将学习如何使用 OpenCV 执行活体检测.您将创建一个活体检测器,该检测器能够在人脸识别系统中发现假人脸并执行反人脸欺骗. 在教程的第一部分,我们将 ...

  3. OpenCV + CPP 系列(卅四)图像特征提取(亚像素级别角点检测)

    文章目录 亚像素级别角点检测 演示像素坐标检测 亚像素级别角点检测 亚像素:在生成数字图像处理时(拍照等)我们是将物理世界中连续的图像进行了离散化处理.现实世界中颜色为连续的且有无数种类,成像到像素面 ...

  4. OpenCV中检测ChArUco的角点(2)

    论文阅读模块将分享点云处理,SLAM,三维视觉,高精地图相关的文章.公众号致力于理解三维视觉领域相关内容的干货分享,欢迎各位加入我,我们一起每天一篇文章阅读,开启分享之旅,有兴趣的可联系微信diany ...

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

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

  6. OpenCV之feature2d 模块. 2D特征框架(1)Harris 角点检测子 Shi-Tomasi角点检测子 定制化创建角点检测子 亚像素级的角点检测 特征点检测

    Harris 角点检测子 目标 本教程中我们将涉及: 有哪些特征?它们有什么用? 使用函数 cornerHarris 通过 Harris-Stephens方法检测角点. 理论 有哪些特征? 在计算机视 ...

  7. OpenCV与图像处理学习十三——Harris角点检测(含代码)

    OpenCV与图像处理学习十三--Harris角点检测(含代码) 一.角点的概念 二.Harris角点检测的实现过程 三.Harris代码应用 一.角点的概念 角点: 在现实世界中, 角点对应于物体的 ...

  8. 【OpenCV 学习笔记】第二十章: 角点检测之:harris算法以及Shi-Tomasi算法

    第二十章: 角点检测之:harris算法以及Shi-Tomasi算法 一张图像,我们可以用很多方法去处理它,就会得到很多不同的特征.比如基于梯度方法我们就能得到图像的边缘特征:比如基于直方图我们就得到 ...

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

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

  10. OpenCV入门学习笔记之Harris角点检测与SIFT特征匹配算法

    1. 写在前面 这篇文章整理两个图像处理中非常重要的算法,一个是Harris角点检测算法,另一个是SIFT特征匹配算法,这两个算法本质上还是去找图像里面的关键特征点,帮助我们后续更好的理解图像以及做各 ...

最新文章

  1. python创建一个简单的服务
  2. 框架学习之Spring 第五节 SSH整合开发[Spring2.5+Hibernate3.3+Struts2]
  3. 函数返回对象写法的失误
  4. 曼哈顿距离和欧拉距离
  5. 统计哈姆雷特文本中高频词的个数
  6. python可以做系统吗_哪个操作系统更适合用来做Python开发
  7. dubbo绕过zookeeper直连本地提供方服务
  8. 第十二章_网络搭建及训练
  9. Java日期与时间的处理/Date,String,Calendar转换
  10. Flex 4与自定义循环布局(转)
  11. 最热web前端技术精粹
  12. java.lang.ClassNotFoundException: net.sf.json.JSONObject
  13. 应用层下的人脸识别(三):人脸比对
  14. 驱动一款淘宝购买的130万像素的USB双目摄像头-记录
  15. 如何对研发团队绩效进行考核--附各环节人员考核参考表
  16. dlna 服务器 性能,dlna 使用体验,供大家参考,欢迎交流
  17. 理解Tensorflow的shape
  18. 高斯模糊算法的实现和优化
  19. 96张完整PPT清晰解读全球智能制造趋势!
  20. 把扫描文件转变为word文档的最实用的四款OCR识别软件

热门文章

  1. linux和window是服务器时间同步
  2. Docker技术入门与实战(第2版)2.5 本章小结
  3. windows下命令行发送邮件blat.exe
  4. 在 ML2 中配置 VXLAN - 每天5分钟玩转 OpenStack(110)
  5. spring中IOC的简单使用
  6. Liferay 加载自定义css 文件
  7. 利用oracle long类型字段,插入大文本
  8. Git部署Git使用Git子模块
  9. Java基础,无许复杂语句,倒序输出整数,int i = 123;输出321
  10. c++多边形扫描线填充算法_一文读懂扫描线算法