4

我遇到了一个关于从图像生成浮点坐标的问题。

原问题如下:输入图像是手写文本。由此我想生成一组组成各个字符的点(只是 x,y 坐标)。

起初我使用 findContours 来生成点。由于这会找到字符的边缘,因此首先需要通过细化算法运行,因为我对字符的形状不感兴趣,只对线条或在这种情况下为点感兴趣。

输入:

输入

细化:

变薄

所以,我通过细化算法运行我的输入,一切都很好,输出看起来不错。然而,在此运行 findContours 并没有那么好,它跳过了很多东西,我最终得到了一些无法使用的东西。

第二个想法是生成边界框(使用 findContours),使用这些边界框从细化过程中抓取字符,并将所有非白色像素索引作为“点”并将它们偏移边界框位置。这会产生更糟糕的输出,并且似乎是一种不好的方法。

可怕的代码:

Mat temp = new Mat(edges, bb);
byte roi_buff[] = new byte[(int) (temp.total() * temp.channels())];
temp.get(0, 0, roi_buff);

int COLS = temp.cols();
List<Point> preArrayList = new ArrayList<Point>();

for(int i  = 0; i < roi_buff.length; i++)
{
    if(roi_buff[i] != 0)
    {
            Point tempP = bb.tl();
            tempP.x += i%COLS;
            tempP.y += i/COLS;
            preArrayList.add(tempP);
    }
}

有没有其他选择或者我忽略了什么?

更新:

我忽略了我需要订购点(像素)的事实。在上面的方法中,我只是简单地使用扫描线方法来抓取所有像素。例如,如果您查看“o”,它将首先抓住左侧的点,然后是右侧的点。我需要它们按相邻像素排序,因为我想稍后用这些点绘制路径(在 opencv 之外)。这可能吗?

4

1 回答 1

1

您应该考虑实现自己的连接组件标签。这个概念非常简单:您扫描第一行并为每个水平连接的像素条分配唯一的标签。您基本上检查每个像素是否连接到其左邻居,并为其分配该邻居的标签或新标签。在第二行中,您执行相同操作,但您还要检查其上方的像素。有时您需要标签合并:在前一行中未连接的两个条带在当前行中连接。处理这个问题的方法是保留标签等价列表或使用指向标签的指针(这样您就可以轻松地对对象进行完整的标签更改)。

这基本上是 findContours 所做的,但是如果您自己实现它,您可以自由地实现 8 连接,甚至可以弥补单像素或两像素的差距。这样您就可以获得“几乎连接的组件标签”。看起来您的示例图片中的“w”需要这个。

以这种方式标记图像后,您可以将单个标签的所有像素推送到矢量,并像这样对它们进行排序。找到左上角的像素,把它推到一个新的向量上,然后从原始向量中删除它。现在在原始向量中找到最接近它的像素,将其推送到新向量并从原始向量中擦除。继续,直到所有像素都已传输完毕。

这种方式不会很快,但应该是一个开始。

于 2013-08-20T15:05:15.083 回答