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

  • 操作系统: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)2∑S(p)dI/dxdI/dy∑S(p)dI/dxdI/dy∑S(p)(dI/dy)2

其中导数使用 Sobel 操作符进行计算。

之后,它找到 M 的特征向量和特征值,并将它们存储在目标图像中,格式为 (λ1, λ2, x1, y1, x2, y2),其中

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

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

函数原型

cpp 复制代码
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。

代码示例

cpp 复制代码
#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;
}

运行结果

相关推荐
Easy_API3 小时前
2.8万亿参数,编程反超GPT-6 Astra:Kimi K3.1 Pro把开源模型推到了哪一步
大数据·人工智能·gpt·深度学习
GlobalInfo3 小时前
2026年机器人多指灵巧手市场分析报告——涵盖行业调查、趋势分析与发展前景
大数据·人工智能·microsoft·微服务·机器人
紧跟先前的步伐4 小时前
Go AI Agent 实战 24|工具系统工程化收尾与阶段验收
人工智能·ai·golang·1024程序员节
释厄6234 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
老金带你玩AI5 小时前
集万家所长,一键复制的Agent.md!
人工智能
ZhuoAIStage5 小时前
舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线
人工智能·自动化·工作流编排·舞台工艺·审图智能体
小奶包他干奶奶5 小时前
AI学习——1、机器学习概念
人工智能·机器学习
展讯快报5 小时前
悬浮提词器免费App评估报告:说得AI的免费策略与可用性分析
人工智能
Yuzhiyuxia5 小时前
【AI Agent面试系列】AI Agent记忆机制知识点1
人工智能·面试·职场和发展
2601_965448875 小时前
AI视频制作:做系列历史人物视频音色不搭,AI 音色克隆的方法实测
人工智能·音视频