【第二部分 图像处理】第3章 Opencv图像处理进阶【6角点检测 B】

2024-08-30 13:32

本文主要是介绍【第二部分 图像处理】第3章 Opencv图像处理进阶【6角点检测 B】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

6.2 Shi-Tomasi角点检测

6.2.1 Shi-Tomasi角点检测概述及原理

Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的行列式值与 M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。
参考论文:hi and C. Tomasi. Good Features to Track. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pages 593-600, June 1994.(见笔者附件)

6.2.2 Shi-Tomasi角点检测:goodFeaturesToTrack()函数

 goodFeaturesToTrack()函数讲解

C++: 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 )

【参数】
第一个参数,image – Input 8-bit or floating-point 32-bit, single-channel image.
第二个参数,eigImage – The parameter is ignored.
第三个参数,tempImage – The parameter is ignored.
第四个参数,corners – Output vector of detected corners.
第五个参数,maxCorners – Maximum number of corners to return. If there are more corners than are found, the strongest of them is returned.
第六个参数,qualityLevel – Parameter characterizing the minimal accepted quality of image corners. The parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue (see cornerMinEigenVal() ) or the Harris function response (see cornerHarris() ). The corners with the quality measure less than the product are rejected. For example, if the best corner has the quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure less than 15 are rejected.
第七个参数,minDistance – Minimum possible Euclidean distance between the returned corners.
mask – Optional region of interest. If the image is not empty (it needs to have the type CV_8UC1 and the same size as image ), it specifies the region in which the corners are detected.
第八个参数,blockSize – Size of an average block for computing a derivative covariation matrix over each pixel neighborhood. See cornerEigenValsAndVecs() .
useHarrisDetector – Parameter indicating whether to use a Harris detector (see cornerHarris()) or cornerMinEigenVal().
第九参数,k – Free parameter of the Harris detector.
 goodFeaturesToTrack()函数源代码

/*【goodFeaturesToTrack ( )源代码】***************************************************** @Version:OpenCV 3.0.0(Opnencv2和Opnencv3差别不大,Linux和PC的对应版本源码完全一样,均在对应的安装目录下)  * @源码路径:…\opencv\sources\modules\imgproc\src\ featureselect.cpp* @起始行数:265行   
********************************************************************************/
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,int maxCorners, double qualityLevel, double minDistance,InputArray _mask, int blockSize,bool useHarrisDetector, double harrisK )
{CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );CV_Assert( _mask.empty() || (_mask.type() == CV_8UC1 && _mask.sameSize(_image)) );CV_OCL_RUN(_image.dims() <= 2 && _image.isUMat(),ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,_mask, blockSize, useHarrisDetector, harrisK))Mat image = _image.getMat(), eig, tmp;if (image.empty()){_corners.release();return;}if( useHarrisDetector )cornerHarris( image, eig, blockSize, 3, harrisK );elsecornerMinEigenVal( image, eig, blockSize, 3 );double maxVal = 0;minMaxLoc( eig, 0, &maxVal, 0, 0, _mask );threshold( eig, eig, maxVal*qualityLevel, 0, THRESH_TOZERO );dilate( eig, tmp, Mat());Size imgsize = image.size();std::vector<const float*> tmpCorners;// collect list of pointers to features - put them into temporary imageMat mask = _mask.getMat();for( int y = 1; y < imgsize.height - 1; y++ ){const float* eig_data = (const float*)eig.ptr(y);const float* tmp_data = (const float*)tmp.ptr(y);const uchar* mask_data = mask.data ? mask.ptr(y) : 0;for( int x = 1; x < imgsize.width - 1; x++ ){float val = eig_data[x];if( val != 0 && val == tmp_data[x] && (!mask_data || mask_data[x]) )tmpCorners.push_back(eig_data + x);}}std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() );std::vector<Point2f> corners;size_t i, j, total = tmpCorners.size(), ncorners = 0;if (minDistance >= 1){// Partition the image into larger gridsint w = image.cols;int h = image.rows;const int cell_size = cvRound(minDistance);const int grid_width = (w + cell_size - 1) / cell_size;const int grid_height = (h + cell_size - 1) / cell_size;std::vector<std::vector<Point2f> > grid(grid_width*grid_height);minDistance *= minDistance;for( i = 0; i < total; i++ ){int ofs = (int)((const uchar*)tmpCorners[i] - eig.ptr());int y = (int)(ofs / eig.step);int x = (int)((ofs - y*eig.step)/sizeof(float));bool good = true;int x_cell = x / cell_size;int y_cell = y / cell_size;int x1 = x_cell - 1;int y1 = y_cell - 1;int x2 = x_cell + 1;int y2 = y_cell + 1;// boundary checkx1 = std::max(0, x1);y1 = std::max(0, y1);x2 = std::min(grid_width-1, x2);y2 = std::min(grid_height-1, y2);for( int yy = y1; yy <= y2; yy++ )for( int xx = x1; xx <= x2; xx++ ){std::vector <Point2f> &m = grid[yy*grid_width + xx];if( m.size() ){for(j = 0; j < m.size(); j++){float dx = x - m[j].x;float dy = y - m[j].y;if( dx*dx + dy*dy < minDistance ){good = false;goto break_out;}}}}break_out:if (good){grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));corners.push_back(Point2f((float)x, (float)y));++ncorners;if( maxCorners > 0 && (int)ncorners == maxCorners )break;}}}else{for( i = 0; i < total; i++ ){int ofs = (int)((const uchar*)tmpCorners[i] - eig.ptr());int y = (int)(ofs / eig.step);int x = (int)((ofs - y*eig.step)/sizeof(float));corners.push_back(Point2f((float)x, (float)y));++ncorners;if( maxCorners > 0 && (int)ncorners == maxCorners )break;}}Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
}

