OpenCV -- cornerHarris()函数 角点检测

cornerHarris函数对于每一个像素(x,y)在blockSize x blockSize 邻域内,计算2x2梯度的协方差矩阵M(x,y)。就可以找出输出图中的局部最大值,即找出了角点。

1
void cornerHarris( InputArray src, OutputArray dst, int block Size,  int ksize, double k, int borderType = BORDER_DEFAULT)

1.InputArray类型的src,输入图像,即原图像,填Mat类型即可,且需要为单通道8位或者浮点型图像;


2.OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和原图片有一样的尺寸和类型;


3.int类型的blockSize,表示邻域的大小,更多详细信息在cornerEigenValsAndVecs()中讲到;


4.int类型的ksize,表示Sobel()算子的孔径的大小;


5.double类型的k,Harris参数;


6.int类型的borderType,图像像素的边界模式。注意它有默认值BORDER_DEFAULT;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
 
#define WINDOW_NAME1 "窗口1"
#define WINDOW_NAME2 "窗口2"
 
Mat g_srcImage, g_srcImage1, g_grayImage;
int g_nThresh = 30; //当前阀值
int g_nMaxThresh = 175;
 
void on_fCornerHarris(int, void*)
{
    Mat dstImage; //目标图
    Mat normImage; //归一化后的图
    Mat scaledImage; //线性变换后的八位无符号整形的图
 
    // 置零当前需要显示的两幅图,即清除上一次调用此函数时他们的值
    dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
    g_srcImage1 = g_srcImage.clone();
 
    //角点检测
    cornerHarris(g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);
    normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
 
    //将归一化后的图线性变换成8位无符号整形
    convertScaleAbs(normImage, scaledImage);
 
    //将检测到的,且符合阀值条件的角点绘制出来
    for (int i = 0; i < normImage.rows; i++)
    {
        for (int j = 0; j < normImage.cols; j++)
        {
            if ((int)normImage.at<float>(i, j) > g_nThresh + 80)
            {
                circle(g_srcImage1, Point(j, i), 5, Scalar(10, 10, 255), 2, 8, 0);
                circle(scaledImage, Point(j, i), 5, Scalar(0, 10, 255), 2, 8, 0);
            }
        }
    }
    imshow(WINDOW_NAME1, g_srcImage1);
    imshow(WINDOW_NAME2, scaledImage);
}
 
int main()
{
    g_srcImage = imread("fangzi.jpg");
    g_srcImage.copyTo(g_srcImage1);
    cvtColor(g_srcImage1, g_grayImage, COLOR_BGR2GRAY);
 
    namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
    createTrackbar("阀值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_fCornerHarris);
 
    on_fCornerHarris(0, NULL);
 
    waitKey(0);
    return 0;
}

  在原图中:

 

 

在二值图中:

 

Shi-Tomasi角点检测是Harris角点检测算法的改进,见下文:

posted @   手磨咖啡  阅读(1741)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示