【发布时间】:2013-09-26 00:48:25
【问题描述】:
我正在研究一种 OCR 算法,该算法给出了一个包含一些数字的图像。我希望它能够简单地检测每个图像,并将其与其他图像分开。
它适用于 0-9 的所有数字,除了数字 4,这给我带来了很多麻烦。
这是我的源图片:
以下是一些数字的解析结果:
如您所见,它们都被完美解析。唯一给我带来麻烦的是 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 中的最后一个缺陷?
【问题讨论】:
-
从您发布的源图片中可以看出,另一种方法是识别数字之间的“空白”空间;然后修剪每个分段数字以获得“最小”数字矩形。空格是那些不包含任何前景像素的“像素列”。这种方法适用于您的情况吗?
-
如果你看到最左边的边缘有前景像素,你可以向后移动几个像素
-
@ratchetfreak 不会让它继续向右直到找到图像的最右边而不是他需要的左边吗?
-
您还可以更改条件以检查向下或像素是否为命中。如果两者都不是前景,这只是一个错过。向左和 向下移动可确保您找不到任何角度超过 45 度的东西。如果你改变字体,那可能是一个更大的问题。
-
@Geobits 叮叮……这似乎是正确的答案!
标签: java algorithm screen-scraping ocr