java-如何使用光学字符识别来解析数字4
作者:互联网
我正在研究一种OCR算法,该算法给出的图像包含一些数字.我希望它仅检测每个图像,并将其与其他图像分开.
除数字4之外,它对于所有0-9的数字都有效,这给我带来了很多麻烦.
这是我的原始图片:
这是一些解析它的结果:
如您所见,它们都被完美地解析了.给我带来麻烦的唯一事情是4.这是数字4的样子:
我遇到的问题是检测4的最左角,以便包括整个数字.
这是我的算法尝试检测每个字符的左边界时的遍历方式(蓝色点表示该算法采用的路径):
如果在另一个选项卡中打开图像并放大,则可能会更好地看到其效果.
如您所见,它向下和向左移动,直到两次遇到背景.当这样做时,就意味着已经达到图像的最左边界.对于4以外的所有其他图像,它都能正常工作,您可以看到它两次遇到背景并停止,但是如果它继续向下再向下移动两个像素,则它将遇到4个像素中的更多个,并且会发现其真正的最边缘.
我不确定如何做到这一点,而不会破坏其他数字.如果有帮助,这是我的实际代码:
int misses = 0;
int maxMisses = 2;
while (y < image.getHeight() && x >= 0 )
{
markPixel(x, y);
color = image.getRGB(x, y);
if (! reader.isForeground(color))
misses++;
if (misses < maxMisses)
{
y++;
x--;
continue;
}
x++;
break;
}
if (x < 0)
x = 0;
return x;
编辑:通过仅遍历整个图像而不是停在遇到2个背景像素上,在遇到前景像素时存储x坐标(每一步),然后按升序对匹配进行排序并返回他们的最低结果.它工作得更好.新的4张图片:
它还不完美.另外,9看起来更小:
算法遍历的新路径:
更新的代码:
ArrayList<Integer> matches = new ArrayList<>();
int yB = y;
for (int i = 1; i <= 2; i++)
{
y = yB;
while (y < image.getHeight() && x >= 0 )
{
markPixel(x, y);
color = image.getRGB(x, y);
if ( reader.isForeground(color))
matches.add(x);
y++;
}
x--;
}
Collections.sort(matches);
return matches.get(0);
任何人都对将最后一个缺陷剔除出4个有任何想法吗?
解决方法:
根据我的评论改编而成,这似乎是一种对发布的算法进行最小程度修改的方法:
检查下一个像素时,不要左右移动,而要独立检查它们.如果lefter(?)和较低像素都是未命中,那只会是一个未命中.这将有助于处理45度以上的任何角度,如果更改字体等,可能会遇到这种情况.
然而,
如果您愿意更改算法,那么我认为其他答案最终可能会更可靠.
>从杜兰达(Durandal)的答案来看:绕着数字走一圈,追踪最小x / y和最大x / y.要获得左下角,假设原点在左上角,则为min x,max y.我看到您遇到的唯一问题是岛(i,j)或极斜体字体,因为这些字符可能在x方向上重叠.
>从user2399923的评论开始:查找空列以划分字符也很好.它不会受到孤岛的影响,但是会受到上述极端斜体情况的影响,因为在这种情况下可能没有空列.
>来自blgt的答案:洪水填充方法也不错,我认为是标准.它需要适应岛屿,但不会受到斜体字的影响,除非字符实际接触到.数字中是否有“孔”(例如8)并不重要,因为您只对淹没区域的最小/最大x / y值感兴趣.根据定义,这些点都不是漏洞.
标签:ocr,screen-scraping,java,algorithm 来源: https://codeday.me/bug/20191122/2062119.html