• OpenCV(四十二):Harris角点检测


    1.Harris角点介绍

    什么是角点? 角点指的是两条边的交点,图中红色圈起来的点就是角点。

    Harris角点检测原理:首先定义一个矩形区域,然后将这个矩形区域放置在我的图像中,求取这个区域内所有的像素值之和,之后沿着多个方向移动我这个区域,再次计算新区域的像素值之和,如果移动前和移动后的像素值两者的差值比较小,那么就不是Harris角点,如果两者之间差值比较大,就认定移动前覆盖的区域内存在Harris角点。

    如图:下图两条线形成角点,而矩形区域分别表示平面、边界、角点三种位置:

    2.Harris角点计算

    Harris角点检测原理:当移动窗口,窗口内像素值变化大就有Harris角点

    Harris角点检测原理公式:

    权重系数的引入是为了更加方便地去确定某一个点是Harris角点。

    Harris角点检测原理公式写成矩阵形式:

    由此可得出梯度协方差矩阵M

    Harris评价函数来测量每个像素的角点程度 ,与梯度协方差矩阵M相关

         在这个公式中,R是角点响应函数的值,M是一个2x2的矩阵,描述了局部区域中像素的梯度信息,det(M)表示矩阵的行列式,trace(M)表示矩阵的迹,k是一个常数,用于调节响应函数的敏感度。

    Harris评价函数可以用特征向量来表示。λ1和λ2分别是M的两个特征值。

    通过对特征值λ1和λ2进行求解,我们可以计算Harris评价函数R,并据此来判断像素是否为角点。

    • 当λ1和λ2都较大且接近时,表示图像局部区域存在角点。
    • 当λ1和λ2都比较小或者差异较大时,表示图像局部区域是平坦或者边缘区域。

    3.检测Harris角点函数cornerHarris()

    void cv::cornerHarris ( InputArray  src,

    OutputArray dst,

    int   blockSize,

    int   ksize,

    double   K,

    int         borderType = BORDER_DEFAULT

    • src:待检测Harris角点的输入图像,图像必须是CV 8U或者CV 32F的单通道灰度图像
    • dst: 存放Harris评价系数的R矩阵,数据类型为CV 32F的单通道图像,与输入图像具有相同的尺寸
    • blockSize:邻域大小
    • ksize: Sobel算子的半径,用于得到梯度信息   
    • k:计算Harris评价系数R的权重系数
    • borderType:像素外推算法标志

    4.绘制角点函数drawKeypoints()

    void drawKeypoints(InputArray image,

    const std::vector& keypoints,

    OutputArray outImage,

    const Scalar& color = Scalar::all(-1),

    int flags = DrawMatchesFlags::DEFAULT

    )

    参数说明:

    • image: 输入图像,可以是任意类型的Mat对象。

    • keypoints: vector类型的关键点,每个关键点包含其在图像中的位置和其他信息(如尺度、方向等)。

    • outImage: 输出图像,用于存储绘制了特征点的图像。可以与输入图像相同的尺寸和类型。

    • color: 绘制特征点的颜色,可以是Scalar对象或CV_RGB(R, G, B)宏定义,默认为Scalar::all(-1)表示随机颜色。

    • flags: 绘制标志,用于控制绘制方式。可以是以下常量之一:

      • DrawMatchesFlags::DEFAULT: 默认绘制方式,显示关键点的位置和大小。

      • DrawMatchesFlags::DRAW_OVER_OUTIMG: 将关键点绘制在输出图像上,而不是创建新的输出图像。

      • DrawMatchesFlags::DRAW_RICH_KEYPOINTS: 绘制丰富的特征点,显示位置、尺度、方向等详细信息。

    5.示例代码:

    1. void Harris_f(Mat image){
    2. //转成灰度图像
    3. Mat gray;
    4. cvtColor(image,gray,COLOR_BGR2GRAY);
    5. // 执行Harris角点检测
    6. Mat harris;
    7. cornerHarris(gray,harris,2,3,0.04);
    8. //归一化便于进行数值比较和结果显示
    9. Mat harrisn;
    10. normalize(harris,harrisn,0,255,NORM_MINMAX);
    11. //将图像的数据类型变成CV_8U
    12. convertScaleAbs(harrisn,harrisn);
    13. //寻找Harris角点
    14. vector<KeyPoint> keyPoints;
    15. for(int row=0;row<harrisn.rows;row++){
    16. for(int col=0;col<harrisn.cols;col++){
    17. int R=harrisn.at<uchar>(row,col);
    18. if(R<180){
    19. //将角点存入KeyPoint中
    20. KeyPoint keyPoint;
    21. keyPoint.pt.y=row;
    22. keyPoint.pt.x=col;
    23. keyPoints.push_back(keyPoint);
    24. }
    25. }
    26. }
    27. //绘制角点
    28. drawKeypoints(image,keyPoints,image,Scalar(0,0,255,255));
    29. //与显示结果
    30. imwrite("/sdcard/DCIM/harrisn.png",harrisn);
    31. imwrite("/sdcard/DCIM/result.png",image);
    32. }

                  (系数矩阵)                                               (绘制Harris角点) 

  • 相关阅读:
    git常用操作总结
    振弦采集模块的通讯协议( IIC)
    毕业论文中的数据分析无从下手?
    Cobalt Strike 的 Beacon 使用介绍以及 Profile 文件修改Beacon内存教程
    【培训课程专用】中断路由代码导读:当cpu运行在TEE来了一个Non secure Group1中断
    CSS Position定位(详解网页中的定位属性)
    docker创建镜像
    力扣(LeetCode)315. 计算右侧小于当前元素的个数(2022.11.12)
    Qt 读写数据流文件(转 CppGuiProgrammingWithQt4)
    最好用的Boost.Asio:现代C++网络编程
  • 原文地址:https://blog.csdn.net/weixin_63357306/article/details/132889530