Allow select ocr language in SelectionDialog.

Support this in Recognizer and Translator.
This commit is contained in:
Gres 2014-04-04 18:39:49 +04:00
parent e7e74ed20e
commit 6e85bfd7eb
5 changed files with 130 additions and 47 deletions

View File

@ -31,28 +31,28 @@ void Recognizer::applySettings()
imageScale_ = settings.value (settings_names::imageScale, imageScale_ = settings.value (settings_names::imageScale,
settings_values::imageScale).toInt (); settings_values::imageScale).toInt ();
initEngine (); initEngine (engine_);
} }
bool Recognizer::initEngine() bool Recognizer::initEngine(tesseract::TessBaseAPI *&engine)
{ {
if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ()) if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ())
{ {
emit error (tr ("Неверные параметры для OCR")); emit error (tr ("Неверные параметры для OCR"));
return false; return false;
} }
if (engine_ != NULL) if (engine != NULL)
{ {
delete engine_; delete engine;
} }
engine_ = new tesseract::TessBaseAPI(); engine = new tesseract::TessBaseAPI();
int result = engine_->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_), int result = engine->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_),
tesseract::OEM_DEFAULT); tesseract::OEM_DEFAULT);
if (result != 0) if (result != 0)
{ {
emit error (tr ("Ошибка инициализации OCR: %1").arg (result)); emit error (tr ("Ошибка инициализации OCR: %1").arg (result));
delete engine_; delete engine;
engine_ = NULL; engine = NULL;
return false; return false;
} }
return true; return true;
@ -61,9 +61,12 @@ bool Recognizer::initEngine()
void Recognizer::recognize(ProcessingItem item) void Recognizer::recognize(ProcessingItem item)
{ {
Q_ASSERT (!item.source.isNull ()); Q_ASSERT (!item.source.isNull ());
if (engine_ == NULL) bool isCustomLanguage = (!item.ocrLanguage.isEmpty () &&
item.ocrLanguage != ocrLanguage_);
tesseract::TessBaseAPI* engine = (isCustomLanguage) ? NULL : engine_;
if (engine == NULL)
{ {
if (!initEngine ()) if (!initEngine (engine))
{ {
return; return;
} }
@ -71,12 +74,18 @@ void Recognizer::recognize(ProcessingItem item)
Pix* image = prepareImage (item.source.toImage (), imageScale_); Pix* image = prepareImage (item.source.toImage (), imageScale_);
Q_ASSERT (image != NULL); Q_ASSERT (image != NULL);
engine_->SetImage (image); engine->SetImage (image);
char* outText = engine_->GetUTF8Text(); char* outText = engine->GetUTF8Text();
QString result = QString (outText).trimmed (); engine->Clear();
engine_->Clear();
cleanupImage (&image); cleanupImage (&image);
QString result = QString (outText).trimmed ();
delete [] outText;
if (isCustomLanguage)
{
delete engine;
}
if (!result.isEmpty ()) if (!result.isEmpty ())
{ {
item.recognized = result; item.recognized = result;
@ -86,5 +95,4 @@ void Recognizer::recognize(ProcessingItem item)
{ {
emit error (tr ("Текст не распознан.")); emit error (tr ("Текст не распознан."));
} }
delete [] outText;
} }

View File

@ -26,7 +26,7 @@ class Recognizer : public QObject
void applySettings (); void applySettings ();
private: private:
bool initEngine (); bool initEngine (tesseract::TessBaseAPI*&engine);
private: private:
tesseract::TessBaseAPI* engine_; tesseract::TessBaseAPI* engine_;

View File

@ -1,13 +1,16 @@
#include "SelectionDialog.h" #include "SelectionDialog.h"
#include "ui_SelectionDialog.h" #include "ui_SelectionDialog.h"
#include "LanguageHelper.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QPainter> #include <QPainter>
#include <QDebug> #include <QDebug>
#include <QMenu>
SelectionDialog::SelectionDialog(QWidget *parent) : SelectionDialog::SelectionDialog(const LanguageHelper &dictionary, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::SelectionDialog) ui(new Ui::SelectionDialog), dictionary_ (dictionary),
languageMenu_ (new QMenu)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags (Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | setWindowFlags (Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
@ -15,6 +18,8 @@ SelectionDialog::SelectionDialog(QWidget *parent) :
ui->label->setAutoFillBackground(false); ui->label->setAutoFillBackground(false);
ui->label->installEventFilter (this); ui->label->installEventFilter (this);
updateMenu ();
} }
SelectionDialog::~SelectionDialog() SelectionDialog::~SelectionDialog()
@ -22,6 +27,49 @@ SelectionDialog::~SelectionDialog()
delete ui; delete ui;
} }
void SelectionDialog::updateMenu()
{
Q_CHECK_PTR (languageMenu_);
languageMenu_->clear ();
QStringList languages = dictionary_.availableOcrLanguagesUi ();
if (languages.isEmpty ())
{
return;
}
const int max = 10;
if (languages.size () <= max)
{
foreach (const QString& language, languages)
{
languageMenu_->addAction (language);
}
}
else
{
int subIndex = max;
QMenu* subMenu = NULL;
QString prevLetter;
foreach (const QString& language, languages)
{
QString curLetter = language.left (1);
if (++subIndex >= max && prevLetter != curLetter)
{
if (subMenu != NULL)
{
subMenu->setTitle (subMenu->title () + " - " + prevLetter);
}
subMenu = languageMenu_->addMenu (curLetter);
subIndex = 0;
}
prevLetter = curLetter;
subMenu->addAction (language);
}
subMenu->setTitle (subMenu->title () + " - " + prevLetter);
}
}
bool SelectionDialog::eventFilter(QObject* object, QEvent* event) bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
{ {
if (object != ui->label) if (object != ui->label)
@ -29,41 +77,24 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
return QDialog::eventFilter (object, event); return QDialog::eventFilter (object, event);
} }
if (event->type () == QEvent::MouseButtonPress) if (event->type () == QEvent::Show)
{
startSelectPos_ = currentSelectPos_ = QPoint ();
}
else if (event->type () == QEvent::MouseButtonPress)
{ {
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event); QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
if (mouseEvent->button () == Qt::LeftButton) if ((mouseEvent->button () == Qt::LeftButton ||
mouseEvent->button () == Qt::RightButton) && startSelectPos_.isNull ())
{ {
startSelectPos_ = mouseEvent->pos (); startSelectPos_ = mouseEvent->pos ();
} }
} }
else if (event->type () == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
if (mouseEvent->button () == Qt::LeftButton)
{
if (startSelectPos_.isNull () || currentPixmap_.isNull ())
{
QDialog::eventFilter (object, event);
}
QPoint endPos = mouseEvent->pos ();
QRect selection = QRect (startSelectPos_, endPos).normalized ();
startSelectPos_ = currentSelectPos_ = QPoint ();
QPixmap selectedPixmap = currentPixmap_.copy (selection);
if (!selectedPixmap.isNull ())
{
ProcessingItem item;
item.source = selectedPixmap;
item.screenPos = selection.topLeft ();
emit selected (item);
accept ();
}
}
}
else if (event->type () == QEvent::MouseMove) else if (event->type () == QEvent::MouseMove)
{ {
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event); QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
if (mouseEvent->buttons () & Qt::LeftButton) if ((mouseEvent->buttons () & Qt::LeftButton ||
mouseEvent->buttons () & Qt::RightButton) && !startSelectPos_.isNull ())
{ {
currentSelectPos_ = mouseEvent->pos (); currentSelectPos_ = mouseEvent->pos ();
ui->label->repaint (); ui->label->repaint ();
@ -79,7 +110,44 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
painter.drawRect (selection); painter.drawRect (selection);
} }
} }
else if (event->type () == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
if (mouseEvent->button () == Qt::LeftButton ||
mouseEvent->button () == Qt::RightButton)
{
if (startSelectPos_.isNull () || currentPixmap_.isNull ())
{
return QDialog::eventFilter (object, event);
}
QPoint endPos = mouseEvent->pos ();
QRect selection = QRect (startSelectPos_, endPos).normalized ();
QPixmap selectedPixmap = currentPixmap_.copy (selection);
if (!selectedPixmap.isNull ())
{
ProcessingItem item;
item.source = selectedPixmap;
item.screenPos = selection.topLeft ();
if (mouseEvent->button () == Qt::RightButton &&
!languageMenu_->children ().isEmpty ())
{
QAction* action = languageMenu_->exec (QCursor::pos ());
if (action == NULL)
{
reject ();
return QDialog::eventFilter (object, event);
}
item.ocrLanguage = dictionary_.ocrUiToCode (action->text ());
Q_ASSERT (!item.ocrLanguage.isEmpty ());
item.sourceLanguage = dictionary_.translateForOcrCode (item.ocrLanguage);
Q_ASSERT (!item.sourceLanguage.isEmpty ());
}
emit selected (item);
accept ();
}
}
}
return QDialog::eventFilter (object, event); return QDialog::eventFilter (object, event);
} }