6.2.3 Shi-Tomasi角点检测实例

代码参看附件【demo1】。

这里写图片描述

图1

这里写图片描述

图2

通过滑动滑动条可以改变角点数量。

参考:
中文
英文

本章参考附件

点击进入

这篇关于【第二部分 图像处理】第3章 Opencv图像处理进阶【6角点检测 B】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120954

相关文章

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python进阶之列表推导式的10个核心技巧

《Python进阶之列表推导式的10个核心技巧》在Python编程中,列表推导式(ListComprehension)是提升代码效率的瑞士军刀,本文将通过真实场景案例,揭示列表推导式的进阶用法,希望对... 目录一、基础语法重构:理解推导式的底层逻辑二、嵌套循环:破解多维数据处理难题三、条件表达式:实现分支

Python脚本轻松实现检测麦克风功能

《Python脚本轻松实现检测麦克风功能》在进行音频处理或开发需要使用麦克风的应用程序时,确保麦克风功能正常是非常重要的,本文将介绍一个简单的Python脚本,能够帮助我们检测本地麦克风的功能,需要的... 目录轻松检测麦克风功能脚本介绍一、python环境准备二、代码解析三、使用方法四、知识扩展轻松检测麦

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

基于Python实现进阶版PDF合并/拆分工具

《基于Python实现进阶版PDF合并/拆分工具》在数字化时代,PDF文件已成为日常工作和学习中不可或缺的一部分,本文将详细介绍一款简单易用的PDF工具,帮助用户轻松完成PDF文件的合并与拆分操作... 目录工具概述环境准备界面说明合并PDF文件拆分PDF文件高级技巧常见问题完整源代码总结在数字化时代,PD

javaSE类和对象进阶用法举例详解

《javaSE类和对象进阶用法举例详解》JavaSE的面向对象编程是软件开发中的基石,它通过类和对象的概念,实现了代码的模块化、可复用性和灵活性,:本文主要介绍javaSE类和对象进阶用法的相关资... 目录前言一、封装1.访问限定符2.包2.1包的概念2.2导入包2.3自定义包2.4常见的包二、stati

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习