QT 、tesseract and Block thread parallel computation(分块线程并行计算)

对于多线程加速,网络博客上有很多种方法,openmp 和QtConcurrent都能够实现一定的加速,然而我使用相应的函数并没有想象中那么友好。准确来说,不止我一个遇到了这样的问题,加速效果不明显等等。还是直接写代码加速的效果明显。采用thread编写多线程,重写run函数。

  • There are many ways to speed up multiple threads on the web blog. Both OpenMP and QtConcurrent are capable of some speed up, but My use of the corresponding functions is not as friendly as I thought.To be precise, I'm not the only one who has this problem, the acceleration is not obvious, etc.Or just write code to speed up the effect is obvious.Use thread to write multithreaded, rewrite the run function.
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <qthread.h>
#include <QImage>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QProcess>
#include "ui_mainwindow.h"
#include "m_table.h"

class MyThread : public QThread
{
public:
    MyThread(M_table* table,int* isFinish,int startCell,int endCell);
    ~MyThread();
    //QString ImageName;
    int* isFinish;
    int startCell;
    int endCell;
    //QTextEdit* edit;
private:
    M_table* table;
protected:
    virtual void run();
};

#endif // MYTHREAD_H
#include "mythread.h"
#include <QTime>
#include "character_tesseract.h"     //C++调用tesseract模型
MyThread :: MyThread(M_table* table,int* isFinish,int startCell,int endCell)
{
    this->table = table;
    this->isFinish = isFinish;
    this->startCell = startCell;
    this->endCell =endCell;

}

MyThread ::~MyThread()
{

}
void MyThread::run()
{
    qDebug()<<"线程start---------------------------------------------------";
    character_tesseract character_tesseract;
    std::tuple<QString,double,bool> tesseract_data;
    QString OutText;
    double confindence_value = 0.0;
    bool isInitSuccess = false;

    for(int j = startCell; j < endCell; j++)
    {
        cv::Mat input_image = table->cells[j].img.clone();
        //cv::Mat input_image = cv::imread((page->tables[i].cells[j].cellPath).toStdString());
        tesseract_data = character_tesseract.tesseract_recognition(input_image);
        //tesseract_data = character_tesseract.tesseract_recognition(page->tables[i].cells[j].img);
       // qDebug()<<"table->cells.size()=ssssssssssssss="<<table->cells.size();
        isInitSuccess = std::get<2>(tesseract_data);
        OutText = std::get<0>(tesseract_data);
        confindence_value = std::get<1>(tesseract_data);
        if(isInitSuccess == true)
        {
            qDebug() <<j<<"-----------"<< OutText << endl;
            table->cells[j].content       = OutText;
            table->cells[j].confidence    = confindence_value;
        }
        else
        {
            //break;
            QDateTime current_date_time = QDateTime::currentDateTime();
            QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd");
            QString fileName = ".//OCR.log";
            QString str = current_date + "----->"+"tesseract初始化失败!!!"+"\r\n";
            QFile file(fileName);
            if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append))
            {
                ;
            }
            QTextStream in(&file);
            in << j <<"---"<< str << "\n";
            file.close();
        }
    }

    *this->isFinish = 1;
    this->exit(0);
}

加速效果很明显,原来不采用加速的时间为9s,采用多线程加速时间为4s。对于172个cell的识别,未采用多线程时间为37s,采用多线程时间为15s。

  • The acceleration effect is obvious. The original acceleration time is 9s, and the multi-thread acceleration time is 4s.For the identification of 172 cells, the time without multi-threading was 37s and the time with multi-threading was 15s.

no thread: 

thread:

接下来就是线程的启动调用,将待识别的图像进行分块,等分N块,开启N线程进行并行加速计算。参考我的代码:

  • Next is the startup call of the thread. The image to be recognized is partitioned into N equal blocks, and N thread is started for parallel acceleration calculation.Refer to my code:
#if 1 //C++调用tesseract模型实现识别
character_tesseract character_tesseract;
std::tuple<QString,double,bool> tesseract_data;
QString OutText;
double confindence_value = 0.0;
bool isInitSuccess = false;

#if 1 //开启线程加速
//开启线程
for(int i = 0; i < page->tables.size(); i++)
{
	 int cellNum = page->tables[i].cells.size();
	 int threadNum = 4;
	 if(threadNum > cellNum)
	 {//用1个线程
		 int  isfinish1 = 0;
		 MyThread * thread1 = new MyThread(&(page->tables[i]),&isfinish1,0, page->tables[i].cells.size());
		 thread1->start();
		 while(isfinish1 == 0)
		 {
			 QTime dieTime = QTime::currentTime().addMSecs(500);
				 while( QTime::currentTime() < dieTime )
					 QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
				 qDebug()<<"用1线程NO完成-----------------------------------------------------";
		 }
		 qDebug()<<"用1线程完成-----------------------------------------------------";
	 }
	 else
	 {
		 int  isfinish1 = 0;
		 MyThread * thread1 = new MyThread(&(page->tables[i]),&isfinish1,0,floor(page->tables[i].cells.size() *0.25) );
		 thread1->start();

		 int  isfinish2 = 0;
		 MyThread * thread2 = new MyThread(&(page->tables[i]),&isfinish2,floor(page->tables[i].cells.size() *0.25), floor(page->tables[i].cells.size() *0.5));
		 thread2->start();

		 int  isfinish3 = 0;
		 MyThread * thread3 = new MyThread(&(page->tables[i]),&isfinish3,floor(page->tables[i].cells.size() *0.5),floor(page->tables[i].cells.size() *0.75));
		 thread3->start();

		 int  isfinish4 = 0;
		 MyThread * thread4 = new MyThread(&(page->tables[i]),&isfinish4,floor(page->tables[i].cells.size() *0.75), page->tables[i].cells.size());
		 thread4->start();

		 while(isfinish1 == 0 || isfinish2 == 0 || isfinish3 == 0 || isfinish4 == 0 )
		 {
			 QTime dieTime = QTime::currentTime().addMSecs(500);
			 while( QTime::currentTime() < dieTime )
				 QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
			 qDebug()<<"线程没完成";
		 }
		 qDebug()<<"线程完成";
	 }
}
#endif
#endif

 I hope I can help you,If you have any questions, please  comment on this blog or send me a private message. I will reply in my free time.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值