本文主要实现了改进Zhang Suen细化算法的C#实现,相关论文 :“牟少敏,杜海洋,苏平,查绪恒,陈光艺.一种改进的快速并行细化算法[J].微电子学与计算机,2013,(第1期)” 。这篇论文中关于Zhang Suen细化算法的描述,貌似存在问题。本文的算法中的意思是两次标记的点迭代后同时删除。而zhang快速算法,是分为两步删除边界点的。第一步迭代之后,已经做标记的点就需要删除了。如果两步可以放在一起删除的话,为什么不在一次迭代中将几个条件一起判断呢

一:Zhang-Suen细化算法介绍

Zhang-Suen细化算法通常是一个迭代算法,整个迭代过程分为两步:

Step One:循环所有前景像素点,对符合如下条件的像素点标记为删除:

1.      2 <= N(p1) <=6

2.      S(P1) = 1

3.      P2 * P4 * P6 = 0

4.      P4 * P6 * P8 = 0

其中N(p1)表示跟P1相邻的8个像素点中,为前景像素点的个数

S(P1)表示从P2 ~ P9 ~ P2像素中出现0~1的累计次数,其中0表示背景,1表示前景

完整的P1 ~P9的像素位置与举例如下:

其中 N(p1) = 4, S(P1) = 3, P2*P4*P6=0*0*0=0, P4*P6*P8=0*0*1=0, 不符合条件,无需标记为删除。

Step Two:跟Step One很类似,条件1、2完全一致,只是条件3、4稍微不同,满足如下条件的像素P1则标记为删除,条件如下:

1.      2 <= N(p1) <=6

2.      S(P1) = 1

3.      P2 * P4 * P8 = 0

4.      P2 * P6 * P8 = 0

循环上述两步骤,直到两步中都没有像素被标记为删除为止,输出的结果即为二值图像细化后的骨架。

二:代码实现步骤

        #region 改进 Zhang-Suen algorithmpublic Bitmap zhang_thinimage_improve(Bitmap bmp){int imgWidth = bmp.Width;int imgHeight = bmp.Height;byte[,] BinaryArray = new byte[imgHeight, imgWidth];int depth = Bitmap.GetPixelFormatSize(bmp.PixelFormat);if (depth != 1)//判断位深度
            {int threshold = 0;BinaryArray = ToBinaryArray(bmp, out threshold);}else{BinaryArray = BinaryBitmapToBinaryArray(bmp);}int[] Zhangmude = new int[9];//int deletecount = 0;List<Point> deletelist = new List<Point>();while (true){for (int y = 1; y < imgHeight-1; y++){for (int x = 1; x < imgWidth-2; x++){if (BinaryArray[y, x] == 0){Zhangmude[0] = 1;if (BinaryArray[y - 1, x] == 0) Zhangmude[1] = 1;else Zhangmude[1] = 0;if (BinaryArray[y - 1, x + 1] == 0) Zhangmude[2] = 1;else Zhangmude[2] = 0;if (BinaryArray[y, x + 1] == 0) Zhangmude[3] = 1;else Zhangmude[3] = 0;if (BinaryArray[y + 1, x + 1] == 0) Zhangmude[4] = 1;else Zhangmude[4] = 0;if (BinaryArray[y + 1, x] == 0) Zhangmude[5] = 1;else Zhangmude[5] = 0;if (BinaryArray[y + 1, x - 1] == 0) Zhangmude[6] = 1;else Zhangmude[6] = 0;if (BinaryArray[y, x - 1] == 0) Zhangmude[7] = 1;else Zhangmude[7] = 0;if (BinaryArray[y - 1, x - 1] == 0) 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++;//计算bpint 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[5] * Zhangmude[7] == 0)){deletelist.Add(new Point(y, x));}}}}}}if (deletelist.Count() == 0) break;foreach (var deleteItem in deletelist){BinaryArray[deleteItem.X, deleteItem.Y] = 255;}deletelist.Clear();for (int y = 1; y < imgHeight-1; y++){for (int x = 1; x < imgWidth-1; x++){if (BinaryArray[y, x] == 0){Zhangmude[0] = 1;if (BinaryArray[y - 1, x] == 0) Zhangmude[1] = 1;else Zhangmude[1] = 0;if (BinaryArray[y - 1, x + 1] == 0) Zhangmude[2] = 1;else Zhangmude[2] = 0;if (BinaryArray[y, x + 1] == 0) Zhangmude[3] = 1;else Zhangmude[3] = 0;if (BinaryArray[y + 1, x + 1] == 0) Zhangmude[4] = 1;else Zhangmude[4] = 0;if (BinaryArray[y + 1, x] == 0) Zhangmude[5] = 1;else Zhangmude[5] = 0;if (BinaryArray[y + 1, x - 1] == 0) Zhangmude[6] = 1;else Zhangmude[6] = 0;if (BinaryArray[y, x - 1] == 0) Zhangmude[7] = 1;else Zhangmude[7] = 0;if (BinaryArray[y - 1, x - 1] == 0) 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++;//计算bpint 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[7] == 0) && (Zhangmude[1] * Zhangmude[5] * Zhangmude[7] == 0)){deletelist.Add(new Point(y, x));}}}}}}if (deletelist.Count() == 0) break;foreach (var deleteItem in deletelist){BinaryArray[deleteItem.X, deleteItem.Y] = 255;}deletelist.Clear();}Bitmap dstBmp = BinaryArrayToBinaryBitmap(BinaryArray);return dstBmp;}#endregion

