конвертирование CV :: Mat для тессеракта - PullRequest
14 голосов
/ 14 ноября 2011

Я использую 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(); 
 }   

Несмотря на то, что он не дает сбоя или что-то еще, результат распознавания по-прежнему неверен.Он должен распознавать одно слово из моего образца изображения, но вместо этого он возвращает некоторые нечитаемые символы.

Метод 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);   

Ответы [ 4 ]

15 голосов
/ 14 ноября 2011
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();
4 голосов
/ 12 мая 2017

Для тех, кто использует предустановки JavaCPP для OpenCV / Tesseract, вот что работает

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())
1 голос
/ 19 сентября 2014
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));
0 голосов
/ 14 ноября 2011

Сначала сделайте глубокую копию вашего 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;
...

Затем установите указатель данных пикселей на указатель данных subImage

pix.data = subImage.data;

Наконец, выполните командуубедитесь, что ваши subImage объекты не выходят за рамки, прежде чем вы закончите свою работу с pix.

...