当前位置: 首页 > article >正文

OpenCV特征检测(6)对初步检测到的角点位置进行亚像素级别的精炼函数cornerSubPix()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

细化角点的位置。
该函数迭代以找到角点或径向鞍点的亚像素级准确位置,如 93中所述,并如下图所示。
在这里插入图片描述
亚像素级准确的角点定位器基于这样一个观察:从中心点 q 到位于 q 的邻域内的某个点 p 的每一个向量都垂直于 p 处的图像梯度,前提是图像和测量噪声的影响。考虑以下表达式:
ϵ i = D I p i T ⋅ ( q − p i ) \epsilon _i = {DI_{p_i}}^T \cdot (q - p_i) ϵi=DIpiT(qpi)
其中 D I p i {DI_{p_i}} DIpi 是邻域中某一点 p i p_i pi处的图像梯度。需要找到 q 的值,使得 ϵ i \epsilon_i ϵi 最小化。可以建立一个方程组,将 ϵ i \epsilon_i ϵi设为零:

∑ i ( D I p i ⋅ D I p i T ) ⋅ q − ∑ i ( D I p i ⋅ D I p i T ⋅ p i ) \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T) \cdot q - \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i) i(DIpiDIpiT)qi(DIpiDIpiTpi)
其中梯度是在 q 的邻域(“搜索窗口”)内求和。称第一个梯度项为 G,第二个梯度项为 b,则有:
q = G − 1 ⋅ b q = G^{-1} \cdot b q=G1b
算法将邻域窗口的中心设置在这个新的中心 q 上,然后迭代直到中心保持在一个设定的阈值内。

函数原型1

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

参数1

  • 参数image 输入单通道 8 位或浮点图像。

  • 参数corners 输入角点的初始坐标,并提供输出精炼后的坐标。

  • 参数winSize 搜索窗口边长的一半。例如,如果 winSize = Size(5, 5),则使用 (52+1)×(52+1) = 11×11 的搜索窗口。

  • 参数zeroZone 搜索区域内中间死区大小的一半,在该区域内公式下的求和不做。有时用于避免自相关矩阵可能的奇异情况。值 (-1, -1) 表示没有这样的大小。

  • 参数criteria 迭代过程角点精炼的终止标准。也就是说,角点位置精炼的过程在达到 criteria.maxCount 次迭代或在某次迭代中角点位置移动小于 criteria.epsilon 时停止。

函数原型2

void cv::goodFeaturesToTrack	
(
	InputArray 	image,
	OutputArray 	corners,
	int 	maxCorners,
	double 	qualityLevel,
	double 	minDistance,
	InputArray 	mask,
	int 	blockSize,
	int 	gradientSize,
	bool 	useHarrisDetector = false,
	double 	k = 0.04 
)		

函数原型3

同上,但还会返回检测到的角点的质量度量。

void cv::goodFeaturesToTrack	
(
	InputArray 	image,
	OutputArray 	corners,
	int 	maxCorners,
	double 	qualityLevel,
	double 	minDistance,
	InputArray 	mask,
	OutputArray 	cornersQuality,
	int 	blockSize = 3,
	int 	gradientSize = 3,
	bool 	useHarrisDetector = false,
	double 	k = 0.04 
)		

参数3

  • 参数image: 输入的 8 位或 32 位浮点型单通道图像。

  • 参数corners: 输出的检测到的角点向量。

  • 参数maxCorners: 返回的最大角点数。如果检测到的角点数量多于这个数值,则返回最强的几个角点。如果 maxCorners <= 0,则表示没有设置最大数量的限制,返回所有检测到的角点。

  • 参数qualityLevel: 表征最小可接受的图像角点质量的参数。该参数值乘以最佳角点的质量度量,该度量可以是最小特征值(参见 cornerMinEigenVal)或 Harris 函数的响应(参见 cornerHarris)。质量度量低于该乘积的角点将被拒绝。例如,如果最佳角点的质量度量为 1500,且 qualityLevel=0.01,则所有质量度量小于 15 的角点都将被拒绝。

  • 参数minDistance: 返回的角点之间的最小可能的欧几里得距离。

  • 参数mask: 兴趣区域。如果该图像不为空(需要是类型 CV_8UC1 且大小与输入图像相同),则它指定了检测角点的区域。

  • 参数cornersQuality: 输出的检测到的角点的质量度量向量。

  • 参数blockSize: 用于在每个像素邻域上计算导数协方差矩阵的平均块大小。参见 cornerEigenValsAndVecs。

  • 参数gradientSize: 用于计算导数的 Sobel 操作符的孔径参数。参见 cornerEigenValsAndVecs。

  • 参数useHarrisDetector: 参数,指示是否使用 Harris 检测器(参见 cornerHarris)或最小特征值方法。

  • 参数k: Harris 检测器中的自由参数。

代码示例


#include <iostream>
#include <opencv2/opencv.hpp>

int main()
{
    // 加载图像
    cv::Mat img = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg", cv::IMREAD_GRAYSCALE );
    if ( img.empty() )
    {
        std::cout << "Error opening image" << std::endl;
        return -1;
    }

    // 检测角点
    std::vector< cv::Point2f > corners;
    cv::goodFeaturesToTrack( img, corners, 100, 0.01, 10, cv::Mat() );

    // 设置搜索窗口大小
    cv::Size win( 5, 5 );

    // 设置零区间大小
    cv::Size zeroZone( -1, -1 );

    // 设置终止标准
    cv::TermCriteria criteria( cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.01 );

    // 对角点进行亚像素级别的精炼
    cv::cornerSubPix( img, corners, win, zeroZone, criteria );

    // 在原始图像上标记精炼后的角点
    cv::Mat imgColor;
    cv::cvtColor( img, imgColor, cv::COLOR_GRAY2BGR );
    for ( const auto& corner : corners )
    {
        cv::circle( imgColor, corner, 2, cv::Scalar( 0, 0, 255 ), 2 );  // 画红色圆圈
    }

    // 显示标记角点的图像
    cv::imshow( "Original Image", img );
    cv::imshow( "Refined Corners", imgColor );

    cv::waitKey( 0 );

    return 0;
}

运行结果

在这里插入图片描述


http://www.kler.cn/a/322067.html

相关文章:

  • HDFS分布式文件系统01-HDFS架构与SHELL操作
  • 微服务保护详细笔记(一):雪崩问题--Sentinel
  • 无人机表演中其关键功能有哪些!
  • yocto通过环境变量控制代码的编译
  • Linux系统安装MySQL8.40(保姆级教程)
  • 【Text2SQL】DAIL-SQL阿里推出,在Spider取得了SOTA
  • 后端回写前端日期格式化
  • 服务器安装openssh9.9p1
  • 学习笔记每日一题
  • node - npm常用命令和package.json说明
  • 编写webpack插件自动找到大文件并上传到指定服务器
  • uniapp实现在表单中展示多个选项,并且用户可以选择其中的一个或多个选项
  • 11.对于贪心算法,该方法如何平衡长期效果和短期最大利用率?
  • 即插即用篇 | YOLOv8 引入单头视觉Transformer模块 | CVPR 2024
  • Python办公自动化教程(004):PDF添加水印
  • Spring Boot用Spring Security + JWT + MySQL实现基于Token的身份认证
  • Python基础知识 (七)--匿名函数
  • 产教专家共议数字时代下的数据思维人才培养
  • 一文系统了解软件检测实验室CNAS认可,文件依据、资源准备、流程、预算
  • 鸿蒙 OS 开发单词打卡 APP 项目实战 20240922 笔记和源码分享