- 1、本文档共8页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Hilditch 细化算法的C#实现
Hilditch 细化算法是经典的二值图像细化算法,然而,在网上却很难找到一个详细、正确的介绍和实现。可以找到一辆个 Hilditch 算法的C实现,但缺乏注释,代码可读性也很差。在期刊网上找到几篇论文,提及了Hilditch 算法,结果一篇说的罗哩罗嗦根本看不懂,另一篇说的说的易懂,却是错误的!拿来主义是行不通了,于是只好结合着这几个论文和代码,从头写 Hilditch 细化算法。
假设像素p的3×3邻域结构为:
Hilditch 细化算法的步骤为:
对图像从左向右从上向下迭代每个像素,是为一个迭代周期。在每个迭代周期中,对于每一个像素p,如果它同时满足6个条件,则标记它。在当前迭代周期结束时,则把所有标记的像素的值设为背景值。如果某次迭代周期中不存在标记点(即满足6个条件的像素),则算法结束。假设背景值为0,前景值为1,则:
6个条件为:
(I):p 为1,即p不是背景;
(2):x1,x3,x5,x7不全部为1(否则把p标记删除,图像空心了);
(3):x1~x8 中,至少有2个为1(若只有1个为1,则是线段的端点。若没有为1的,则为孤立点);
(4):p的8连通联结数为1;
联结数指在像素p的3*3邻域中,和p连接的图形分量的个数:
上图中,左图的4连通联结数是2,8连通联结数是1,而右图的4联通联结数和8联通联结数都是2。
4连通联结数计算公式是:
8连通联结数计算公式是:
其中,
?
至于公式怎么来的就不管了,直接用就行了。
(5)假设x3已经标记删除,那么当x3为0时,p的8联通联结数为1;
(6)假设x5已经标记删除,那么当x5为0时,p的8联通联结数为1。
======
在程序中,我使用的是这样的邻域编码:
为了方便计算联结数,以0作为前景,1作为背景。程序如下(完整程序见: \o /svn/trunk/src/Orc.SmartImage.Common/UnmanagedImage/ImageU8.cs /svn/trunk/src/Orc.SmartImage.Common/UnmanagedImage/ImageU8.cs):
/// summary /// 计算八联结的联结数,计算公式为: ///???? (p6 - p6*p7*p0) + sigma(pk - pk*p(k+1)*p(k+2)), k = {0,2,4) /// /summary /// param name=list/param /// returns/returns private unsafe Int32 DetectConnectivity(Int32* list) { ??? Int32 count = list[6] - list[6] * list[7] * list[0]; ??? count += list[0] - list[0] * list[1] * list[2]; ??? count += list[2] - list[2] * list[3] * list[4]; ??? count += list[4] - list[4] * list[5] * list[6]; ??? return count; }
private unsafe void FillNeighbors(Byte* p, Int32* list, Int32 width, Byte foreground = 255) { ??? // list 存储的是补集,即前景点为0,背景点为1,以方便联结数的计算
??? list[0] = p[1] == foreground ? 0 : 1; ??? list[1] = p[1 - width] == foreground ? 0 : 1; ??? list[2] = p[-width] == foreground ? 0 : 1; ??? list[3] = p[-1 - width] == foreground ? 0 : 1; ??? list[4] = p[-1] == foreground ? 0 : 1; ??? list[5] = p[-1 + width] == foreground ? 0 : 1; ??? list[6] = p[width] == foreground ? 0 : 1; ??? list[7] = p[1 + width] == foreground ? 0 : 1; }
/// summary /// 使用 hilditch 算法进行细化 /// /summary public unsafe void Thinning(Byte foreground
文档评论(0)