Canny 算子的非极大值抑制

之前刚接触 Canny 算子的时候,已经理解过一次。最近需要再次用到它,又花了很长的时间去理解。为方便下次理解,做了这次笔记。文中代码是我从 matlab edge函数中 canny_old 部分中粘贴出来的部分代码,只是用来配合理解非极大值抑制的原理,不能直接使用。

Canny 非极大值抑制分成 3 部分:

  • 确定像素的梯度方向
  • 对像素线性插值,找出极大值点。
  • 将像素值大于低阈值的极大值点作为弱边缘

本文中符号表示:

  • X :讨论像素
  • ix:x 方向梯度值
  • iy:y方向梯度值
  • direction:梯度方向 1-4
  • mag 梯度幅度


1 确定像素梯度方向

在这里插入图片描述
如上图所示,X 是需要讨论的像素点,梯度向量的每个四分之一圆被45°线分成两种情况,一种情况是倾向于水平,另一种倾向于竖直。一共 8 个方向,因为我们使用关于中心像素的对称点,所以对于非极大值抑制我们只考虑其中 4 个(1 和 (1) 属于一个方向)

以图中属于方向 1 的区间为例: iy < 0, ix > 0, ix > -iy。
其他也是类似的分法。

这部分 Matlab edge 函数代码是这样的,非常简单明确:

switch direction
    case 1
        idx = find((iy<=0 & ix>-iy)  | (iy>=0 & ix<-iy));
    case 2
        idx = find((ix>0 & -iy>=ix)  | (ix<0 & -iy<=ix));
    case 3
        idx = find((ix<=0 & ix>iy) | (ix>=0 & ix<iy));
    case 4
        idx = find((iy<0 & ix<=iy) | (iy>0 & ix>=iy));
end



然后下面的部分我不理解,有知道的大佬望告知一下。
注释部分是:Exclude the exterior pixels(排除外部像素)外部像素是什么意思?

if ~isempty(idx)
  v = mod(idx, m);
  extIdx = (v == 1 | v == 0 | idx<=m | (idx > (n-1)* m)); 
  idx(extIdx) = [];
  end
ixv = ix(idx);
iyv = iy(idx);
gradmag = mag(idx);


2 线性插值

如果梯度极大值不在像素点上,而在他们之间的某一点(亚像素点)。那么为了算出这个点,就需要进行线性插值
在这里插入图片描述
还是以属于方向 1 的区间为例,红色点的梯度值由绿色点和黄色点的梯度值算出。
那么红色点是靠近黄色点还是绿色点?这就需要一个数来表示它于黄色点和绿色点的距离,我们将它命名为权重 d
在方向 1 的区间中 d = i y i x d = \frac{iy}{ix} d=ixiy

红色点的梯度值 gradmag1 = mag(idx+m)(黄色点梯度值).*(1-d) + mag(idx+m-1)(绿色梯度值).*d;

这里有个小知识:
Matlab 中矩阵元素下标是按列数的。比如
A = [ 8 1 6 3 5 7 4 9 2 ] A = \begin{bmatrix} 8 &amp; 1 &amp; 6 \\ 3 &amp; 5 &amp; 7 \\ 4 &amp; 9 &amp; 2 \\ \end{bmatrix} A=834159672
当寻找 A 中大于 5 的下标 find(A>5) 时:
A = [ 1 6 7 8 ] A = \begin{bmatrix} 1 \\ 6 \\ 7 \\ 8 \\ \end{bmatrix} A=1678
其中 8,9,6,7 的下标分别是 1,6,7,8.

这里注释是:对内部像素线性插值,一样没搞懂。

switch direction
  case 1
    d = abs(iyv./ixv);
    gradmag1 = mag(idx+m).*(1-d) + mag(idx+m-1).*d;
    gradmag2 = mag(idx-m).*(1-d) + mag(idx-m+1).*d;
  case 2
        d = abs(ixv./iyv);
        gradmag1 = mag(idx-1).*(1-d) + mag(idx+m-1).*d;
        gradmag2 = mag(idx+1).*(1-d) + mag(idx-m+1).*d;
  case 3
        d = abs(ixv./iyv);
        gradmag1 = mag(idx-1).*(1-d) + mag(idx-m-1).*d;
        gradmag2 = mag(idx+1).*(1-d) + mag(idx+m+1).*d;
  case 4
        d = abs(iyv./ixv);
        gradmag1 = mag(idx-m).*(1-d) + mag(idx-m-1).*d;
        gradmag2 = mag(idx+m).*(1-d) + mag(idx+m+1).*d;
end
获取极大值
idxLocalMax = idx(gradmag>=gradmag1 & gradmag>=gradmag2);

之后便是非极大值抑制部分,这部分理解起来比较简单

     idxWeak = idxLocalMax(mag(idxLocalMax) > lowThresh);
     e(idxWeak) = 1;
     idxStrong = [idxStrong; idxWeak(mag(idxWeak) > highThresh)];
  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值