Matlab实现SUSAN角点检测

目录

1. 基本原理

2. Matlab代码

2.1 相似像素点统计函数

2.2  图像预处理

2.3 窗口滑动

2.4  筛选非角点

2.5  剔除伪角点

2.6 绘制图像

2.7 完整代码

3. 运行结果

4. 总结 

5. 代码获取


1. 基本原理

       为 了 提 取 图 像 的 角 点 ( 特 征 点 ),最 小 核 值 相 似 区 ( Smallest Univalue Segment Assimilating Nucleus,SUSAN)算法引入了圆形模板如图 1 所示,其中蓝色部分和红色部分表示圆形模板实际覆盖的像素点范围,红色部分表示模板核。

图1 SUSAN模板

       类似于卷积操作,SUSAN角点检测算法将圆形模板在图像上进行窗口滑动,每次滑动都会对圆形模板覆盖的像素点进行统计。统计时,算法会计算模板内蓝色部分像素值与模板核像素值的距离(即两者之差的绝对值),若距离小于给定距离阈值,则认为该像素属于SUSAN区域,计算公式如下:

       其中,c(r,r_0)用于判断像素是否属于 SUSAN 区域,I(r)为模板内蓝色区域像素值,I(r_0) 为模板核像素值,T为距离阈值。接着只需统计模板内属于 SUSAN 区域的像素值数量即可:

       其中,表示N(r_0)r_0 为模板核的模板内的蓝色区域覆盖的像素点集合,S(r_0) 表示该模板内相近的像素点个数。

       最后,模板滑动结束后,得到相似像素值数量矩阵S,记矩阵中的最大值为S_{max},则阈值 G可表示为G=3S_{max}/4,通过阈值 G来筛选非角点:

       一般地, S矩阵中非零值对应位置均为角点。但实际情况往往更为复杂,为了进一步剔除伪角点,可以采用 3X3 模板滑动方式扫描S,若模板中心值大于所有领域值,将该点记为角点,否则不记为角点。

2. Matlab代码

参考代码

SUSAN角点检测 - 百度文库https://wenku.baidu.com/view/d368076c862458fb770bf78a6529647d2728348e.html

2.1 相似像素点统计函数

       首先根据式(1)(2),编写 count 函数,用于统计模板 mask 内与模板核距离小于阈值 threshol 的像素个数。输入的 mask 模板的大小是 7X7,因此在 count 函数的前两行需要将圆形区域以外的部分设置为 NAN(非数字),接着统计符合要求的像素值个数 s。

function s = count(mask, threshold)
mask([1 7],[1 2 6 7]) = nan;
mask([2 6],[1 7]) = nan;
index = abs(mask(4,4)-mask) < threshold;
s = sum(index(:));
end

2.2  图像预处理

       读入图像后,若图像为彩色图像,需要先转换为灰度图像。将原始图像进行padding 操作,以便于后续的模板窗口滑动。

clear, close all
im = imread('cameraman.tif');
[row, col, channel] = size(im);
if channel == 3
    im_ = rgb2gray(im);
else
    im_ = im;
end
im_padded = zeros(row+6, col+6);
im_padded(4:end-3, 4:end-3) = im_;

2.3 窗口滑动

       执行模板窗口滑动操作,调用count函数,将统计结果记录在向量 S 中。

threshold = 45;
S = [];
for i = 4: row+3
    for j = 4: col+3
        mask = im_padded(i-3:i+3, j-3:j+3);
        S = [S count(mask, threshold)];
    end
end

2.4  筛选非角点

       将向量 S 还原回矩阵,得到相似像素值数量矩阵,即角点矩阵。计算阈值G,并通过式(3)筛选非角点,筛选后非零值对应位置一般为角点。

S = reshape(S, row, col);
S = fliplr(imrotate(S, -90));

G = 3*max(S(:))/4;
index = S < G;
S(index) = G-S(index);
S(~index) = 0;

2.5  剔除伪角点

      为进一步剔除伪角点,需判断每个角点是否为 3X3 邻域内的最大值。

loc = [];
for i = 2: row-1
    for j = 2: col-1
        temp = S(i-1:i+1,j-1:j+1);
        temp(2,2) = 0;
        if S(i,j) > temp
            loc = [loc; [j i]];
        end
    end
end

2.6 绘制图像

      绘制原始图像和角点检测图像。

subplot(1,2,1), imshow(im);
subplot(1,2,2), imshow(im);
hold on
plot(loc(:,1), loc(:,2), '*')

2.7 完整代码

clear, close all
%% 读取图像并padding
im = imread('cameraman.tif');
[row, col, channel] = size(im);
if channel == 3
    im_ = rgb2gray(im);
else
    im_ = im;
end
im_padded = zeros(row+6, col+6);
im_padded(4:end-3, 4:end-3) = im_;
%% 窗口滑动,得到角点向量
threshold = 45;
S = [];
for i = 4: row+3
    for j = 4: col+3
        mask = im_padded(i-3:i+3, j-3:j+3);
        S = [S count(mask, threshold)];
    end
end
%% 角点向量转矩阵
S = reshape(S, col, row);
S = fliplr(imrotate(S, -90));
%% 筛选非角点
G = 3*max(S(:))/4;
index = S < G;
S(index) = G-S(index);
S(~index) = 0;
%% 进一步剔除伪角点
loc = [];
for i = 2: row-1
    for j = 2: col-1
        temp = S(i-1:i+1,j-1:j+1);
        temp(2,2) = 0;
        if S(i,j) > temp
            loc = [loc; [j i]];
        end
    end
end
%% 绘制原始图像和角点检测图像
subplot(1,2,1), imshow(im);
subplot(1,2,2), imshow(im);
hold on
plot(loc(:,1), loc(:,2), '*')

%% 相似像素点统计函数
function s = count(mask, threshold)
mask([1 7],[1 2 6 7]) = nan;
mask([2 6],[1 7]) = nan;
index = abs(mask(4,4)-mask) < threshold;
s = sum(index(:));
end

3. 运行结果

       从图 2 可以观察 SUSAN 角点检测算法的准确度。一个明显的结果是左上方孤立的一个点,可以看到在原图中它是一个白色的像素点,不同于周边的灰色像素,它是一个较为明显的角点。

图2 角点检测人物

       从图 2,3,4 中可以看出,SUSAN 角点检测算法拥有较好的鲁棒性,能够较为准确地检测出图像的角点。从图 3 的两个字母 S 的结果可以看出,同一角点在不同位置也能检测出来,不受位置的影响。从图4和5可以看出,SUSAN 角点检测算法具有旋转不变性。

图3 角点检测单词

图4 角点检测抽象画

图5 图4旋转后的角点检测结果

4. 总结 

       算法优点 算法简单易于实现,角点位置识别准确,具有较好的鲁棒性,无需计算梯度,窗口滑动可以加速获得较快的检测速度。

       局限性 该算法仅适用灰度图像,对于彩色图像需要将其转换为灰度图像,忽略了彩色空间分量之间的关联性,从而导致检测结果可能并不准确。单纯通过统计模板中和模板核相近的像素点个数较为理想化,实际场景可能并不能仅凭该统计结果判断角点。

5. 代码获取

 关注公众号,回复“数字图像处理”,即可获取完整代码和测试图片

  • 1
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Toblerone_Wind

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

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

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

打赏作者

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

抵扣说明:

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

余额充值