改进zhang方法图像细化(单像素)
来源:互联网 发布:淘宝开店一件代发 编辑:程序博客网 时间:2024/06/07 14:02
本文主要实现实现了和讲解图像细化算法,引用论文 “牟少敏,杜海洋,苏平,查绪恒,陈光艺.一种改进的快速并行细化算法[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++; //计算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[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方法图像细化(单像素)
- 图像处理之Zhang Suen细化算法
- 图像处理之Zhang Suen细化算法
- Win8 Metro(C#)数字图像处理--2.49Zhang二值图像细化算法
- 图像的细化(源程序)
- 图像细化
- 图像细化
- 图像细化
- 图像细化
- 图像细化
- 图像细化
- 细化处理(二值图像)Hilditch细化算法
- 并行Zhang细化算法FPA算法
- 图像的细化(骨架抽取)
- 获取图像像素方法汇总
- 获取图像像素方法汇总
- 定位图像中像素坐标的方法(matlab)
- opencv访问(Mat)图像的像素方法汇总
- 2017美国数学建模ICM D题翻译 在机场安检站优化乘客吞吐量
- zynq中各种GPIO方式的区别
- CoreOS系统组件介绍
- 漫谈程序员(二十)炉石传说罕见数据库事故!丢失30%数据,疑似误操作?
- 2017美国数学建模MCM E题(环境) 翻译 需要可持续城市!
- 改进zhang方法图像细化(单像素)
- Windows CMD命令行编程总结
- QT+SQLite 判断表中是否含有指定字段
- 2017美国数学建模ICM F题(政策)翻译 迁移到火星
- 斜率优化
- java的setter、getter 以及python的@property函数
- web服务器之mini_httpd搭建方法
- gstreamer播放器,playbin2插件使用,适合新来gstreamer
- 克服跨洋网络延迟,使用Docker Hub Mirror加速Docker官方镜像下载