Commit 5073d5bc authored by lluis's avatar lluis

refactors OCRTesseract interface

parent 47f61f1c
...@@ -44,24 +44,15 @@ ...@@ -44,24 +44,15 @@
#ifndef __OPENCV_TEXT_OCR_HPP__ #ifndef __OPENCV_TEXT_OCR_HPP__
#define __OPENCV_TEXT_OCR_HPP__ #define __OPENCV_TEXT_OCR_HPP__
#include "text_config.hpp"
#ifdef HAVE_TESSERACT
#include <tesseract/baseapi.h>
#include <tesseract/resultiterator.h>
#endif
#include "opencv2/core.hpp"
#include <vector> #include <vector>
#include <string> #include <string>
using namespace std;
namespace cv namespace cv
{ {
namespace text namespace text
{ {
using namespace std;
enum enum
{ {
...@@ -69,40 +60,35 @@ enum ...@@ -69,40 +60,35 @@ enum
OCR_LEVEL_TEXTLINE OCR_LEVEL_TEXTLINE
}; };
#ifdef HAVE_TESSERACT //base class BaseOCR declares a common API that would be used in a typical text recognition scenario
class CV_EXPORTS OCRTesseract class CV_EXPORTS BaseOCR
{ {
private:
tesseract::TessBaseAPI tess;
public: public:
//Default constructor virtual ~BaseOCR() {};
OCRTesseract(const char* datapath=NULL, const char* language=NULL, const char* char_whitelist=NULL, virtual void run(Mat& image, string& output_text, vector<Rect>* component_rects=NULL,
tesseract::OcrEngineMode oem=tesseract::OEM_DEFAULT, tesseract::PageSegMode psmode=tesseract::PSM_AUTO); vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL,
int component_level=0) = 0;
~OCRTesseract();
void run(Mat& image, string& output_text, vector<Rect>* component_rects=NULL,
vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL,
int component_level=0);
}; };
#else
//stub class CV_EXPORTS OCRTesseract : public BaseOCR
class CV_EXPORTS OCRTesseract
{ {
public: public:
//Default constructor virtual void run(Mat& image, string& output_text, vector<Rect>* component_rects=NULL,
OCRTesseract(const char* datapath=NULL, const char* language=NULL, const char* char_whitelist=NULL, vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL,
int oem=0, int psmode=0); int component_level=0)
{
~OCRTesseract(); CV_Assert( (image.type() == CV_8UC1) || (image.type() == CV_8UC1) );
CV_Assert( (component_level == OCR_LEVEL_TEXTLINE) || (component_level == OCR_LEVEL_WORD) );
void run(Mat& image, string& output_text, vector<Rect>* component_rects=NULL, output_text.clear();
vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL, if (component_rects != NULL)
int component_level=0); component_rects->clear();
if (component_texts != NULL)
component_texts->clear();
if (component_confidences != NULL)
component_confidences->clear();
}
static Ptr<OCRTesseract> create(const char* datapath=NULL, const char* language=NULL, const char* char_whitelist=NULL, int oem=3, int psmode=3);
}; };
#endif
} }
......
...@@ -102,7 +102,7 @@ int main(int argc, char* argv[]) ...@@ -102,7 +102,7 @@ int main(int argc, char* argv[])
/*Text Recognition (OCR)*/ /*Text Recognition (OCR)*/
double t_r = (double)getTickCount(); double t_r = (double)getTickCount();
OCRTesseract* ocr = new OCRTesseract(); Ptr<OCRTesseract> ocr = OCRTesseract::create();
cout << "TIME_OCR_INITIALIZATION = " << ((double)getTickCount() - t_r)*1000/getTickFrequency() << endl; cout << "TIME_OCR_INITIALIZATION = " << ((double)getTickCount() - t_r)*1000/getTickFrequency() << endl;
string output; string output;
......
...@@ -54,12 +54,12 @@ private: ...@@ -54,12 +54,12 @@ private:
vector< vector<Rect> > &boxes; vector< vector<Rect> > &boxes;
vector< vector<string> > &words; vector< vector<string> > &words;
vector< vector<float> > &confidences; vector< vector<float> > &confidences;
vector< OCRTesseract* > &ocrs; vector< Ptr<OCRTesseract> > &ocrs;
public: public:
Parallel_OCR(vector<Mat> &_detections, vector<string> &_outputs, vector< vector<Rect> > &_boxes, Parallel_OCR(vector<Mat> &_detections, vector<string> &_outputs, vector< vector<Rect> > &_boxes,
vector< vector<string> > &_words, vector< vector<float> > &_confidences, vector< vector<string> > &_words, vector< vector<float> > &_confidences,
vector< OCRTesseract* > &_ocrs) vector< Ptr<OCRTesseract> > &_ocrs)
: detections(_detections), outputs(_outputs), boxes(_boxes), words(_words), : detections(_detections), outputs(_outputs), boxes(_boxes), words(_words),
confidences(_confidences), ocrs(_ocrs) confidences(_confidences), ocrs(_ocrs)
{} {}
...@@ -120,11 +120,10 @@ int main(int argc, char* argv[]) ...@@ -120,11 +120,10 @@ int main(int argc, char* argv[])
//Initialize OCR engine (we initialize 10 instances in order to work several recognitions in parallel) //Initialize OCR engine (we initialize 10 instances in order to work several recognitions in parallel)
int num_ocrs = 10; int num_ocrs = 10;
vector<OCRTesseract*> ocrs; vector< Ptr<OCRTesseract> > ocrs;
for (int o=0; o<num_ocrs; o++) for (int o=0; o<num_ocrs; o++)
{ {
OCRTesseract* ocr = new OCRTesseract(); ocrs.push_back(OCRTesseract::create());
ocrs.push_back(ocr);
} }
//cout << "TIME_OCR_INITIALIZATION_ALT = "<< ((double)getTickCount() - t_r)*1000/getTickFrequency() << endl; //cout << "TIME_OCR_INITIALIZATION_ALT = "<< ((double)getTickCount() - t_r)*1000/getTickFrequency() << endl;
......
...@@ -47,25 +47,32 @@ ...@@ -47,25 +47,32 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <queue> #include <queue>
using namespace std;
namespace cv namespace cv
{ {
namespace text namespace text
{ {
using namespace std;
#ifdef HAVE_TESSERACT class OCRTesseractImpl : public OCRTesseract
//Default constructor
OCRTesseract::OCRTesseract(const char* datapath, const char* language, const char* char_whitelist, tesseract::OcrEngineMode oemode, tesseract::PageSegMode psmode)
{ {
private:
#ifdef HAVE_TESSERACT
tesseract::TessBaseAPI tess;
#endif
public:
//Default constructor
OCRTesseractImpl(const char* datapath, const char* language, const char* char_whitelist, int oemode, int psmode)
{
#ifdef HAVE_TESSERACT
const char *lang = "eng"; const char *lang = "eng";
if (language != NULL) if (language != NULL)
lang = language; lang = language;
if (tess.Init(datapath, lang, oemode)) if (tess.Init(datapath, lang, (tesseract::OcrEngineMode)oemode))
{ {
cout << "OCRTesseract: Could not initialize tesseract." << endl; cout << "OCRTesseract: Could not initialize tesseract." << endl;
throw 1; throw 1;
...@@ -73,7 +80,7 @@ OCRTesseract::OCRTesseract(const char* datapath, const char* language, const cha ...@@ -73,7 +80,7 @@ OCRTesseract::OCRTesseract(const char* datapath, const char* language, const cha
//cout << "OCRTesseract: tesseract version " << tess.Version() << endl; //cout << "OCRTesseract: tesseract version " << tess.Version() << endl;
tesseract::PageSegMode pagesegmode = psmode; tesseract::PageSegMode pagesegmode = (tesseract::PageSegMode)psmode;
tess.SetPageSegMode(pagesegmode); tess.SetPageSegMode(pagesegmode);
if(char_whitelist != NULL) if(char_whitelist != NULL)
...@@ -82,18 +89,33 @@ OCRTesseract::OCRTesseract(const char* datapath, const char* language, const cha ...@@ -82,18 +89,33 @@ OCRTesseract::OCRTesseract(const char* datapath, const char* language, const cha
tess.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); tess.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
tess.SetVariable("save_best_choices", "T"); tess.SetVariable("save_best_choices", "T");
#else
cout << "OCRTesseract("<<oemode<<psmode<<"): Tesseract not found." << endl;
if (datapath != NULL)
cout << " " << datapath << endl;
if (language != NULL)
cout << " " << language << endl;
if (char_whitelist != NULL)
cout << " " << char_whitelist << endl;
#endif
}
} ~OCRTesseractImpl()
{
#ifdef HAVE_TESSERACT
tess.End();
#endif
}
OCRTesseract::~OCRTesseract() void run(Mat& image, string& output, vector<Rect>* component_rects=NULL,
{ vector<string>* component_texts=NULL, vector<float>* component_confidences=NULL,
tess.End(); int component_level=0)
} {
CV_Assert( (image.type() == CV_8UC1) || (image.type() == CV_8UC1) );
#ifdef HAVE_TESSERACT
void OCRTesseract::run(Mat& image, string& output, vector<Rect>* component_rects,
vector<string>* component_texts, vector<float>* component_confidences, int component_level)
{
CV_Assert( (image.type() == CV_8UC1) || (image.type() == CV_8UC1) );
if (component_texts != 0) if (component_texts != 0)
component_texts->clear(); component_texts->clear();
if (component_rects != 0) if (component_rects != 0)
...@@ -135,30 +157,8 @@ void OCRTesseract::run(Mat& image, string& output, vector<Rect>* component_rects ...@@ -135,30 +157,8 @@ void OCRTesseract::run(Mat& image, string& output, vector<Rect>* component_rects
} }
tess.Clear(); tess.Clear();
}
#else
//Stub constructor
OCRTesseract::OCRTesseract(const char* datapath, const char* language, const char* char_whitelist, int oemode, int psmode)
{
cout << "OCRTesseract("<<oemode<<psmode<<"): Tesseract not found." << endl;
if (datapath != NULL)
cout << " " << datapath << endl;
if (language != NULL)
cout << " " << language << endl;
if (char_whitelist != NULL)
cout << " " << char_whitelist << endl;
}
//Stub destructor #else
OCRTesseract::~OCRTesseract()
{
}
//Stub method, does nothing
void OCRTesseract::run(Mat& image, string& output, vector<Rect>* component_rects,
vector<string>* component_texts, vector<float>* component_confidences, int component_level)
{
CV_Assert( (image.type() == CV_8UC1) || (image.type() == CV_8UC1) );
cout << "OCRTesseract(" << component_level << image.type() <<"): Tesseract not found." << endl; cout << "OCRTesseract(" << component_level << image.type() <<"): Tesseract not found." << endl;
output.clear(); output.clear();
...@@ -168,9 +168,16 @@ void OCRTesseract::run(Mat& image, string& output, vector<Rect>* component_rects ...@@ -168,9 +168,16 @@ void OCRTesseract::run(Mat& image, string& output, vector<Rect>* component_rects
component_texts->clear(); component_texts->clear();
if(component_confidences) if(component_confidences)
component_confidences->clear(); component_confidences->clear();
}
#endif #endif
}
};
Ptr<OCRTesseract> OCRTesseract::create(const char* datapath, const char* language, const char* char_whitelist, int oem, int psmode)
{
return makePtr<OCRTesseractImpl>(datapath,language,char_whitelist,oem,psmode);
}
} }
......
...@@ -45,4 +45,11 @@ ...@@ -45,4 +45,11 @@
#include "opencv2/text.hpp" #include "opencv2/text.hpp"
#include "text_config.hpp"
#ifdef HAVE_TESSERACT
#include <tesseract/baseapi.h>
#include <tesseract/resultiterator.h>
#endif
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment