快速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细化算法、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)