[英]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.