FAST角点检测算法(二)- 非极大值抑制筛选fast特征点

FAST角点检测算法(二)- 非极大值抑制筛选fast特征点


author@jason_ql(lql0716)
http://blog.csdn.net/lql0716


  • fast角点检测算法参考文章《fast角点检测算法》(涵盖fast角点检测原理及C++、python代码,以及效果图)

  • 非极大值抑制,就是对于一个3*3(或5*5,7*7等奇数窗口)的窗口,如果存在多个特征点,则删除响应值较小的特征点,只保留响应值最大的特征点。

  • 这里根据fast特征点的响应值的大小,做了非极大值抑制处理,对特征点进行了筛选。

1.1 C++代码

#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

//局部极大值抑制,这里利用fast特征点的响应值做比较
void selectMax(int window, cv::Mat gray, std::vector<KeyPoint> & kp){

    //window是局部极大值抑制的窗口大小,r为半径
    int r = window / 2;
    if (window != 0){
        //对kp中的点进行局部极大值筛选
        for (int i = 0; i < kp.size(); i++){
            for (int j = i + 1; j < kp.size(); j++){
                //如果两个点的距离小于半径r,则删除其中响应值较小的点
                if (abs(kp[i].pt.x - kp[j].pt.x) + abs(kp[i].pt.y - kp[j].pt.y) <= 2 * r){
                    if (kp[i].response < kp[j].response){
                        std::vector<KeyPoint>::iterator it = kp.begin() + i;
                        kp.erase(it);
                        selectMax(window, gray, kp);
                    }
                    else{
                        std::vector<KeyPoint>::iterator it = kp.begin() + j;
                        kp.erase(it);
                        selectMax(window, gray, kp);
                    }
                }
            }
        }
    }

}

//
void fastpoint(cv::Mat gray, int threshold, int window, int pointNum, std::vector<KeyPoint> & kp){

    std::vector<KeyPoint> keypoint;

    cv::FastFeatureDetector fast(threshold, true);  //threshold 为阈值,越大,特征点越少
    fast.detect(gray, keypoint);  //fast特征检测
    if (keypoint.size() > pointNum){
        threshold = threshold + 5;
        fastpoint(gray, threshold, window, pointNum, keypoint);
    }
    selectMax(window, gray, keypoint);
    kp.assign(keypoint.begin(), keypoint.end());    //复制可以point到kp

}


int main(){
    cv::Mat img = cv::imread("D:/photo/06.jpg");
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    std::vector<KeyPoint> kp;
    int threshold = 30;  //fast阈值
    int window1 = 7;  //局部非极大值抑制窗口
    int pointMaxNum1 = 400; //特征点最大个数
    fastpoint(gray, threshold, window1, pointMaxNum1, kp);

    cv::Mat img2, gray2;
    std::vector<KeyPoint> kp2;
    img.copyTo(img2);
    gray.copyTo(gray2);
    int window2 = 15;  //局部非极大值抑制窗口
    int pointMaxNum2 = 400; //特征点最大个数
    fastpoint(gray2, threshold, window2, pointMaxNum2, kp2);

    cv::drawKeypoints(img, kp, img, Scalar(0, 0, 255));
    cv::drawKeypoints(img2, kp2, img2, Scalar(255, 0, 0));

    cv::imwrite("D:/photo/06_1.jpg", img);
    cv::namedWindow("img", cv::WINDOW_NORMAL);
    cv::imshow("img", img);

    cv::imwrite("D:/photo/06_2.jpg", img2);
    cv::namedWindow("img2", cv::WINDOW_NORMAL);
    cv::imshow("img2", img2);

    cv::waitKey(0);

    system("pause");
    return 0;
}

原图:
这里写图片描述

效果图img:
这里写图片描述

效果图img2:
这里写图片描述

1.2 python代码

# -*- coding: utf-8 -*-
"""
Created on Fri Jun 16 09:55:41 2017

@author: User
"""

import cv2
import numpy as np
import copy

def selectMax(window, gray, kp):
    r = window / 2
    a = 0
    if window != 0:
        for i in range(np.array(kp).shape[0]):
            for j in range(i+1, np.array(kp).shape[0]):
                if np.abs(kp[i].pt[0]-kp[j].pt[0]) + np.abs(kp[i].pt[1] - kp[j].pt[1]) <= 2*r:
                    if kp[i].response < kp[j].response:
                        kp.pop(i)                      
                        a = 1
                        break
                    else:
                        kp.pop(j)
                        a = 1
                        break
        if a != 0:
            kp = selectMax(window, gray, kp)

    return kp

def fastpoint(gray, threshold, window, pointNum):
        #fast = cv2.FeatureDetector_create('FAST')
    #cv2.FAST_FEATURE_DETECTOR_TYPE_5_8
    #cv2.FAST_FEATURE_DETECTOR_TYPE_7_12
    #cv2.FAST_FEATURE_DETECTOR_TYPE_9_16

    fasts = cv2.FastFeatureDetector(threshold)
    kp = fasts.detect(gray, None)
    if np.array(kp).shape[0] > pointNum:
        threshold = threshold + 5
        kp = fastpoint(gray, threshold, window, pointNum)

    kp0 = selectMax(window, gray, kp)
    return kp0


img = cv2.imread('D:/photo/06.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
threshold = 20;
window1 = 7
pointMaxNum1 = 400
kp = fastpoint(gray, threshold, window1, pointMaxNum1)


img2 = copy.deepcopy(img)
gray2 = copy.deepcopy(gray)
window2 = 15
pointMaxNum2 = 400
kp2 = fastpoint(gray2, threshold, window2, pointMaxNum2)

img = cv2.drawKeypoints(img, kp, color = (0,255,255))
img2 = cv2.drawKeypoints(img2, kp2, color = (255,255,0))

cv2.imwrite('D:/photo/06_1p.jpg', img)
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.imshow('img',img)

cv2.imwrite('D:/photo/06_2p.jpg', img2)
cv2.namedWindow('img2', cv2.WINDOW_NORMAL)
cv2.imshow('img2',img2)

cv2.waitKey(0)

效果图img:
这里写图片描述

效果图img2:
这里写图片描述


  • 相关文章

  • 10
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Susan角点检测是一种计算机视觉中常用的角点检测算法,它可以用来检测图像中的角点。这个算法的基本思想是寻找图像中像素点周围像素点的变化率最小的位置,这些位置就是图像中的角点。 在实现Susan角点检测算法时,通常还需要进行非极大值抑制。这是因为在图像中存在很多的局部极大值,如果不进行抑制,就会导致角点检测结果不准确。 以下是一个实现Susan角点检测非极大值抑制的Python代码示例: ```python import numpy as np import cv2 def susan_corner_detection(image, threshold=27, radius=3): height, width = image.shape[:2] corners = np.zeros((height, width), dtype=np.uint8) dx = [1, 1, 0, -1, -1, -1, 0, 1] dy = [0, 1, 1, 1, 0, -1, -1, -1] for i in range(radius, height - radius): for j in range(radius, width - radius): center_pixel = image[i, j] count = 0 for k in range(8): x = i + dx[k] y = j + dy[k] if image[x, y] < center_pixel: count += 1 if count > threshold: corners[i, j] = 255 return corners def non_maximum_suppression(image, window_size=3): height, width = image.shape[:2] offset = window_size // 2 corners = np.zeros((height, width), dtype=np.uint8) for i in range(offset, height - offset): for j in range(offset, width - offset): if image[i, j] == 0: continue local_max = True for k in range(-offset, offset + 1): for l in range(-offset, offset + 1): if image[i + k, j + l] > image[i, j]: local_max = False break if not local_max: break if local_max: corners[i, j] = 255 return corners # 读取图像 image = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE) # 进行角点检测 corners = susan_corner_detection(image) # 进行非极大值抑制 corners = non_maximum_suppression(corners) # 显示结果 cv2.imshow('image', image) cv2.imshow('corners', corners) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这个代码示例中,首先定义了一个`susan_corner_detection`函数和一个`non_maximum_suppression`函数分别用来进行Susan角点检测非极大值抑制。然后读取一张图像,调用`susan_corner_detection`函数进行角点检测,再调用`non_maximum_suppression`函数进行非极大值抑制,最后将结果显示出来。 需要注意的是,在进行非极大值抑制时,我们需要指定一个窗口大小`window_size`,窗口大小越大,角点检测的灵敏度就越低,检测出来的角点就越少。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI人工智能科学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值