繁体   English   中英

从点中提取图像上单词或短语区域的最佳方法,以便进一步识别?

[英]Best way to extract word or phrase region on image from point for it's further recognition?

解决方案必须是通用的(使用不同的字体和颜色)并且稳定。

输入数据是具有X,Y坐标的点,输出数据是矩形或更复杂的形状,其中包含单词或短语。

具有输入点(红色)和输出矩形(蓝色)的图像

现在,我使用带有hocr选项的整个图像的tesseract识别,然后从输出html中提取所有矩形,最后找到最接近点的reactangle。 代码如下所示。 但是由于整个图像识别效率低下。

当然,由于字体大小不同且无用的单词识别效果相同,因此可能无法识别全部图像,而只能识别部分图像,但这也不是一个明确的解决方案。

UPDATE

public class WordRecognizerTesseractHocr
{
    const string HelperFileName = "temp";

    public string NextVariant()
    {
        Bitmap.Save(HelperFileName + ".png", ImageFormat.Png);
        var startInfo = new ProcessStartInfo("tesseract.exe", HelperFileName + ".png temp hocr");
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        var process = Process.Start(startInfo);
        process.WaitForExit();

        var result = GetNearestWord(File.ReadAllText(HelperFileName + ".html"), Position);

        return result;
    }

    public string GetNearestWord(string tesseractHtml, Point position)
    {
        var xml = XDocument.Parse(tesseractHtml);

        RectsWords = new Dictionary<Rectangle, string>();

        var ocr_words = xml.Descendants("span").Where(element => element.Attribute("class").Value == "ocr_word").ToList();
        foreach (var ocr_word in ocr_words)
        {
            var strs = ocr_word.Attribute("title").Value.Split(' ');
            int left = int.Parse(strs[1]);
            int top = int.Parse(strs[2]);
            int width = int.Parse(strs[3]) - left + 1;
            int height = int.Parse(strs[4]) - top + 1;
            RectsWords.Add(new Rectangle(left, top, width, height), ocr_word.Value);
        }

        var nearestWords = RectsWords.OrderBy(rectWord => Distance(position, rectWord.Key));

        return nearestWords.Count() != 0 ? nearestWords.First().Value : string.Empty;
    }

    public static double Distance(Point pos, Rectangle rect)
    {
        if (pos.X < rect.Left)
        {
            if (pos.Y < rect.Top)
                return Math.Sqrt((rect.X - pos.X) * (rect.X - pos.X) + (rect.Top - pos.Y) * (rect.Top - pos.Y));
            else if (pos.Y < rect.Top + rect.Height)
                return rect.Left - pos.X;
            else
                return Math.Sqrt((rect.X - pos.X) * (rect.X - pos.X) + 
                    (rect.Top + rect.Height - 1 - pos.Y) * (rect.Top + rect.Height - 1 - pos.Y));
        }
        else if (pos.X < rect.Left + rect.Width)
        {
            if (pos.Y < rect.Top)
                return rect.Top - pos.Y;
            else if (pos.Y < rect.Top + rect.Height)
                return 0;
            else
                return pos.Y - (rect.Top + rect.Height - 1);
        }
        else
        {
            if (pos.Y < rect.Top)
                return Math.Sqrt((rect.X + rect.Width - 1 - pos.X) * (rect.X + rect.Width - 1 - pos.X) + 
                    (rect.Top - pos.Y) * (rect.Top - pos.Y));
            else if (pos.Y < rect.Top + rect.Height)
                return pos.X - (rect.Left + rect.Width - 1);
            else
                return Math.Sqrt((rect.X + rect.Width - 1 - pos.X) * (rect.X + rect.Width - 1 - pos.X) +
                    (rect.Top + rect.Height - 1 - pos.Y) * (rect.Top + rect.Height - 1 - pos.Y));
        }
    }

    public IDictionary<Rectangle, string> RectsWords
    {
        get;
        protected set;
    }
}

这可能有效。 它应该很快,但是很容易被噪音伤害。

首先获取文本的去歪斜图像,采用最容易使用的任何格式。

接下来,在x,y中得到您关心的点。

从y坐标开始,向上和向下查看完整的行,直到看到几个完全空的行。 这些将标记您指定点的文本行的顶部和底部。 这些是y中的矩形字的边界。

对x重复相同的操作,但要查找列以获取x中单词矩形的边界。

现在您应该有整个单词的界限,并且可以轻松地从中得到单词。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM