图像细化方法

图像细化方法,第1张

快速zhang并行算法,很好的一种常用方法

具体细化方法:

满足下列四个条件的点可以删除

p3 p2 p9

p4 p1 p8

p5 p6 p7

细化删除条件为: (1)、2 < Nz(p1) <= 6 Nz为八邻域中黑点的数目

(2)、Zo(p1)=1,指中心为黑点

(3)、p2p4p8=0 or Zo(p1)!=1 避免黑线被打断

(4)、p2p4p6=0 or Zo(p4)!=1

细化算法的分类:

依据是否使用迭代运算可以分为两类:第一类是非迭代算法,一次即产生骨架,如基于距离变换的方法。游程长度编码细化等。第二类是迭代算法,即重复删除图像边缘满足一定条件的像素,最终得到单像素宽带骨架。迭代方法依据其检查像素的方法又可以再分成串行算法和并行算法,在串行算法中,是否删除像素在每次迭代的执行中是固定顺序的,它不仅取决于前次迭代的结果,也取决于本次迭代中已处理过像素点分布情况,而在并行算法中,像素点删除与否与像素值图像中的顺序无关,仅取决于前次迭代的结果。在经典细化算法发展的同时,起源于图像集合运算的形态学细化算法也得到了快速的发展。

Hilditch、Pavlidis、Rosenfeld细化算法:这类算法则是在程序中直接运算,根据运算结果来判定是否可以删除点的算法,差别在于不同算法的判定条件不同。

其中Hilditch算法使用于二值图像,比较普通,是一般的算法; Pavlidis算法通过并行和串行混合处理来实现,用位运算进行特定模式的匹配,所得的骨架是8连接的,使用于0-1二值图像 ;Rosenfeld算法是一种并行细化算法,所得的骨架形态是8-连接的,使用于0-1二值图像 。 后两种算法的效果要更好一些,但是处理某些图像时效果一般,第一种算法使用性强些。

索引表细化算法:经过预处理后得到待细化的图像是0、1二值图像。像素值为1的是需要细化的部分,像素值为0的是背景区域。基于索引表的算法就是依据一定的判断依据,所做出的一张表,然后根据魔鬼要细化的点的八个邻域的情况查询,若表中元素是1,若表中元素是1,则删除该点(改为背景),若是0则保留。因为一个像素的8个邻域共有256中可能情况,因此,索引表的大小一般为256。

///// <summary>

/// 该函数用于对图像进行细化运算。要求目标图像为灰度图像

/// </summary>

/// <param name="dgGrayValue"></param>

public void ThiningPic(Bitmap bmpobj,int dgGrayValue)

{

int lWidth = bmpobjWidth;

int lHeight = bmpobjHeight;

// Bitmap newBmp = new Bitmap(lWidth, lHeight);

bool bModified; //脏标记

int i, j, n, m; //循环变量

Color pixel; //像素颜色值

//四个条件

bool bCondition1;

bool bCondition2;

bool bCondition3;

bool bCondition4;

int nCount; //计数器

int[,] neighbour = new int[5, 5]; //5×5相邻区域像素值

bModified = true;

while (bModified)

{

bModified = false;

//由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素

for (j = 2; j < lHeight - 2; j++)

{

for (i = 2; i < lWidth - 2; i++)

{

bCondition1 = false;

bCondition2 = false;

bCondition3 = false;

bCondition4 = false;

if (bmpobjGetPixel(i, j)R > dgGrayValue)

{

if(bmpobjGetPixel(i, j)R<255)

bmpobjSetPixel(i, j, ColorBlack);

continue;

}

//获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表

for (m = 0; m < 5; m++)

{

for (n = 0; n < 5; n++)

{

neighbour[m, n] = bmpobjGetPixel(i + m - 2, j + n - 2)R < dgGrayValue 1 : 0;

}

}

//逐个判断条件。

//判断2<=NZ(P1)<=6

nCount = neighbour[1, 1] + neighbour[1, 2] + neighbour[1, 3]

+ neighbour[2, 1] + neighbour[2, 3] +

+neighbour[3, 1] + neighbour[3, 2] + neighbour[3, 3];

if (nCount >= 2 && nCount <= 6)

{

bCondition1 = true;

}

//判断Z0(P1)=1

nCount = 0;

if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1)

nCount++;

if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1)

nCount++;

if (neighbour[2, 1] == 0 && neighbour[3, 1] == 1)

nCount++;

if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1)

nCount++;

if (neighbour[3, 2] == 0 && neighbour[3, 3] == 1)

nCount++;

if (neighbour[3, 3] == 0 && neighbour[2, 3] == 1)

nCount++;

if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1)

nCount++;

if (neighbour[1, 3] == 0 && neighbour[1, 2] == 1)

nCount++;

if (nCount == 1)

bCondition2 = true;

//判断P2P4P8=0 or Z0(p2)!=1

if (neighbour[1, 2] neighbour[2, 1] neighbour[2, 3] == 0)

{

bCondition3 = true;

}

else

{

nCount = 0;

if (neighbour[0, 2] == 0 && neighbour[0, 1] == 1)

nCount++;

if (neighbour[0, 1] == 0 && neighbour[1, 1] == 1)

nCount++;

if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1)

nCount++;

if (neighbour[2, 1] == 0 && neighbour[2, 2] == 1)

nCount++;

if (neighbour[2, 2] == 0 && neighbour[2, 3] == 1)

nCount++;

if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1)

nCount++;

if (neighbour[1, 3] == 0 && neighbour[0, 3] == 1)

nCount++;

if (neighbour[0, 3] == 0 && neighbour[0, 2] == 1)

nCount++;

if (nCount != 1)

bCondition3 = true;

}

//判断P2P4P6=0 or Z0(p4)!=1

if (neighbour[1, 2] neighbour[2, 1] neighbour[3, 2] == 0)

{

bCondition4 = true;

}

else

{

nCount = 0;

if (neighbour[1, 1] == 0 && neighbour[1, 0] == 1)

nCount++;

if (neighbour[1, 0] == 0 && neighbour[2, 0] == 1)

nCount++;

if (neighbour[2, 0] == 0 && neighbour[3, 0] == 1)

nCount++;

if (neighbour[3, 0] == 0 && neighbour[3, 1] == 1)

nCount++;

if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1)

nCount++;

if (neighbour[3, 2] == 0 && neighbour[2, 2] == 1)

nCount++;

if (neighbour[2, 2] == 0 && neighbour[1, 2] == 1)

nCount++;

if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1)

nCount++;

if (nCount != 1)

bCondition4 = true;

}

if (bCondition1 && bCondition2 && bCondition3 && bCondition4)

{

bmpobjSetPixel(i, j, ColorWhite);

bModified = true;

}

else

{

bmpobjSetPixel(i, j, ColorBlack);

}

}

}

}

// 复制细化后的图像

// bmpobj = newBmp;

}

以上就是关于图像细化方法全部的内容,包括:图像细化方法、求 c# Hilditch细化算法、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9778676.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存