将cv::Mat转换为tesseract
converting cv::Mat for tesseract
我使用OpenCV来提取扫描文档的子图像,并希望使用tesseract对该子图像执行OCR。
我发现我可以在tesseract中使用两种方法进行文本识别,但到目前为止,我无法找到一个有效的解决方案。
a。)如何将cv::Mat
转换为PIX*
?(PIX*是leptonica的数据类型)
根据下面的vasiles代码,这基本上是我当前的代码:
cv::Mat image = cv::imread("c:/image.png");
cv::Mat subImage = image(cv::Rect(50, 200, 300, 100));
int depth;
if(subImage.depth() == CV_8U)
depth = 8;
//other cases not considered yet
PIX* pix = pixCreateHeader(subImage.size().width, subImage.size().height, depth);
pix->data = (l_uint32*) subImage.data;
tesseract::TessBaseAPI tess;
STRING text;
if(tess.ProcessPage(pix, 0, 0, &text))
{
std::cout << text.string();
}
虽然它没有崩溃或任何东西,OCR结果仍然是错误的。它应该能识别示例图像中的一个单词,但它返回了一些不可读的字符。
方法PIX_HEADER
不存在,所以我用pixCreateHeader
,但它不以通道数作为参数。那么我如何设置频道的数量呢?
b)如何使用cv::Mat
代替TesseractRect()
Tesseract提供了另一种文本识别方法,使用以下签名:
char * TessBaseAPI::TesseractRect (
const UINT8 * imagedata,
int bytes_per_pixel,
int bytes_per_line,
int left,
int top,
int width,
int height
)
目前我正在使用下面的代码,但它也返回不可读的字符(尽管与上面的代码不同)。
char* cr = tess.TesseractRect(
subImage.data,
subImage.channels(),
subImage.channels() * subImage.size().width,
0,
0,
subImage.size().width,
subImage.size().height);
tesseract::TessBaseAPI tess;
cv::Mat sub = image(cv::Rect(50, 200, 300, 100));
tess.SetImage((uchar*)sub.data, sub.size().width, sub.size().height, sub.channels(), sub.step1());
tess.Recognize(0);
const char* out = tess.GetUTF8Text();
对于使用OpenCV/Tesseract的JavaCPP预设的任何人,这里是工作
Mat img = imread("file.jpg");
Mat gray = new Mat();
cvtColor(img, gray, CV_BGR2GRAY);
// api is a Tesseract client which is initialised
api.SetImage(gray.data().asBuffer(),gray.size().width(),gray.size().height(),gray.channels(),gray.size1())
cv::Mat image = cv::imread(argv[1]);
cv::Mat gray;
cv::cvtColor(image, gray, CV_BGR2GRAY);
PIX *pixS = pixCreate(gray.size().width, gray.size().height, 8);
for(int i=0; i<gray.rows; i++)
for(int j=0; j<gray.cols; j++)
pixSetPixel(pixS, j,i, (l_uint32) gray.at<uchar>(i,j));
首先,对subImage进行深度复制,以便将其存储在连续的内存块中:
cv::Mat subImage = image(cv::Rect(50, 200, 300, 100)).clone();
然后,用正确的参数初始化一个PIX头(我不知道怎么做)。
// ???? Put your own constructor here.
PIX* pix = new PIX_HEADER(width, height, channels, depth);
或者,手动创建:
PIX pix;
pix.width = subImage.width;
...
然后将像素数据指针设置为子图像数据指针
pix.data = subImage.data;
最后,确保在完成pix的工作之前,subImage对象没有超出作用域。
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将cv::Mat转换为tesseract