使用Tesseract做OCR时,如何让OpenCV Mat与Leptonica Pix结果质量一致?
解决OpenCV Mat与Leptonica Pix输入Tesseract识别结果不一致的问题
我一眼就看到问题出在OpenCV图像格式与Tesseract期望的格式不匹配上,这是个很常见的新手坑,咱们一步步来解决:
问题根源
- OpenCV的
imread()默认读取的是BGR格式的3通道彩色图像(Mat的type是CV_8UC3),但你调用ocr.SetImage()时指定了1作为通道数,这相当于告诉Tesseract“这是单通道灰度图”,但实际传入的是3通道BGR数据,数据解析完全混乱,自然识别结果差、置信度低。 - 而Leptonica的
pixRead()会自动正确识别图像的通道数和色彩空间(比如彩色图会以RGB格式加载),所以Tesseract能正确处理,得到正常的识别结果。
解决方案
有两种靠谱的处理方式,选哪种都能让OpenCV输入的效果和Leptonica一致:
方式1:转换为灰度图输入(推荐,OCR通常灰度图效果更稳定)
把OpenCV读取的彩色图转换成单通道灰度图,再传给Tesseract,这样通道数匹配,数据解析正确:
void opencvVariant(string titleFile) { cout << endl << "OpenCV variant (Grayscale)..." << endl; TessBaseAPI ocr; ocr.Init(NULL, "eng"); Mat image = imread(titleFile); // 转换为灰度图 Mat gray; cvtColor(image, gray, COLOR_BGR2GRAY); // 现在是单通道,参数正确 ocr.SetImage(gray.data, gray.cols, gray.rows, 1, gray.step); char* outText = ocr.GetUTF8Text(); int confidence = ocr.MeanTextConf(); cout << "Text: " << outText << endl; cout << "Confidence: " << confidence << endl; // 记得释放内存! ocr.End(); delete[] outText; }
方式2:转换为RGB格式的彩色图输入
如果需要保留彩色信息(虽然OCR大多时候不需要),要把OpenCV的BGR转换成RGB,然后指定3通道:
void opencvVariant(string titleFile) { cout << endl << "OpenCV variant (RGB)..." << endl; TessBaseAPI ocr; ocr.Init(NULL, "eng"); Mat image = imread(titleFile); // BGR转RGB Mat rgb; cvtColor(image, rgb, COLOR_BGR2RGB); // 指定3通道 ocr.SetImage(rgb.data, rgb.cols, rgb.rows, 3, rgb.step); char* outText = ocr.GetUTF8Text(); int confidence = ocr.MeanTextConf(); cout << "Text: " << outText << endl; cout << "Confidence: " << confidence << endl; // 释放资源 ocr.End(); delete[] outText; }
额外注意事项
- 记得调用
ocr.End()释放Tesseract的资源,以及delete[] outText释放识别结果的内存,避免内存泄漏。 - 你的Leptonica代码片段没写完,也要记得在最后调用
pixDestroy(&image)和ocr.End()、delete[] outText来释放资源。
这样修改后,OpenCV输入的识别结果就会和Leptonica版本完全一致了!
内容的提问来源于stack exchange,提问作者Björn Larsson
相关产品推荐
相关产品推荐