还有一个问题需要注意,找到要删除的点之后不能立即删除,而是把找到的点做标记,等第一步全部遍历完之后才删除标记的点。同样第二步也是这样。

下面是实验结果:

  

本文借鉴了两篇博客,下面是原文地址:

https://blog.csdn.net/u011941438/article/details/54628836

https://blog.csdn.net/jia20003/article/details/52142992

转载于:https://www.cnblogs.com/dearzhoubi/p/10173015.html

改进Zhang Suen细化算法的C#实现相关推荐

  1. C#:实现Zhang Suen细化算法(附完整源码)

    C#:实现Zhang Suen细化算法 #region xqpublic Bitmap zhang_thinimage_improve(Bitmap bmp){int imgWidth = bmp.W ...

  2. 图像处理之Zhang Suen细化算法

    在二值图像处理特别是OCR识别与匹配中,都要通过对字符进行细化以便获得图像的骨架,通过zhang-suen细化算法获得图像,作为图像的特征之一,常用来作为识别或者模式匹配. 一:算法介绍 Zhang- ...

  3. zhang 快速并行细化方法_一种改进的Zhang并行图像细化算法的制作方法

    本发明涉及图像处理技术,具体涉及一种改进的Zhang并行图像细化算法. 背景技术: 图像细化是将图像的线条从多像素宽度减少到单位像素宽度,简称骨架化.细化效果的好坏直接影响后期图像处理的效果.对于二值 ...

  4. 改进的脱机手写体汉字细化算法

    摘要:基础数据来源于23名同学手写的100个汉字,共计2300个,然后对这组数据进行二值化,去噪,分割,归一化后所得数据. 作者:刘亚宁,2010年9月10日 在进行细化之前首先以说明为什么要将手写体 ...

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

    本文主要实现实现了和讲解图像细化算法,引用论文 "牟少敏,杜海洋,苏平,查绪恒,陈光艺.一种改进的快速并行细化算法[J].微电子学与计算机,2013,(第1期)" ,免费下载地址点 ...

  6. 并行Zhang细化算法FPA算法

    并行Zhang细化算法 和 FPA算法 ,的规则好像完全一样. //  p9 p2 p3   //  p8 p1 p4   //  p7 p6 p5 前景点为1,背景点为0 条件1:p1为前景点 条件 ...

  7. OpenCV学习(13) 细化算法(1)(转)

    1.转载链接:http://www.cnblogs.com/mikewolf2002/p/3321732.html 程序编码参考经典的细化或者骨架算法文章: T. Y. Zhang and C. Y. ...

  8. OpenCV学习(14) 细化算法(2)

    前面一篇教程中,我们实现了Zhang的快速并行细化算法,从算法原理上,我们可以知道,算法是基于像素8邻域的形状来决定是否删除当前像素.还有很多与此算法相似的细化算法,只是判断的条件不一样.在综述文章, ...

  9. Zhang-Suen细化算法讲解及实现

    算法流程 首先要反转原图像,因为算法之后所有的操作都将0作为前景,将1作为背景. 中心像素x_1(x,y)的8-近邻定义如下所示: 考虑以下两个步骤 步骤1:执行光栅扫描并标记满足以下5个条件的所有像 ...

最新文章

  1. 只有20%的iOS程序员能看懂:详解intrinsicContentSize 及 约束优先级/content Hugging/content Compression Resistance
  2. Science:纽约西奈山医学院房刚组定量分析真核生物DNA 6mA解析细菌污染的影响...
  3. 从源码分析DEARGUI之add_drawing
  4. MySQL流程控制的使用
  5. 服务间调用要通过网关吗_Asp.Net Boilerplate微服务实战(二)架构解析
  6. Microsoft CryptoAPI加密技术(一)
  7. jsp的九大内置对象和四大作用域
  8. Android Studio添加aar
  9. 【机器视觉】 reset_fuzzy_measure算子
  10. 自动化用户特定实体的访问控制
  11. Python筛选Excel文件中超过一定年龄的人员信息
  12. JS获取鼠标的坐标和滚动条的位置
  13. 程序员计算器 android6,程序员计算器
  14. 远程过程调用(RPC)详解
  15. 认识电路板上的电子元件
  16. 计算机如何快速切换窗口,如何快速切换电脑页面
  17. EXCEL-数据透视表、日数据整理成月数据
  18. 区块链的隐私保护问题
  19. python直方图教程_Matplotlib绘制直方图
  20. DNS 缓存查看以及清除(转载)

热门文章

  1. 怎样设置计算机默认字体及语言,电脑中默认输入法如何设置 Win7系统设置默认输入法技巧...
  2. node-sass报错
  3. Kali metasploit 更新以及问题 Unable to find a spec satisfying metasploit-framework (>= 0) in the set.
  4. 谈谈如何设计秒杀服务
  5. unity换装骨骼、蒙皮、动作之美
  6. 时之歌 服务器维护,时之歌抽卡卡住了怎么办 时之歌手游招募吞卡解决方法
  7. 用过滤器防sql注入
  8. 算法笔记.胡凡 第四章 算法初步
  9. 读薄《高性能MySql》(三)索引优化
  10. ubuntu 16.04 通过wine安装Kindle for pc 中文无乱码