粘粘字符“花式分割”___fix broken characters
在我们的研究对象中,有的字符在某些笔画上颜色相对较浅,这样导致二值化的图像会有缺口。这样的缺口最直接的影响就是让某些loop不完整,在后续的算法中不完整的loop会被涂为背景色,于是我们就会失去一个宝贵的loop分割依据,给整个分割大计造成重大损失。因此我们必须想办法将这些缺口修补起来,我将这项工作称为fix broken characters。
那么现在问题就来了:什么样的缺口该补,什么样的缺口又不该补呢?首先大原则是我们只补那些单像素点的缺口,原因显而易见。即便是单像素,在我们的研究对象中,也有众多嗷嗷待补的缺口。
以8领域为研究对象,我们可以将待补的缺口分为三类:直线或竖线的中间点;斜线的中间点;两点中间的拐点。
首先如果我们只补第一类缺口,效果图如下。修补起来的缺口基本都是应该要补的,但有些该补的loop会被遗漏。
如果这三类都补,那么效果图如下。显然因为过于博爱,经过修补后,多出了很多不该有的loop,于是我们又多了一项工作:真假loop大作战。综合各方面因素考虑,我觉得这样种方案得不偿失,因此不考虑。
因此最终fix broken characters函数中仅补偿了第一类缺口,本函数的实现原理与《<一种改进的并行细化算法>的CSharp代码详解》类似,将每种待修补的笔画组合变换为一个数值,然后将其制表,通过查表法来判断是否需要修补字符,程序中列出了这三类缺口的数值,有兴趣的同学可以随时增减观察补偿效果,有任何疑问,欢迎讨论。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
/// <summary> /// 修补有笔画缺陷的字符 /// </summary> /// <param name="imageHeight">二值化图像的高度</param> /// <param name="imageWidth">二值化图像的宽度</param> /// <param name="BinaryArray">二值化数组</param> /// <returns>修补后的二值化数组</returns>//Byte[,] public static Byte[,] FixBrokenCharacter(int imageHeight, int imageWidth, Byte[,] BinaryArray) { /* 5 7 8 5 X 1 4 3 2 */ // 1 2 3 4 5 6 7 8 // 1 0 0 1 0 0 0 0 144 // 1 0 0 0 1 0 0 0 136 // 1 0 0 0 0 1 0 0 132 // 0 1 0 0 1 0 0 0 72 // 0 1 0 0 0 1 0 0 68 // 0 1 0 0 0 0 1 0 66 // 0 0 1 0 0 1 0 0 36 // 0 0 1 0 0 0 1 0 34 // 0 0 1 0 0 0 0 1 33 // 0 0 0 1 0 0 1 0 18 // 0 0 0 1 0 0 0 1 17 // 0 0 0 0 1 0 0 1 9 int[] templateFix = new int[] {34,136 }; //{9,17,18,33,34,36,66,68,72,132,136,144}; Byte[,] fixArray = new Byte[imageHeight, imageWidth]; int i = 0, j = 0; for(i = 0; i < imageHeight; i ++) { for (j = 0; j < imageWidth; j ++) { fixArray[i,j] = BinaryArray[i,j]; if (0 == fixArray[i, j]) { fixArray[i, j] = 1; } else { fixArray[i, j] = 0; } } } Byte point1 = 0; Byte point2 = 0; Byte point3 = 0; Byte point4 = 0; Byte point5 = 0; Byte point6 = 0; Byte point7 = 0; Byte point8 = 0; for(i = 1; i < (imageHeight - 1); i ++) { for (j = 1; j < (imageWidth - 1); j ++ ) { if (0 == fixArray[i, j]) { point1 = fixArray[i, j + 1]; point2 = fixArray[i + 1, j + 1]; point3 = fixArray[i + 1, j]; point4 = fixArray[i + 1, j - 1]; point5 = fixArray[i, j - 1]; point6 = fixArray[i - 1, j - 1]; point7 = fixArray[i - 1, j]; point8 = fixArray[i - 1, j + 1]; int nValue = (point1 << 7) + (point2 << 6) + (point3 << 5) + (point4 << 4) + (point5 << 3) + (point6 << 2) + (point7 << 1) + point8; if (templateFix.Contains(nValue)) { fixArray[i, j] = 1; } } } } for (i = 0; i < imageHeight; i++) { for (j = 0; j < imageWidth; j++) { if (0 == fixArray[i, j]) { fixArray[i, j] = 255; } else { fixArray[i, j] = 0; } } } return fixArray; } |
粘粘字符“花式分割”___fix broken characters
粘粘字符“花式分割”___loop and guideline
粘粘字符“花式分割”___guideline principle