OpenCV特征检测(3)计算图像中每个像素处的特征值和特征向量函数cornerEigenValsAndVecs()的使用

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

算法描述

计算图像块的特征值和特征向量用于角点检测。
对于每一个像素 p ,函数 cornerEigenValsAndVecs 考虑一个 blockSize × blockSize 的邻域 S§ 。它计算邻域内的协变矩阵 M ,公式如下:
M = [ ∑ S ( p ) ( d I / d x ) 2 ∑ S ( p ) d I / d x d I / d y ∑ S ( p ) d I / d x d I / d y ∑ S ( p ) ( d I / d y ) 2 ] M = \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 & \sum _{S(p)}dI/dx dI/dy \\ \sum _{S(p)}dI/dx dI/dy & \sum _{S(p)}(dI/dy)^2 \end{bmatrix} M=[S(p)(dI/dx)2S(p)dI/dxdI/dyS(p)dI/dxdI/dyS(p)(dI/dy)2]
其中导数使用 Sobel 操作符进行计算。
之后,它找到 M 的特征向量和特征值,并将它们存储在目标图像中,格式为 (λ1, λ2, x1, y1, x2, y2),其中

  • λ1, λ2 是未排序的 M 的特征值;
  • x1, y1 是对应于 λ1 的特征向量;
  • x2, y2 是对应于 λ2 的特征向量。

该函数的输出可以用于稳健的边缘或角点检测。

函数原型

void cv::cornerEigenValsAndVecs	
(
	InputArray 	src,
	OutputArray 	dst,
	int 	blockSize,
	int 	ksize,
	int 	borderType = BORDER_DEFAULT 
)		

参数

  • 参数src:输入单通道 8 位或浮点图像。
  • 参数dst:用于存储结果的图像。它与 src 大小相同,类型为 CV_32FC(6)。
  • 参数blockSize:邻域大小(参见下面的详细信息)。
  • 参数ksize:Sobel 操作符的孔径参数。
  • 参数borderType:像素外推方法。参见 BorderTypes。不支持 BORDER_WRAP。

代码示例


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

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;
    }

     // 计算特征值和特征向量
    cv::Mat eigen;
    int blockSize = 3; // 邻域大小
    int ksize = 3; // Sobel 梯度算子的大小

    cv::cornerEigenValsAndVecs(img, eigen, blockSize, ksize);

    // 显示特征值
    cv::Mat eigenVal1(img.rows, img.cols, CV_32F);
    cv::Mat eigenVal2(img.rows, img.cols, CV_32F);
    cv::Mat eigenVec1(img.rows, img.cols, CV_32FC2);
    cv::Mat eigenVec2(img.rows, img.cols, CV_32FC2);

    // 分离特征值和特征向量
    for (int y = 0; y < img.rows; ++y)
    {
        for (int x = 0; x < img.cols; ++x)
        {
            // 获取每个像素处的特征值和特征向量
            const cv::Vec4f& eigenRow = eigen.at<cv::Vec4f>(y, x);
            eigenVal1.at<float>(y, x) = eigenRow[0]; // 第一个特征值
            eigenVal2.at<float>(y, x) = eigenRow[1]; // 第二个特征值
            eigenVec1.at<cv::Vec2f>(y, x) = cv::Vec2f(eigenRow[2], eigenRow[3]); // 第一个特征向量
            eigenVec2.at<cv::Vec2f>(y, x) = cv::Vec2f(eigenRow[4], eigenRow[5]); // 第二个特征向量
        }
    }

    // 显示特征值图像
    cv::normalize(eigenVal1, eigenVal1, 0, 255, cv::NORM_MINMAX, CV_8U);
   
    cv::imshow("Original Image", img);
    cv::imshow("Eigen Value 1", eigenVal1);

    cv::normalize(eigenVal2, eigenVal2, 0, 255, cv::NORM_MINMAX, CV_8U);
    cv::imshow("Eigen Value 2", eigenVal2);

    cv::waitKey(0);

    return 0;
}

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 在 GIS 领域的学习路线?

