【OpenCV3】角点检测——cv::goodFeaturesToTrack()与cv::cornerSubPix()详解
来源:互联网 发布:美工主要负责什么 编辑:程序博客网 时间:2024/04/29 14:15
一提到角点检测,最常用的方法莫过于Harris角点检测,opencv中也提供了Harris角点检测的接口,即cv::cornerHarris(),但是Harris角点检测存在很多缺陷(如角点是像素级别的,速度较慢等),因此我们这里将介绍opencv中的另一个功能更为强大的函数——cv::goodFeaturesToTrack(),它不仅支持Harris角点检测,也支持Shi Tomasi算法的角点检测。但是,该函数检测到的角点依然是像素级别的,若想获取更为精细的角点坐标,则需要调用cv::cornerSubPix()函数进一步细化处理,即亚像素。
1、cv::goodFeaturesToTrack()角点检测
cv::goodFeaturesToTrack()的具体调用形式如下:
void cv::goodFeaturesToTrack(cv::InputArray image, // 输入图像(CV_8UC1 CV_32FC1)cv::OutputArray corners, // 输出角点vectorint maxCorners, // 最大角点数目double qualityLevel, // 质量水平系数(小于1.0的正数,一般在0.01-0.1之间)double minDistance, // 最小距离,小于此距离的点忽略cv::InputArray mask = noArray(), // mask=0的点忽略int blockSize = 3, // 使用的邻域数bool useHarrisDetector = false, // false ='Shi Tomasi metric'double k = 0.04 // Harris角点检测时使用);
第一个参数是输入图像(8位或32位单通道图)。
第二个参数是检测到的所有角点,类型为vector或数组,由实际给定的参数类型而定。如果是vector,那么它应该是一个包含cv::Point2f的vector对象;如果类型是cv::Mat,那么它的每一行对应一个角点,点的x、y位置分别是两列。
第三个参数用于限定检测到的点数的最大值。
第四个参数表示检测到的角点的质量水平(通常是0.10到0.01之间的数值,不能大于1.0)。
第五个参数用于区分相邻两个角点的最小距离(小于这个距离得点将进行合并)。
第六个参数是mask,如果指定,它的维度必须和输入图像一致,且在mask值为0处不进行角点检测。
第七个参数是blockSize,表示在计算角点时参与运算的区域大小,常用值为3,但是如果图像的分辨率较高则可以考虑使用较大一点的值。
第八个参数用于指定角点检测的方法,如果是true则使用Harris角点检测,false则使用Shi Tomasi算法。
第九个参数是在使用Harris算法时使用,最好使用默认值0.04。
下面使用测试代码,看一下实际的检测效果。
测试代码如下:
cv::Mat image_color = cv::imread("house.jpg", cv::IMREAD_COLOR);//使用灰度图像进行角点检测cv::Mat image_gray;cv::cvtColor(image_color, image_gray, cv::COLOR_BGR2GRAY);//设置角点检测参数std::vector<cv::Point2f> corners;int max_corners = 200;double quality_level = 0.01;double min_distance = 3.0;int block_size = 3;bool use_harris = false;double k = 0.04;//角点检测cv::goodFeaturesToTrack(image_gray, corners, max_corners, quality_level, min_distance, cv::Mat(), block_size, use_harris, k);//将检测到的角点绘制到原图上for (int i = 0; i < corners.size(); i++){cv::circle(image_color, corners[i], 1, cv::Scalar(0, 0, 255), 2, 8, 0);}cv::imshow("house corner", image_color);cv::waitKey(0);return;
实际检测效果如下:
2、cv::cornerSubPix()亚像素角点检测
前面已经提及,cv::goodFeaturesToTrack()提取到的角点只能达到像素级别,在很多情况下并不能满足实际的需求,这时,我们则需要使用cv::cornerSubPix()对检测到的角点作进一步的优化计算,可使角点的精度达到亚像素级别。
具体调用形式如下:
void cv::cornerSubPix(cv::InputArray image, // 输入图像cv::InputOutputArray corners, // 角点(既作为输入也作为输出)cv::Size winSize, // 区域大小为 NXN; N=(winSize*2+1)cv::Size zeroZone, // 类似于winSize,但是总具有较小的范围,Size(-1,-1)表示忽略cv::TermCriteria criteria // 停止优化的标准);
第一个参数是输入图像,和cv::goodFeaturesToTrack()中的输入图像是同一个图像。
第二个参数是检测到的角点,即是输入也是输出。
第三个参数是计算亚像素角点时考虑的区域的大小,大小为NXN; N=(winSize*2+1)。
第四个参数作用类似于winSize,但是总是具有较小的范围,通常忽略(即Size(-1, -1))。
第五个参数用于表示计算亚像素时停止迭代的标准,可选的值有cv::TermCriteria::MAX_ITER 、cv::TermCriteria::EPS(可以是两者其一,或两者均选),前者表示迭代次数达到了最大次数时停止,后者表示角点位置变化的最小值已经达到最小时停止迭代。二者均使用cv::TermCriteria()构造函数进行指定。
下面就通过一个示例看看cv::cornerSubPix()亚像素角点检测的具体效果。
cv::Mat image_color = cv::imread("image.jpg", cv::IMREAD_COLOR);//用于绘制亚像素角点cv::Mat image_copy = image_color.clone();//使用灰度图像进行角点检测cv::Mat image_gray;cv::cvtColor(image_color, image_gray, cv::COLOR_BGR2GRAY);//设置角点检测参数std::vector<cv::Point2f> corners;int max_corners = 100;double quality_level = 0.01;double min_distance = 10;int block_size = 3;bool use_harris = false;double k = 0.04;//角点检测cv::goodFeaturesToTrack(image_gray,corners,max_corners,quality_level,min_distance,cv::Mat(),block_size,use_harris,k);//将检测到的角点绘制到原图上for (int i = 0; i < corners.size(); i++){cv::circle(image_color, corners[i], 5, cv::Scalar(0, 0, 255), 2, 8, 0);}//指定亚像素计算迭代标注cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,40,0.01);//亚像素检测cv::cornerSubPix(image_gray, corners, cv::Size(5, 5), cv::Size(-1, -1), criteria);//将检测到的亚像素角点绘制到原图上for (int i = 0; i < corners.size(); i++){cv::circle(image_copy, corners[i], 5, cv::Scalar(0, 255, 0), 2, 8, 0);}cv::imshow("corner", image_color);cv::imshow("sub pixel corner", image_copy);cv::imwrite("corner.jpg", image_color);cv::imwrite("corner_sub.jpg", image_copy);cv::waitKey(0);return;
直接角点检测和亚像素角点检测的结果分别如下:
从检测的效果来看,使用亚像素角点检测后角点的精细度确实得到了显著的提升。
2017.04.07
- 【OpenCV3】角点检测——cv::goodFeaturesToTrack()与cv::cornerSubPix()详解
- 【OpenCV3】棋盘格角点检测与绘制——cv::findChessboardCorners()与cv::drawChessboardCorners()详解
- 【OpenCV3】图像轮廓查找与绘制——cv::findContours()与cv::drawContours()详解
- 【OpenCV3】图像通道分离与合并——cv::split()与cv::merge()详解
- 【OpenCV3】图像旋转与平移——cv::warpAffine()详解
- 【OpenCV3】彩色映射——cv::applyColorMap()与cv::LUT()详解
- 【OpenCV3】透视变换——cv::getPerspectiveTransform()与cv::warpPerspective()详解
- 【OpenCV3】彩色映射——cv::applyColorMap()与cv::LUT()详解
- 【OpenCV3】彩色映射——cv::applyColorMap()与cv::LUT()详解
- opencv3/C++角点检测goodFeaturesToTrack()
- 【OpenCV3】视频读写——cv::VideoCapture和cv::VideoWriter详解
- 【OpenCV3】颜色空间转换——cv::cvtColor()详解
- 【OpenCV3】图像翻转——cv::flip()详解
- 【OpenCV3】模板匹配——cv::matchTemplate()详解
- 【OpenCV3】直线拟合——cv::fitLine()详解
- 【OpenCV3】颜色空间转换——cv::cvtColor()详解
- goodFeaturesToTrack——Shi-Tomasi角点检测
- goodFeaturesToTrack——Shi-Tomasi角点检测
- 学习H5页面遇到的一些问题与解决办法汇总
- CKEditor-4.6.2结合Struts2的使用,加CKEditor图片上传的配置
- C++第三次作业
- AppiumLibrary 联动菜单
- display:flex 布局教程
- 【OpenCV3】角点检测——cv::goodFeaturesToTrack()与cv::cornerSubPix()详解
- 447. Number of Boomerangs\187. Repeated DNA Sequences\537. Complex Number Multiplication
- 蓝桥杯四平方和
- 关于在PLSQL中实现DEBUG调试功能的方法
- 配置ngnix实现HLS m3u8点播
- ElasticSearch + Canal 开发千万级的实时搜索系统
- 在eclipse中使用NLPIR(ICTCLAS)2013进行分词
- laravel框架中使用QueryList插件采集数据
- 拼多多上货助理使用教程