View File

@ -3,19 +3,21 @@
#include <QDialog> #include <QDialog>
#include <QPixmap> #include <QPixmap>
#include <QMenu>
#include "ProcessingItem.h" #include "ProcessingItem.h"
namespace Ui { namespace Ui {
class SelectionDialog; class SelectionDialog;
} }
class LanguageHelper;
class SelectionDialog : public QDialog class SelectionDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit SelectionDialog(QWidget *parent = 0); explicit SelectionDialog(const LanguageHelper& dictionary, QWidget *parent = 0);
~SelectionDialog(); ~SelectionDialog();
bool eventFilter (QObject *object, QEvent *event); bool eventFilter (QObject *object, QEvent *event);
@ -25,12 +27,15 @@ class SelectionDialog : public QDialog
public slots: public slots:
void setPixmap (QPixmap pixmap); void setPixmap (QPixmap pixmap);
void updateMenu ();
private: private:
Ui::SelectionDialog *ui; Ui::SelectionDialog *ui;
const LanguageHelper& dictionary_;
QPoint startSelectPos_; QPoint startSelectPos_;
QPoint currentSelectPos_; QPoint currentSelectPos_;
QPixmap currentPixmap_; QPixmap currentPixmap_;
QMenu* languageMenu_;
}; };
#endif // SELECTIONDIALOG_H #endif // SELECTIONDIALOG_H

View File

@ -39,12 +39,14 @@ void Translator::applySettings()
void Translator::translate(ProcessingItem item) void Translator::translate(ProcessingItem item)
{ {
Q_ASSERT (!item.recognized.isEmpty ()); Q_ASSERT (!item.recognized.isEmpty ());
if (translationLanguage_.isEmpty ()) QString sourceLanguage = item.sourceLanguage.isEmpty () ? sourceLanguage_ :
item.sourceLanguage;
if (translationLanguage_.isEmpty () || sourceLanguage.isEmpty ())
{ {
emit error (tr ("Неверные парметры для перевода.")); emit error (tr ("Неверные парметры для перевода."));
return; return;
} }
QUrl url (translateBaseUrl.arg (item.recognized, sourceLanguage_, translationLanguage_)); QUrl url (translateBaseUrl.arg (item.recognized, sourceLanguage, translationLanguage_));
QNetworkReply* reply = network_.get (QNetworkRequest (url)); QNetworkReply* reply = network_.get (QNetworkRequest (url));
items_.insert (reply, item); items_.insert (reply, item);
} }