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

2024-08-30 13:32

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

6.3亚像素角点检测

6.3.1 亚像素角点检测

前文讲解了利用Harris进行角点检测和利用Shi-Tomasi方法进行角点检测外,如果对角点的精度有更高的要求,可以用cornerSubPix()函数将角点定位到子像素,从而取得亚像素级别的角点检测效果。

6.3.2 亚像素角点检测:cornerSubPix()函数

 cornerSubPix()函数讲解

C++: void cornerSubPix( InputArray image, InputOutputArray corners, Size winSize, Size zeroZone,TermCriteria criteria)

【参数】
第一个参数,image – Input image.
第二个参数,corners – Initial coordinates of the input corners and refined coordinates provided for output.
第三个参数,winSize – Half of the side length of the search window. For example, if winSize=Size(5,5) , then a search window is used.
第四个参数,zeroZone – Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such a size.
第五个参数,criteria – Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after criteria.maxCount iterations or when the corner position moves by less than criteria.epsilon on some iteration.
 cornerSubPix()函数源代码

/*【cornerSubPix ( )源代码】************************************************************ @Version:OpenCV 3.0.0(Opnencv2和Opnencv3差别不大,Linux和PC的对应版本源码完全一样,均在对应的安装目录下)  * @源码路径:…\opencv\sources\modules\imgproc\src\ cornersubpix.cpp* @起始行数:44行   
********************************************************************************/
void cv::cornerSubPix( InputArray _image, InputOutputArray _corners,Size win, Size zeroZone, TermCriteria criteria )
{const int MAX_ITERS = 100;int win_w = win.width * 2 + 1, win_h = win.height * 2 + 1;int i, j, k;int max_iters = (criteria.type & CV_TERMCRIT_ITER) ? MIN(MAX(criteria.maxCount, 1), MAX_ITERS) : MAX_ITERS;double eps = (criteria.type & CV_TERMCRIT_EPS) ? MAX(criteria.epsilon, 0.) : 0;eps *= eps; // use square of error in comparsion operationscv::Mat src = _image.getMat(), cornersmat = _corners.getMat();int count = cornersmat.checkVector(2, CV_32F);CV_Assert( count >= 0 );Point2f* corners = cornersmat.ptr<Point2f>();if( count == 0 )return;CV_Assert( win.width > 0 && win.height > 0 );CV_Assert( src.cols >= win.width*2 + 5 && src.rows >= win.height*2 + 5 );CV_Assert( src.channels() == 1 );Mat maskm(win_h, win_w, CV_32F), subpix_buf(win_h+2, win_w+2, CV_32F);float* mask = maskm.ptr<float>();for( i = 0; i < win_h; i++ ){float y = (float)(i - win.height)/win.height;float vy = std::exp(-y*y);for( j = 0; j < win_w; j++ ){float x = (float)(j - win.width)/win.width;mask[i * win_w + j] = (float)(vy*std::exp(-x*x));}}// make zero_zoneif( zeroZone.width >= 0 && zeroZone.height >= 0 &&zeroZone.width * 2 + 1 < win_w && zeroZone.height * 2 + 1 < win_h ){for( i = win.height - zeroZone.height; i <= win.height + zeroZone.height; i++ ){for( j = win.width - zeroZone.width; j <= win.width + zeroZone.width; j++ ){mask[i * win_w + j] = 0;}}}// do optimization loop for all the pointsfor( int pt_i = 0; pt_i < count; pt_i++ ){Point2f cT = corners[pt_i], cI = cT;int iter = 0;double err = 0;do{Point2f cI2;double a = 0, b = 0, c = 0, bb1 = 0, bb2 = 0;getRectSubPix(src, Size(win_w+2, win_h+2), cI, subpix_buf, subpix_buf.type());const float* subpix = &subpix_buf.at<float>(1,1);// process gradientfor( i = 0, k = 0; i < win_h; i++, subpix += win_w + 2 ){double py = i - win.height;for( j = 0; j < win_w; j++, k++ ){double m = mask[k];double tgx = subpix[j+1] - subpix[j-1];double tgy = subpix[j+win_w+2] - subpix[j-win_w-2];double gxx = tgx * tgx * m;double gxy = tgx * tgy * m;double gyy = tgy * tgy * m;double px = j - win.width;a += gxx;b += gxy;c += gyy;bb1 += gxx * px + gxy * py;bb2 += gxy * px + gyy * py;}}double det=a*c-b*b;if( fabs( det ) <= DBL_EPSILON*DBL_EPSILON )break;// 2x2 matrix inversiondouble scale=1.0/det;cI2.x = (float)(cI.x + c*scale*bb1 - b*scale*bb2);cI2.y = (float)(cI.y - b*scale*bb1 + a*scale*bb2);err = (cI2.x - cI.x) * (cI2.x - cI.x) + (cI2.y - cI.y) * (cI2.y - cI.y);cI = cI2;if( cI.x < 0 || cI.x >= src.cols || cI.y < 0 || cI.y >= src.rows )break;}while( ++iter < max_iters && err > eps );// if new point is too far from initial, it means poor convergence.// leave initial point as the resultif( fabs( cI.x - cT.x ) > win.width || fabs( cI.y - cT.y ) > win.height )cI = cT;corners[pt_i] = cI;}
}

6.3.3亚像素角点检测实例

代码参看附件【demo1】。

这里写图片描述

图1

这里写图片描述

图2

参考:
英文链接
中文链接

本章参考附件

点击进入

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



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

相关文章

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 核心功能从零开始学习

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解