我遇到了一个有关从图像生成浮点坐标的问题。
原始问题如下: 输入图像是手写文本。由此我想生成一组构成单个字符的点(只是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之外)绘制带点的路径。 这可能吗?
答案 0 :(得分:1)
您应该考虑实施自己的连接组件标签。这个概念非常简单:您扫描第一行并为每个水平连接的像素带分配唯一的标签。您基本上检查每个像素是否连接到其左邻居并为其指定邻居的标签或新标签。在第二行中,您也会这样做,但您也会检查其上方的像素。有时您需要标签合并:在前一行中连接的两个条带在当前行中连接。处理此问题的方法是保留标签等效列表或使用指向标签的指针(这样您就可以轻松地对对象进行完整的标签更改)。
这基本上就是findContours所做的,但如果你自己实现它,你就可以自由地进行8连通性甚至桥接单像素或两像素间隙。这样你就可以获得“几乎连接的组件标签”。您的示例图片中的“w”似乎需要这个。
一旦您以这种方式标记图像,您就可以将单个标签的所有像素推送到矢量,并按照这样的顺序排序。找到左上角的像素,将其推送到新的矢量并从原始矢量中删除它。现在找到最接近它的原始矢量中的像素,将其推送到新矢量并从原始矢量中删除。继续,直到所有像素都已传输完毕。
这种方式不会很快,但它应该是一个开始。