Java是一门广泛应用于企业级开发的编程语言&#xff0c;而GIS则是一种常用于地理信息处理和分析的技术。将Java与GIS结合起来&#xff0c;可以在企业级应用中实现更多的功能和业务需求&#xff0c;且在实际领域越来越广泛。 Java在GIS中重要的作用 1、跨平台性 Java具有跨平台…

基于C语言+SQL Server2008实现(控制台)图书管理系统

第1章 概述 1.1项目背景 随着科技的发展&#xff0c;尤其是计算机技术的迅猛发展&#xff0c;图书馆管理的问题从以往的人工管理&#xff0c;到现在的电脑化&#xff0c;系统化&#xff0c;是对图书馆管理方法的质的飞跃&#xff0c;这些技术不仅让图书馆管理变得更加方便、快…

美国联邦基金有效利率及目标利率历史数据集(1990.1-2024.9)

美联储在2024年9月18日宣布将其调50个基点&#xff0c;降至4.75%至5.00%之间的水平。这是美联储自2020年3月以来首次降息&#xff0c;也是自2023年7月将利率水平调升至历史高位后的首次下调&#xff0c;标志着货币政策由紧缩周期向宽松周期的转向。一、数据介绍 数据名称&…

web基础—dvwa靶场(八)XSS

XSS(DOM) 跨站点脚本&#xff08;XSS&#xff09;攻击是一种注入攻击&#xff0c;恶意脚本会被注入到可信的网站中。当攻击者使用 web 应用程序将恶意代码&#xff08;通常以浏览器端脚本的形式&#xff09;发送给其他最终用户时&#xff0c;就会发生 XSS 攻击。允许这些攻击成…

网络-内核是如何与用户进程交互

