Harris角点检测及代码分析(续)

本文详细介绍了OpenCV中的cvGoodFeaturesToTrack()函数,该函数用于角点检测,并对比了不同版本间的优化差异。从Harris角点检测到非极大值抑制,再到距离滤波器的应用,文章全面解析了角点检测的算法步骤。
摘要由CSDN通过智能技术生成

紧接着“Harris角点检测及代码分析”,这里主要分析OpenCV的cvGoodFeaturesToTrack()函数,这才是角点提取的真正代码。
Jianbo Shi, Carlo Tomasi. Good Features to Track. CVPR94
时间:2015-05-25 16:12

算法步骤

  1. cvCornerHarris()函数仅计算出每个像素单元的 R 值,然后再对R进行过滤,仅留下 β×maxR 的像素点;
  2. 非极大值抑制(Non-Maximum Suppression),我看到网上很多人直接Dilate-Image && Origin-Image,但这样会形成角点块,除非有下面的步骤;
  3. 对该阶段的角点 R 值进行降序排序;
  4. 距离滤波器,过滤点靠太近的点,留下R值高的角点。

代码分析

便于理解先看OpenCV1.0的cvGoodFeaturesToTrack()源码,已删除了与理解算法无关的代码。

void cvGoodFeaturesToTrack(...)
{
    // 是否使用harris角点响应器
    if(use_harris)
    {
        // harris角点响应值,det(M)-a*(trace(M))^2
        cvCornerHarris(img, eig, block_size, 3, harris_k);
    }
    else
    {
        // 用最小特征值作为响应值
        cvCornerMinEigenVal(img, eig, block_size, 3);
    }
    cvMinMaxLoc(eig, 0, &max_val, 0, 0, mask);
    cvThreshold(eig, eig, max_val * 0.01, 0, CV_THRESH_TOZERO);
    cvDilate(eig, tmp);

    min_dist = cvRound(min_distance * min_distance);

    // 检查原响应图与dilate图的每个像素,如果不为0且相等,则为候选角点
    for(y = 1, k = 0; y < size.height - 1; y++)
    {
        for(x = 1; x < size.width - 1; x++)
        {
            if(eig_data[x] != 0 && eig_data[x] == tmp_data[x])
                ptr_data[k++] = eig_data + x;
        }
    }

    // 对候选角点按响应值降序排序
    icvSortFeatures( ptr_data, k, 0 );

    // 遍历所有候选角点,如果当前角点与前面所有角点的欧式距离小于min_dist,
    // 则标记为真正角点
    for(i = 0; i < k; i++)
    {
        for(j = 0; j < count; j++)
        {
            int dx = x - ptr[j].x;
            int dy = y - ptr[j].y;
            int dist = dx * dx + dy * dy;

            if(dist < min_dist)
                break;
        }

        if(j == count)
        {
            ptr[count].x = x;
            ptr[count].y = y;
            if(++count >= max_count)
                break;
        }
    }
}

算法优化

OpenCV2.0以上版本在goodFeaturesToTrack()函数中对距离滤波器做了修改,应该是为了加速做的改进。具体方法为:

  1. 对整张图像划分网格,每个网格的大小为min_dist * min_dst,网格数量为grid_width * grid_height;
  2. 建立二维矩阵,grid(grid_width * grid_height),用来存放最终标记的角点;
  3. 进行距离滤波时,计算出候选角点所在网格,仅需检测网格8领域的角点与候选角点的距离,就能快速verify。

为了保证能计算出比较多的角点,一般min_dist设置得比较小,如果10,针对一张640 * 480的图像检测角点,应该能有不错的性能提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值