改进zhang方法图像细化(单像素)

本文主要实现实现了和讲解图像细化算法,引用论文 “牟少敏,杜海洋,苏平,查绪恒,陈光艺.一种改进的快速并行细化算法[J].微电子学与计算机,2013,(第1期)” ,免费下载地址点击打开链接(直接在http://www.ucdrs.superlib.net/中搜索也可)。

zhang的算法是经典的细化算法,具有速度快、保持细化后 曲线的连通性和无毛刺产生等优点,但它细化后的结果不能保证曲线纹路为单一像素,细化不彻底。

先介绍几个基本概念:

1.目标点和背景点:目标点指像素值为1的点,与此对应,背景点像素值为0.

2.8邻域:如图所示,设有任意像素点 P,P的8邻点即以P为中心的 3×3 区域中除了 P 点以外的P2到P的8个点。

   

3.边界点:属于目标点,且其8领域中至少有一个为背景点。

4.端点:属于边界点,且其8领域中至少有一个为目标点。

Zhang快速并行细化算法执行过程对边界点进行如下操作:



经过细化后的图像并非是单像素的。


牟少敏,杜海洋等提出了对zhang算法的改进,以实现单像素化。

经过分析 Zhang 算法 的原理和细化后的图像 ,发现导致细化后纹路非单一像素原 因是因为部分该删除的点由于不满足 Zhang 细化算法删除条件 1.2S (P ) 一1 而被遗漏掉 ,将这些点分为三类. 如图 3~图 5 所 示




为了易于识别和计算这类点,将8领域点进行二进制编码,从P2到P9进行二进制编码,如下如所示



对所有遗漏目标点的8领域进行编码,并转为十进制,第一类点转化结果为65、5、20和80,第二类点转化结果为:13、97、22、208、67、88、52和133,第三类点转化结果为141、99、54和216。

在扫描过程中上述16种目标点不能全部删除,否则会出现断点。适当选取删除点,已达到最好的细化结果。实验发现删除以下组合中的10个点最为良好。第一类4种全部删除,编码组合为{65,5,20,80},第二类中选择4种删除,编码组合为{13,22,52,133},第三类种删除2个,编码组合为{141,54},总的删除点集合为{65,5,20,80,13,22,52,133,141,54}

改进后的算法描述如下



实现代码如下:

void zhang_thinimage_improve(Mat &srcimage)//单通道、二值化后的图像  
{  
    vector<Point> deletelist1;  
    int Zhangmude[9];  
    int nl = srcimage.rows;  
    int nc = srcimage.cols;  
    while (true)  
    {  
        for (int j = 1; j<(nl - 1); j++)  
        {  
            uchar* data_last = srcimage.ptr<uchar>(j - 1);  
            uchar* data = srcimage.ptr<uchar>(j);  
            uchar* data_next = srcimage.ptr<uchar>(j + 1);  
            for (int i = 1; i<(nc - 1); i++)  
            {  
                if (data[i] == 255)  
                {  
                    Zhangmude[0] = 1;  
                    if (data_last[i] == 255) Zhangmude[1] = 1;  
                    else  Zhangmude[1] = 0;  
                    if (data_last[i + 1] == 255) Zhangmude[2] = 1;  
                    else  Zhangmude[2] = 0;  
                    if (data[i + 1] == 255) Zhangmude[3] = 1;  
                    else  Zhangmude[3] = 0;  
                    if (data_next[i + 1] == 255) Zhangmude[4] = 1;  
                    else  Zhangmude[4] = 0;  
                    if (data_next[i] == 255) Zhangmude[5] = 1;  
                    else  Zhangmude[5] = 0;  
                    if (data_next[i - 1] == 255) Zhangmude[6] = 1;  
                    else  Zhangmude[6] = 0;  
                    if (data[i - 1] == 255) Zhangmude[7] = 1;  
                    else  Zhangmude[7] = 0;  
                    if (data_last[i - 1] == 255) Zhangmude[8] = 1;  
                    else  Zhangmude[8] = 0;  
                    int whitepointtotal = 0;  
                    for (int k = 1; k < 9; k++)  
                    {  
						//得到1的个数
                        whitepointtotal = whitepointtotal + Zhangmude[k];  
                    }  
                    if ((whitepointtotal >= 2) && (whitepointtotal <= 6))  
                    {  
						//得到01的个数
                        int ap = 0;  
                        if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;  
                        if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;  
                        if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;  
                        if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;  
                        if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;  
                        if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;  
                        if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;  
                        if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;  
			//计算bp
			int bp=0;
			bp+=Zhangmude[1];
			bp+=Zhangmude[2]<<1;
			bp+=Zhangmude[3]<<2;
			bp+=Zhangmude[4]<<3;
			bp+=Zhangmude[5]<<4;
			bp+=Zhangmude[6]<<5;
			bp+=Zhangmude[7]<<6;
			bp+=Zhangmude[8]<<7;

                        if (ap == 1||bp==65||bp==5||bp==20||bp==80||bp==13||bp==22||bp==52||bp==133||bp==141||bp==54)  
                        {  
                            if ((Zhangmude[1] * Zhangmude[7] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[5] * Zhangmude[7] == 0))  
                            {  
                                deletelist1.push_back(Point(i, j));  //满足条件,去除该点
                            }  
                        }  
                    }  
                }  
            }  
        }  
        if (deletelist1.size() == 0) break;  
        for (size_t i = 0; i < deletelist1.size(); i++)  
        {  
            Point tem;  
            tem = deletelist1[i];  
            uchar* data = srcimage.ptr<uchar>(tem.y);  
            data[tem.x] = 0;  
        }  
        deletelist1.clear();  
  
		
        for (int j = 1; j<(nl - 1); j++)  
        {  
            uchar* data_last = srcimage.ptr<uchar>(j - 1);  
            uchar* data = srcimage.ptr<uchar>(j);  
            uchar* data_next = srcimage.ptr<uchar>(j + 1);  
            for (int i = 1; i<(nc - 1); i++)  
            {  
                if (data[i] == 255)  
                {  
                    Zhangmude[0] = 1;  
                    if (data_last[i] == 255) Zhangmude[1] = 1;  
                    else  Zhangmude[1] = 0;  
                    if (data_last[i + 1] == 255) Zhangmude[2] = 1;  
                    else  Zhangmude[2] = 0;  
                    if (data[i + 1] == 255) Zhangmude[3] = 1;  
                    else  Zhangmude[3] = 0;  
                    if (data_next[i + 1] == 255) Zhangmude[4] = 1;  
                    else  Zhangmude[4] = 0;  
                    if (data_next[i] == 255) Zhangmude[5] = 1;  
                    else  Zhangmude[5] = 0;  
                    if (data_next[i - 1] == 255) Zhangmude[6] = 1;  
                    else  Zhangmude[6] = 0;  
                    if (data[i - 1] == 255) Zhangmude[7] = 1;  
                    else  Zhangmude[7] = 0;  
                    if (data_last[i - 1] == 255) Zhangmude[8] = 1;  
                    else  Zhangmude[8] = 0;  
                    int whitepointtotal = 0;  
                    for (int k = 1; k < 9; k++)  
                    {  
                        whitepointtotal = whitepointtotal + Zhangmude[k];  
                    }  
                    if ((whitepointtotal >= 2) && (whitepointtotal <= 6))  
                    {  
                        int ap = 0;  
                        if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;  
                        if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;  
                        if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;  
                        if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;  
                        if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;  
                        if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;  
                        if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;  
                        if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;  
			int bp=0;
			bp+=Zhangmude[1];
			bp+=Zhangmude[2]<<1;
			bp+=Zhangmude[3]<<2;
			bp+=Zhangmude[4]<<3;
			bp+=Zhangmude[5]<<4;
			bp+=Zhangmude[6]<<5;
			bp+=Zhangmude[7]<<6;
			bp+=Zhangmude[8]<<7;				
                        if (ap == 1||bp==65||bp==5||bp==20||bp==80||bp==13||bp==22||bp==52||bp==133||bp==141||bp==54)  
                        {  
                            if ((Zhangmude[1] * Zhangmude[3] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[1] * Zhangmude[7] == 0))  
                            {  
                                deletelist1.push_back(Point(i, j));  
                            }  
                        }  
                    }  
                }  
            }  
        }  
        if (deletelist1.size() == 0) break;  
        for (size_t i = 0; i < deletelist1.size(); i++)  
        {  
            Point tem;  
            tem = deletelist1[i];  
            uchar* data = srcimage.ptr<uchar>(tem.y);  
            data[tem.x] = 0;  
        }  
        deletelist1.clear(); 
    }  
}

zhang方法


改进方法


改进方法剔除的点


如有对论文作者造成侵权,请与我联系删除


二值图像细化是一种图像处理方法,通过对二值图像进行迭代操作,使得边缘线变得更加细长,并且不改变图像的几何形状。二值图像细化通常用于目标识别、图像分析和图像压缩等领域。 二值图像细化算法中常使用的方法有Zhang-Suen细化算法和Guo-Hall细化算法。这些算法的基本原理是通过迭代操作,将边缘线上的点逐渐消除,直到只剩下一个像素表示边缘。 Zhang-Suen细化算法是一种迭代算法,每次迭代分别对图像的奇数次和偶数次迭代进行操作。在奇数次迭代中,通过满足边缘点周围像素的条件来消除边缘点。而在偶数次迭代中,则通过满足边缘点四周像素的条件来消除边缘点。经过多次迭代操作,直到没有需要删除的边缘点为止,即得到细化后的二值图像。 Guo-Hall细化算法也是一种迭代算法,该算法通过分别对图像的四个子图像进行操作,不断消除边缘点。每次迭代操作会遍历子图像的所有像素,满足一定条件的边缘点会被删除。通过重复迭代操作,直到没有需要删除的边缘点为止,最终获得细化后的二值图像细化算法的目标是尽可能地保留图像的几何形状,同时使得边缘线更加细长。在实际应用中,合适的细化算法可以提高图像的分析和识别效果。与其他图像处理方法相比,细化算法对计算资源的需求较低,可以实现快速且准确的图像细化
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值