1、socket的直接创建 net/socket.cSYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) {...retval sock_create(family, type, protocol, &sock);... }int sock_create(int family, int type, int protocol, struct socket **res) {return __sock_create(cu…

字符串函数的使用与模拟(2)——C语言内存函数

目录 1. memcpy函数的使用与模拟 2. memmove函数的使用与模拟 3. memset函数的使用 4. memcmp函数的使用 5. memchr函数的使用 前言&#xff1a;C语言内存函数是一组用于直接操作计算机内存的内置函数。使用时要包含头文件<string.h> 1. memcpy函数的使用与模拟 函…

【MYSQL表的增删改查(进阶)】

MYSQL表的增删改查&#xff08;进阶&#xff09; 一、新增二、查询2.1 聚合查询2.1.1 聚合函数count&#xff08;&#xff09;sum&#xff08;&#xff09;AVG&#xff08;&#xff09;MAX&#xff08;&#xff09;&#xff0c;MIN&#xff08;&#xff09;GROUP_CONCAT() 2.1.…

前端学习杂乱记录

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Html二、CSS1. BFC布局2. 定位总结3. 动画1. transform变换2. transition过渡3. keyframes 和 animation 3. 伸缩盒模型&#xff1a;flex布局 三、JS1. 逻辑中断…

nvm安装实现node多版本的切换

nvm安装实现node多版本的切换 方式一 下载安装包安装下载安装包解压安装设置 nvm 环境变量查看 nvm 是否安装完成安装 node 环境切换 node 版本列出已经安装的版本 方式二 一键脚本安装下载安装查看 nvm 是否安装完成安装 node 环境切换 node 版本列出已经安装的版本nvm相关命令…

PyTorch中的学习率预热(warmup)

PyTorch提供了学习率调度器(learning rate schedulers)&#xff0c;用于在训练过程中实现各种调整学习率的方法。实现在torch.optim.lr_scheduler.py中&#xff0c;根据epoch数调整学习率。大多数学习率调度器可以称为背对背(back-to-back)&#xff0c;也称为链式调度器&#x…

Linux入门2

文章目录 一、Linux基本命令1.1 文件的创建和查看命令1.2 文件的复制移动删除等命令1.3 查找命令1.4 文件的筛选和管道的使用1.5 echo、tail和重定向符 二、via编辑器三、权限控制3.1 root用户&#xff08;超级管理员&#xff09;3.2 用户和用户组3.3 权限信息3.4 chmod命令 一…

Streamlit:使用 Python 快速开发 Web 应用

一、简单介绍 Streamlit 是一个开源 Python 库&#xff0c;官网地址&#xff1a; https://streamlit.io/http://StreamlitStreamlit 是一个开源的 Python 框架&#xff0c;旨在为数据科学家和 后端工程师们提供只需几行代码即可创建动态数据应用的功能。 让没有任何前端基础…

C#软键盘设计字母数字按键处理相关事件函数

应用场景&#xff1a;便携式设备和检测设备等小型设备经常使用触摸屏来代替键盘鼠标的使用&#xff0c;因此在查询和输入界面的文本或者数字输入控件中使用软件盘来代替真正键盘的输入。 软键盘界面&#xff1a;软键盘界面实质上就是一个普通的窗体上面摆放了很多图片按钮&…

使用SpringCloud构建可伸缩的微服务架构

Spring Cloud是一个用于构建分布式系统的开源框架。它基于Spring Boot构建&#xff0c;并提供了一系列的工具和组件&#xff0c;用于简化开发分布式系统的难度。Spring Cloud可以帮助开发人员快速构建可伸缩的微服务架构。 要使用Spring Cloud构建可伸缩的微服务架构&#xff0…

实时监控局域网计算机桌面怎么设置!五个可实现的方法分享,绝了!

员工在工作时间里究竟在做什么&#xff1f;他们的网络活动是否合规&#xff1f;如何确保敏感信息不被泄露&#xff1f; 在企业管理层面&#xff0c;实时监控局域网计算机桌面已成为提升工作效率、确保数据安全与规范员工行为的重要手段。 技术的不断进步&#xff0c;多种解决…

【C++进阶】map和set的使用

【C进阶】map和set的使用 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 序列式容器和关联式容器 2. set系列的使用 2.1 set 和 multiset 2.2 set 类的介绍 2.3 set 的构造和…

【Linux篇】常用命令及操作技巧(基础篇)

&#x1f30f;个人博客主页&#xff1a;意疏-CSDN博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 阅读指南&#xff1a; 开篇说明帮助命令常见的七个linux操作终端实用的技巧跟文件目录…

C++11之统一的列表初始化

一.{}初始化 在c98中&#xff0c;标准允许使用{}对数组或结构体元素进行统一的列表初始值设定&#xff1a; struct mess {int _x;string _str; }; int main() {//注意&#xff0c;使用new的一定是指针int* arr new int[4] {1, 2, 3, 4};//数组初始化int arr[] { 1,3,5,6 };…

基于Spring Boot和Vue的私人牙科诊所系统的设计与实现(毕业论文)

目 录 1 前言 1 1.1 研究目的与意义 1 1.2 国内外研究概况 1 1.3 主要研究内容 2 1.4 论文结构 3 2 系统分析 3 2.1 可行性分析 3 2.1.1 技术可行性分析 3 2.1.2 经济可行性分析 3 2.1.3 操作可行性分析 4 2.1.4 法律可行性分析 4 2.2 需求分析 4 2.2.1 管理员需求分析 4 2.2.2…

3.1 数据表的基本查询

我们学习的怎么管理逻辑空间&#xff0c;怎么创建数据表&#xff0c;怎么定义字段&#xff0c;怎么创建索引&#xff0c;这些都是DDL语句。从本次课开始&#xff0c;我们来学习DML语句&#xff0c;也就是该如何增删改查操作数据。我们学习DML语句的前提是数据表要有足够多的数据…