将带有 OpenCV 边界框的图像传递给 tesseract OCR
Passing image with OpenCV bounding boxes to tesseract OCR
我正在尝试使用 OpenCV 和 Tesseract 从图像中提取文本。我已经设法检测到文本区域并使用边界框来分隔它们。但是现在我找不到如何将边界框传递给 Tesseract。
for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
{
Rect rect = boundingRect(contours[idx]);
Mat maskROI(mask, rect);
maskROI = Scalar(0, 0, 0);
// fill the contour
drawContours(mask, contours, idx, Scalar(255, 255, 255), CV_FILLED);
// ratio of non-zero pixels in the filled region
double r = (double)countNonZero(maskROI)/(rect.width*rect.height);
if (r > .45 /* assume at least 45% of the area is filled if it contains text */
&&
(rect.height > 8 && rect.width > 8) /* constraints on region size */
/* these two conditions alone are not very robust. better to use something
like the number of significant peaks in a horizontal projection as a third condition */
)
{
rectangle(rgb, rect, Scalar(0, 255, 0), 2);
}
}
imwrite(OUTPUT_FOLDER_PATH + string("/rgb.jpg"), rgb);
return 0;
}
我使用边界框获得了非常好的结果。带边界框的图像:
然后尝试了 cv::text::OCRTesseract::run
,但似乎不起作用。
有人有想法吗?
编辑:我不得不删除大部分代码,因为我实习的公司要求我这样做。但这是我的年终项目,所以一旦我结束了这一年,我将用 github link 为整个项目编辑 post。
首先感谢miki的帮助。这就是我为解决此问题所做的工作。
裁剪每个边界框的原始图像。这将为 image.To 中的许多文本区域提供单独的图像,只需将 Mat cropedImage = small(Rect(rect));
放在 rectangle(rgb, rect, Scalar(0, 255, 0), 2);
行下方
创建 OCRTesseract 实例 class 并初始化 tesseract 引擎。为此,请添加此行 Ptr<cv::text::OCRTesseract> tess = cv::text::OCRTesseract::create(NULL,NULL,NULL,3,3);
(最好在您的 main 之前,但您可以将其放在任何地方,只要它在此代码中的 for 循环之前即可)。该参数不是强制性的,因此您可以只输入 Ptr<cv::text::OCRTesseract> tess = cv::text::OCRTesseract::create();
.
- 现在你已经有了你的引擎。您可以 运行 OCR。您可以 运行 它带有许多参数,但我将坚持使用基本参数:输入图像和输出文本。所以你现在可以在
Mat cropedImage = small(Rect(rect));
下面添加这一行 tess->run(cropedImage, output_string);
请注意,最好在将裁剪后的图像传递给 OCR 之前对其进行处理(对二值图像进行阈值处理,放大裁剪以使文本不接触边缘)
您需要 OpenCV 额外模块才能使用 cv::text::OCRTesseract::run。您可以从 here 下载相同的内容。
该页面底部的教程将告诉您如何在 linux 上安装它们,以便与您的 OpenCV 一起使用。不过据我所知,您需要在安装 OpenCV 期间构建它们。此外,这些模块仅适用于 OpenCV3。
有关 windows 说明,请查看 here。
我正在尝试使用 OpenCV 和 Tesseract 从图像中提取文本。我已经设法检测到文本区域并使用边界框来分隔它们。但是现在我找不到如何将边界框传递给 Tesseract。
for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
{
Rect rect = boundingRect(contours[idx]);
Mat maskROI(mask, rect);
maskROI = Scalar(0, 0, 0);
// fill the contour
drawContours(mask, contours, idx, Scalar(255, 255, 255), CV_FILLED);
// ratio of non-zero pixels in the filled region
double r = (double)countNonZero(maskROI)/(rect.width*rect.height);
if (r > .45 /* assume at least 45% of the area is filled if it contains text */
&&
(rect.height > 8 && rect.width > 8) /* constraints on region size */
/* these two conditions alone are not very robust. better to use something
like the number of significant peaks in a horizontal projection as a third condition */
)
{
rectangle(rgb, rect, Scalar(0, 255, 0), 2);
}
}
imwrite(OUTPUT_FOLDER_PATH + string("/rgb.jpg"), rgb);
return 0;
}
我使用边界框获得了非常好的结果。带边界框的图像:
然后尝试了 cv::text::OCRTesseract::run
,但似乎不起作用。
有人有想法吗?
编辑:我不得不删除大部分代码,因为我实习的公司要求我这样做。但这是我的年终项目,所以一旦我结束了这一年,我将用 github link 为整个项目编辑 post。
首先感谢miki的帮助。这就是我为解决此问题所做的工作。
裁剪每个边界框的原始图像。这将为 image.To 中的许多文本区域提供单独的图像,只需将
Mat cropedImage = small(Rect(rect));
放在rectangle(rgb, rect, Scalar(0, 255, 0), 2);
行下方
创建 OCRTesseract 实例 class 并初始化 tesseract 引擎。为此,请添加此行
Ptr<cv::text::OCRTesseract> tess = cv::text::OCRTesseract::create(NULL,NULL,NULL,3,3);
(最好在您的 main 之前,但您可以将其放在任何地方,只要它在此代码中的 for 循环之前即可)。该参数不是强制性的,因此您可以只输入Ptr<cv::text::OCRTesseract> tess = cv::text::OCRTesseract::create();
.- 现在你已经有了你的引擎。您可以 运行 OCR。您可以 运行 它带有许多参数,但我将坚持使用基本参数:输入图像和输出文本。所以你现在可以在
Mat cropedImage = small(Rect(rect));
下面添加这一行
tess->run(cropedImage, output_string);
- 现在你已经有了你的引擎。您可以 运行 OCR。您可以 运行 它带有许多参数,但我将坚持使用基本参数:输入图像和输出文本。所以你现在可以在
请注意,最好在将裁剪后的图像传递给 OCR 之前对其进行处理(对二值图像进行阈值处理,放大裁剪以使文本不接触边缘)
您需要 OpenCV 额外模块才能使用 cv::text::OCRTesseract::run。您可以从 here 下载相同的内容。
该页面底部的教程将告诉您如何在 linux 上安装它们,以便与您的 OpenCV 一起使用。不过据我所知,您需要在安装 OpenCV 期间构建它们。此外,这些模块仅适用于 OpenCV3。
有关 windows 说明,请查看 here。