本章我们学习一下Hilditch算法的基本原理,从网上找资料的时候,竟然发现两个有很大差别的算法描述,而且都叫Hilditch算法。不知道那一个才是正宗的,两个算法实现的效果接近,第一种算法更好一些。

第一种算法描述参考paper和代码:

Linear Skeletons from Square Cupboards

Speedup Method for Real-Time Thinning Algorithm

http://cis.k.hosei.ac.jp/~wakahara/Hilditch.c

第二种算法描述参考资料:

http://cgm.cs.mcgill.ca/~godfried/teaching/projects97/azar/skeleton.html#algorithm

 

下面我们分别看一下这两种算法描述:

一、第一种算法描述

假设当前被处理的像素为p0,我们使用下图所示的8邻域表示方式。

OpenCV学习(15) 细化算法(3)

     我们处理的为二值图像,背景为黑色,值为0,要细化的前景物体像素值为255。

     对于Hilditch算法来说,它并不是一个完全的并行算法,而是串行并行相结合。当前像素是否是能够删除的骨架点,不仅是由它周围的8邻域决定,而且和前面像素的判定结果有关。一个像素判定为可以删除,我们并不直接删除它,而是在目地图像中设置像素值为GRAY=128,这个信息可能会影响之后其它像素的判定。

      当图像一次扫描迭代完成后,我们把所有置为GRAY的像素设置为0,从而删除它。

 

算法的描述如下。

迭代扫描当前图像

    对于当前像素点,扫描它的8邻域,如果邻域的像素值为255,则b[i]=1(i=0…8),像素值为128(GRAY,表示该像素点在前面的循环中被标记为删除),b[i]=-1,如果像素值为0,则b[i]=0。

OpenCV学习(15) 细化算法(3)OpenCV学习(15) 细化算法(3)

下面会根据b[i]的值进行6个条件判断,如果条件满足,则会标记该像素值为GRAY(128)。

1. b[0]=1,即当前像素必须为前景点。

2. 1-abs(b1) + 1 – abs(b3) + 1 – abs(b5) + 1 – abs(b7) >= 1,该条件表示当前像素为边界点,即东西南北四个点至少有一个b[i]=0。

3. abs(b1)+…+abs(b8)>=2, 该条件表示不能删除端点,即p0点周围只有一个点为1或-1的情况。

4.  统计b1到b8等于1的数量,该数量值必须大于1,该条件表示不能删除端点。、

5.  连通性检测,使用下面的公式:首先根据当前像素周围3*3域的值,记录d[9]数组,如果b[i]等于0,则d[i]=0, 否则d[i]=1,最后计算 d1-d1*d2*d3+d3-d3*d4*d5+d5-d5*d6*d7+d7-d7*d8*d1是否为1,为1则满足连通性,可以删除。

OpenCV学习(15) 细化算法(3)

6.最后一个条件保证当轮廓是2个像素宽时,只删除一边。统计sum的值,当值为8时候,可以删除。

sum = 0;
for (i = 1; i <= 8; i++)
{
    if (b[i] != -1)
    {
        sum++;
    } else
    {
        copy = b[i];
        b[i] = 0;
        if (func_nc8(b) == 1) sum++;
        b[i] = copy;
    }

     当这6个条件都满足时候,标记当前像素值为GRAY(128),然后在判断别的像素。当所有像素都扫描一遍后,完成一次迭代。

此时我们会把刚才标记为GARY的像素,都设置为0,真正的删除它,如果上一次循环已经没有标记删除的像素,则退出迭代,否则进行下一次迭代。

算法代码:

while (counter != 0);

}

二、第二种算法描述

       第二种算法描述和Zhang的并行算法很相似,特别是前2个条件一模一样,不同的是3,4两个条件,还有就是该描述算法并没有像zhang算法那样,把一次迭代分成2个阶段。

此时我们使用的8邻域标记为:

OpenCV学习(15) 细化算法(3)

下面看下它的算法描述:

复制目地图像到临时图像,对临时图像进行一次扫描,对于不为0的点,如果满足以下四个条件,则在目地图像中删除该点(就是设置该像素为0)

a. 2<= p2+p3+p4+p5+p6+p7+p8+p9<=6

    大于等于2会保证p1点不是端点或孤立点,因为删除端点和孤立点是不合理的,小于等于6保证p1点是一个边界点,而不是一个内部点。等于0时候,周围没有等于1的像素,所以p1为孤立点,等于1的时候,周围只有1个灰度等于1的像素,所以是端点(注:端点是周围有且只能有1个值为1的像素)。

OpenCV学习(15) 细化算法(3)

b. p2->p9的排列顺序中,01模式的数量为1,比如下面的图中,有p2p3 => 01, p6p7=>01,所以该像素01模式的数量为2。

OpenCV学习(15) 细化算法(3)

  之所以要01模式数量为1,是要保证删除当前像素点后的连通性。比如下面的图中,01模式数量大于1,如果删除当前点p1,则连通性不能保证。

OpenCV学习(15) 细化算法(3)

 

c. p2.p4.p8 = 0 or A(p2)!=1,A(p2)表示p2周围8邻域的01模式和。这个条件保证2个像素宽的垂直条不完全被腐蚀掉。

OpenCV学习(15) 细化算法(3)

d.p2.p4.p6 = 0 or A(p4)!=1,A(p4)表示p4周围8邻域的01模式和。这个条件保证2个像素宽的水平条不完全被腐蚀掉。

OpenCV学习(15) 细化算法(3)

算法代码:

break;
}
}

第一种Hilditch算法的结果:

OpenCV学习(15) 细化算法(3)

OpenCV学习(15) 细化算法(3)OpenCV学习(15) 细化算法(3)

第二种Hilditch算法的结果:

OpenCV学习(15) 细化算法(3)

OpenCV学习(15) 细化算法(3)OpenCV学习(15) 细化算法(3)

程序代码:工程FirstOpenCV11

相关文章:

  • 2021-11-18
  • 2021-11-07
  • 2021-07-31
  • 2021-10-26
  • 2021-06-28
猜你喜欢
  • 2021-06-03
  • 2021-05-23
  • 2021-12-19
  • 2021-12-03
  • 2022-01-14
  • 2021-07-23
  • 2021-10-21
相关资源
相似解决方案