博客
关于我
(八)HS角点检测
阅读量:797 次
发布时间:2023-03-28

本文共 4592 字,大约阅读时间需要 15 分钟。

基础理论

在处理适用于多幅图像的特征描述子时,主要有两种特征检测方法:一种是基于角的检测,另一种是处理图像中的所有区域。这里主要讨论一下基于角的检测。

1988年,Harris和Stephens提出了一种角检测算法——HS角检测器。这一算法通过数学公式来区分三种情况:

  • 各个方向上灰度均不变化。
  • 在某个方向上变化,但在另一个方向灰度不变。
  • 两个方向都发生变化。
  • HS角检测器通过计算每个像素点周围邻域的灰度变化量,找到灰度变化最大的方向,即角的位置。

    HS角检测器的工作原理

    HS角检测器计算每个像素点周围邻域的灰度变化量。具体来说,对于图像中的一个像素点 $(s, t)$,其周围邻域的像素点 $(s+x, t+y)$ 的灰度变化量的平方和可以表示为:

    $$C(x, y) = \sum_{s,t} \omega(s,t) [f(s+x, t+y) - f(s, t)]^2$$

    其中,$\omega(s,t)$ 是一个加权函数,用于控制每个像素点对周围变化的敏感度。$f(s+x, t+y)$ 表示泰勒展开的近似值:

    $$f(s+x, t+y) \approx f(s, t) + x f_x(s, t) + y f_y(s, t)$$

    将上述近似代入灰度变化量的计算中,得到:

    $$C(x, y) = \sum_{s,t} \omega(s,t) [x f_x(s, t) + y f_y(s, t)]^2$$

    这可以表示为矩阵形式:

    $$C(x, y) = [x, y] M [x; y]$$

    其中,$M$ 是一个 2x2 矩阵:

    $$M = \sum_{s,t} \omega(s,t) A$$

    $A$ 是一个矩阵,用于计算梯度的平方和:

    $$A = \begin{bmatrix}f_x^2 & f_x f_y \f_x f_y & f_y^2\end{bmatrix}$$

    $M$ 被称为 Harris矩阵。矩阵 $M$ 的特征值与特征向量方向上的数据扩展量成正比。特征值的大小反映了灰度变化的程度:

    • 两个特征值都大时,表示存在一个角。
    • 一个特征值较大,一个较小时,表示存在垂直或水平边界。
    • 两个特征值都小,表示灰度变化很小。

    为了避免手动计算特征值,HS角检测器使用迹和行列式来判断角的存在。

    • $R = \lambda_x \lambda_y - k (\lambda_x + \lambda_y)^2 = \det(M) - k \text{trace}(M)^2$
    • $k$ 是一个敏感度参数,通常取值在 $(0, 0.25)$ 之间。

    $k$ 的值影响角的检测数量:$k$ 越小,检测到的角越多。

    Shi-Tomasi 角点检测器

    为了进一步提高角点检测的稳定性和鲁棒性,Jianbo Shi 和 Carlo Tomasi 在 1994 年提出了 Shi-Tomasi 角点检测器。该算法直接使用最小特征值作为度量:

    $$R = \min(\lambda_x, \lambda_y)$$

    与 HS 角检测器不同,Shi-Tomasi 算法避免了超参数 $k$ 的使用,从而更加简洁和灵活。

    OpenCV API

    OpenCV 提供了丰富的函数和接口来实现角检测和相关操作。以下是相关 API 的说明:

    2.1 cornerHarris 函数

    void cv::cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType = BORDER_DEFAULT)
    • src:输入图像,8 位单通道灰度图像。
    • dst:存储 Harris 检测结果的图像,数据类型为 CV_32FC1。
    • blockSize:计算 $C(x, y)$ 时的邻域大小。
    • ksize:使用 Sobel 算子计算梯度时的卷积核大小。
    • k:检测角的敏感度参数。
    • borderType:边界像素的处理方式,默认为 BORDER_DEFAULT。

    2.2 goodFeaturesToTrack 函数

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

    该函数实现了角点检测的完整流程:

  • 使用 cornerHarris 计算每个像素的角度度量。
  • 在 3x3 邻域范围内执行极大值抑制。
  • 根据最小特征值和质量水平筛选角点。
  • 排除距离过近的角点。
  • 示例

    以下是一个使用 OpenCV 实现角点检测的示例代码:

    #include 
    #include
    #include
    #include
    using namespace cv;using namespace std;Mat src, src_gray;int maxCorners = 23;int maxTrackbar = 100;RNG rng(12345);int thresh = 200;int max_thresh = 255;const char* source_window = "Source image";const char* corners_window = "Corners detected";void cornerHarris_demo(int, void*) { int blockSize = 2; int apertureSize = 3; double k = 0.04; Mat dst = Mat::zeros(src.size(), CV_32FC1); cornerHarris(src_gray, dst, blockSize, apertureSize, k); Mat dst_norm, dst_norm_scaled; normalize(dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); convertScaleAbs(dst_norm, dst_norm_scaled); for (int i = 0; i < dst_norm.rows; i++) { for (int j = 0; j < dst_norm.cols; j++) { if ((int)dst_norm.at
    (i, j) > thresh) { circle(dst_norm_scaled, Point(j, i), 5, Scalar(0), 2, 8, 0); } } } namedWindow(corners_window); imshow(corners_window, dst_norm_scaled); imwrite("corner_grid.png", dst_norm_scaled);}void goodFeaturesToTrack_Demo(int, void*) { maxCorners = MAX(maxCorners, 1); vector
    corners; double qualityLevel = 0.01; double minDistance = 10; int blockSize = 3, gradientSize = 3; bool useHarrisDetector = false; double k = 0.04; Mat copy = src.clone(); goodFeaturesToTrack(src_gray, corners, maxCorners, qualityLevel, minDistance, Mat(), blockSize, gradientSize, useHarrisDetector, k); cout << "** Number of corners detected: " << corners.size() << endl; int radius = 8; for (size_t i = 0; i < corners.size(); i++) { circle(copy, corners[i], radius, Scalar(0, 0, rng.uniform(0, 256)), FILLED); } namedWindow(source_window); imwrite("corner_grid_st.png", copy); imshow(source_window, copy);}int main(int argc, char** argv) { CommandLineParser parser(argc, argv, "{@input | building.jpg | input image}"); src = imread(samples::findFile(parser.get
    ("@input"))); if (src.empty()) { cout << "Could not open or find the image!\n"; cout << "Usage: " << argv[0] << "
    \n"; return -1; } cvtColor(src, src_gray, COLOR_BGR2GRAY); namedWindow(source_window); createTrackbar("Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo); imshow(source_window, src); goodFeaturesToTrack_Demo(0, 0); waitKey(); return 0;}

    代码解释

  • cornerHarris_demo 函数:使用 cornerHarris 函数计算角度度量,并绘制结果图像。
  • goodFeaturesToTrack_Demo 函数:使用 goodFeaturesToTrack 函数检测角点,并绘制结果图像。
  • main 函数:初始化图像,创建滑动条,展示结果。
  • 通过这些函数,可以轻松实现基于 Harris 和 Shi-Tomasi 算法的角点检测,适用于多种图像处理任务。

    转载地址:http://uohfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现max_heap最大堆算法(附完整源码)
    查看>>
    Objective-C实现md5算法(附完整源码)
    查看>>
    Objective-C实现memoization优化技术算法(附完整源码)
    查看>>
    Objective-C实现memset函数功能(附完整源码)
    查看>>
    Objective-C实现merge insertion sort合并插入排序算法(附完整源码)
    查看>>
    Objective-C实现merge sort归并排序算法(附完整源码)
    查看>>
    Objective-C实现mergesort归并排序算法(附完整源码)
    查看>>
    Objective-C实现miller rabin米勒-拉宾素性检验算法(附完整源码)
    查看>>
    Objective-C实现Miller-Rabin素性测试程序(附完整源码)
    查看>>
    Objective-C实现Miller-Rabin素性测试程序(附完整源码)
    查看>>
    Objective-C实现MinhashLSH算法(附完整源码)
    查看>>
    Objective-C实现MinHeap最小堆算法(附完整源码)
    查看>>
    Objective-C实现multilayer perceptron classifier多层感知器分类器算法(附完整源码)
    查看>>
    Objective-C实现n body simulationn体模拟算法(附完整源码)
    查看>>
    Objective-C实现naive string search字符串搜索算法(附完整源码)
    查看>>
    Objective-C实现natural sort自然排序算法(附完整源码)
    查看>>
    Objective-C实现nested brackets嵌套括号算法(附完整源码)
    查看>>
    Objective-C实现nevilles method多项式插值算法(附完整源码)
    查看>>
    Objective-C实现newtons second law of motion牛顿第二运动定律算法(附完整源码)
    查看>>
    Objective-C实现newton_raphson牛顿拉夫森算法(附完整源码)
    查看>>