使用boost线程池(多线程使用opencv处理图片)
2017-05-12 15:12
483 查看
[+]
很多时候,需要用到多线程,但是线程每一次的分配都需要消耗时间,同时线程也不是无限制的开启的(需要固定一个数量)。
如果我们既想要固定数量,又不想每次都new一个线程,我们这么做就能满足要求:
a、固定一个数量,表示最大可使用线程的个数,threadCount=8;
b、在程序开始的时候,直接new出来threadCount个线程,假如存放到thread[threadCount-1]中
c、遇到一个任务,从thread[threadCount-1]中取出来一个线程,设置他的任务为Task,并且让threadCount-1,让此线程start
d、线程中的任务结束后让,threadCount+1
上面的流程,其实就是一个线程池的原型,为了使用方便,使用了boost的一个开源工程,threadpool,下载地址为
http://threadpool.sourceforge.net/
也可以从这里直接下载
http://download.csdn.net/detail/zengraoli/9815332
把源码下载下来,解压得到一个文件夹和hpp文件
拷贝到(或者直接解压到boost目录中)
打开vs(使用比较低版本的vs2010,要求比较高,同时没有c11可以使用,在vs2015也同样通过了测试)
如果还不会使用OpenCV和boost,可以参考blog文:
编译并使用opencv3.2:http://blog.csdn.net/zengraoli/article/details/70185803
编译并使用boost1.63:http://blog.csdn.net/zengraoli/article/details/70187556
测试例子的功能是浏览一个文件夹里面的1到10张图片,对比用单线程显示一张图片,和用8个线程同时显示的耗时对比
代码如下:
[cpp] view
plain copy
print?
#include "stdafx.h"
#include "stdio.h"
#include "iostream"
#include "vector"
#include "windows.h"
#include "boost/threadpool.hpp"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace boost::threadpool;
using namespace cv;
#define THREAD_COUNT 8 // 进程池的进程最大个数
#define FILE_NAME_LENGTH 64 // 文件名的长度
#define WINDOWS_NAME_LENGTH 32 // 窗口名的长度
#define SLEEP_SECOND 1000 // 每一个进程结束任务退出时,需要等待的时长
#define WAIT_KEY_SECOND 100 // opencv显示的等待时间
#define PIC_FOLDER_PATH "D:\\pic\\" // 表明显示图片所在的文件夹路径
#define PIC_BEGIN_NUM 1 // 文件夹下最小图片的下标(包含)
#define PIC_END_NUM 11 // 文件夹下最大图片的下标(不包含)
#pragma comment(lib, "lib/opencv_core320d.lib")
#pragma comment(lib, "lib/opencv_highgui320d.lib")
#pragma comment(lib, "lib/opencv_imgcodecs320d.lib")
// 每个线程的任务
void Task(IplImage *p_img)
{
// boost::mutex::scoped_lock lock(m_io_monitor) //每个线程使用全局互斥来保证每次只有一个线程执行
char windows_name[WINDOWS_NAME_LENGTH];
sprintf_s(windows_name, "%d", boost::this_thread::get_id());
cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);
cvShowImage(windows_name, p_img);
cvWaitKey(WAIT_KEY_SECOND);
cvReleaseImage(&p_img);//释放图片
// cvDestroyAllWindows();//销毁窗口
Sleep(SLEEP_SECOND);
}
// 给线程池中的每一个线程分配任务,schedule会先把全部的任务接下来,如果没有线程空闲,则自动等待;wait遇到还有线程没有结束任务,那么其会进行阻塞等待
void ExecuteWithThreadpool()
{
//设置允许开启的线程数
pool tp(THREAD_COUNT);
// opencv读取文件夹下的所有图片
char file_name[FILE_NAME_LENGTH];
IplImage *p_img;
vector<IplImage *> v;
for (int index = PIC_BEGIN_NUM; index < PIC_END_NUM; index++)
{
sprintf_s(file_name, "%s%d.png", PIC_FOLDER_PATH, index);
p_img = cvLoadImage(file_name, 1);
v.push_back(p_img);
}
vector<IplImage *>::iterator it;
int index = 0;
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
// 传入线程中作为参数
tp.schedule(boost::bind(Task, *it));
cout << "===========" << index++ << "===========" << endl;
}
tp.wait();
cout << "end." << endl;
}
// 显示一张图片
void ShowImg(IplImage *p_img, int index)
{
char windows_name[WINDOWS_NAME_LENGTH];
sprintf_s(windows_name, "%d", index);
cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);
cvShowImage(windows_name, p_img);
cvWaitKey(WAIT_KEY_SECOND);
cvReleaseImage(&p_img);//释放图片
cvDestroyAllWindows();//销毁窗口
Sleep(SLEEP_SECOND);
}
// 不使用多线程的程序段
void ExecuteWithNotThread()
{
// opencv读取文件夹下的所有图片
char file_name[FILE_NAME_LENGTH];
IplImage *p_img;
vector<IplImage *> v;
for (int index = 1; index < 11; index++)
{
sprintf_s(file_name, "D:\\pic\\%d.png", index);
p_img = cvLoadImage(file_name, 1);
v.push_back(p_img);
}
vector<IplImage *>::iterator it;
int index = 0;
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
// 传入线程中作为参数
ShowImg(*it, index);
cout << "===========" << index++ << "===========" << endl;
}
cout << "end." << endl;
}
int main()
{
double start, end;
start = clock();
ExecuteWithNotThread();
end = clock();
printf("ExecuteWithNotThread:%fs \n", (end - start)/1000);
start = clock();
ExecuteWithThreadpool();
end = clock();
printf("ExecuteWithThreadpool:%fs \n", (end - start)/1000);
return 0;
}
效果如下:
转自:http://blog.csdn.net/zengraoli/article/details/70187693
需求
很多时候,需要用到多线程,但是线程每一次的分配都需要消耗时间,同时线程也不是无限制的开启的(需要固定一个数量)。如果我们既想要固定数量,又不想每次都new一个线程,我们这么做就能满足要求:
a、固定一个数量,表示最大可使用线程的个数,threadCount=8;
b、在程序开始的时候,直接new出来threadCount个线程,假如存放到thread[threadCount-1]中
c、遇到一个任务,从thread[threadCount-1]中取出来一个线程,设置他的任务为Task,并且让threadCount-1,让此线程start
d、线程中的任务结束后让,threadCount+1
线程池
上面的流程,其实就是一个线程池的原型,为了使用方便,使用了boost的一个开源工程,threadpool,下载地址为http://threadpool.sourceforge.net/
也可以从这里直接下载
http://download.csdn.net/detail/zengraoli/9815332
把源码下载下来,解压得到一个文件夹和hpp文件
拷贝到(或者直接解压到boost目录中)
在vs中配置使用
打开vs(使用比较低版本的vs2010,要求比较高,同时没有c11可以使用,在vs2015也同样通过了测试)如果还不会使用OpenCV和boost,可以参考blog文:
编译并使用opencv3.2:http://blog.csdn.net/zengraoli/article/details/70185803
编译并使用boost1.63:http://blog.csdn.net/zengraoli/article/details/70187556
测试例子的功能是浏览一个文件夹里面的1到10张图片,对比用单线程显示一张图片,和用8个线程同时显示的耗时对比
代码如下:
[cpp] view
plain copy
print?
#include "stdafx.h"
#include "stdio.h"
#include "iostream"
#include "vector"
#include "windows.h"
#include "boost/threadpool.hpp"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace boost::threadpool;
using namespace cv;
#define THREAD_COUNT 8 // 进程池的进程最大个数
#define FILE_NAME_LENGTH 64 // 文件名的长度
#define WINDOWS_NAME_LENGTH 32 // 窗口名的长度
#define SLEEP_SECOND 1000 // 每一个进程结束任务退出时,需要等待的时长
#define WAIT_KEY_SECOND 100 // opencv显示的等待时间
#define PIC_FOLDER_PATH "D:\\pic\\" // 表明显示图片所在的文件夹路径
#define PIC_BEGIN_NUM 1 // 文件夹下最小图片的下标(包含)
#define PIC_END_NUM 11 // 文件夹下最大图片的下标(不包含)
#pragma comment(lib, "lib/opencv_core320d.lib")
#pragma comment(lib, "lib/opencv_highgui320d.lib")
#pragma comment(lib, "lib/opencv_imgcodecs320d.lib")
// 每个线程的任务
void Task(IplImage *p_img)
{
// boost::mutex::scoped_lock lock(m_io_monitor) //每个线程使用全局互斥来保证每次只有一个线程执行
char windows_name[WINDOWS_NAME_LENGTH];
sprintf_s(windows_name, "%d", boost::this_thread::get_id());
cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);
cvShowImage(windows_name, p_img);
cvWaitKey(WAIT_KEY_SECOND);
cvReleaseImage(&p_img);//释放图片
// cvDestroyAllWindows();//销毁窗口
Sleep(SLEEP_SECOND);
}
// 给线程池中的每一个线程分配任务,schedule会先把全部的任务接下来,如果没有线程空闲,则自动等待;wait遇到还有线程没有结束任务,那么其会进行阻塞等待
void ExecuteWithThreadpool()
{
//设置允许开启的线程数
pool tp(THREAD_COUNT);
// opencv读取文件夹下的所有图片
char file_name[FILE_NAME_LENGTH];
IplImage *p_img;
vector<IplImage *> v;
for (int index = PIC_BEGIN_NUM; index < PIC_END_NUM; index++)
{
sprintf_s(file_name, "%s%d.png", PIC_FOLDER_PATH, index);
p_img = cvLoadImage(file_name, 1);
v.push_back(p_img);
}
vector<IplImage *>::iterator it;
int index = 0;
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
// 传入线程中作为参数
tp.schedule(boost::bind(Task, *it));
cout << "===========" << index++ << "===========" << endl;
}
tp.wait();
cout << "end." << endl;
}
// 显示一张图片
void ShowImg(IplImage *p_img, int index)
{
char windows_name[WINDOWS_NAME_LENGTH];
sprintf_s(windows_name, "%d", index);
cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);
cvShowImage(windows_name, p_img);
cvWaitKey(WAIT_KEY_SECOND);
cvReleaseImage(&p_img);//释放图片
cvDestroyAllWindows();//销毁窗口
Sleep(SLEEP_SECOND);
}
// 不使用多线程的程序段
void ExecuteWithNotThread()
{
// opencv读取文件夹下的所有图片
char file_name[FILE_NAME_LENGTH];
IplImage *p_img;
vector<IplImage *> v;
for (int index = 1; index < 11; index++)
{
sprintf_s(file_name, "D:\\pic\\%d.png", index);
p_img = cvLoadImage(file_name, 1);
v.push_back(p_img);
}
vector<IplImage *>::iterator it;
int index = 0;
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
// 传入线程中作为参数
ShowImg(*it, index);
cout << "===========" << index++ << "===========" << endl;
}
cout << "end." << endl;
}
int main()
{
double start, end;
start = clock();
ExecuteWithNotThread();
end = clock();
printf("ExecuteWithNotThread:%fs \n", (end - start)/1000);
start = clock();
ExecuteWithThreadpool();
end = clock();
printf("ExecuteWithThreadpool:%fs \n", (end - start)/1000);
return 0;
}
效果如下:
转自:http://blog.csdn.net/zengraoli/article/details/70187693
相关文章推荐
- 使用boost线程池(多线程使用opencv处理图片)
- 使用GCD处理非UI相关的异步任务 Object-C异步多线程加载网络图片
- qt中使用opencv处理图片 QImage 和 IplImage 相互之间转换问题
- 在Android中使用OpenCv 来处理图片
- qt中使用opencv处理图片 QImage 和 IplImage 相互之间转换问题
- Java使用OpenCV和Tesseract-OCR实现银行卡图片处理与卡号识别
- 【IOS】Opencv使用摄像头实时处理图片的demo
- ImageMagick for java 使用Jmagick处理高质量图片
- image 和 imagebuffer 的 使用 (一个图片 处理 的 算法 )
- ASP JPEG图片处理高级使用方法
- 使用 Visual Studio 2008 和 OpenCV 在窗口显示图片或视频
- 使用.net(C#)处理图片之:旋转图片任意角度
- 关于Gridview中使用控件和图片导出到Excel的处理
- 使用OpenMP实现多线程,不仅是用在循环处理上
- 使用等待对象的方法,实现多线程的同步处理。。
- (转) 在C#中使用WIA获取扫描仪数据(三、利用Filter处理图片)
- 关于Gridview中使用控件和图片导出到Excel的处理
- FCKeditor是使用非常广泛的HTML编辑器,本文从 ASP.NET 的使用场景对 FCKeditor 与 FCKeditor.NET 的配置、功能扩展(如自定义文件上传子目录、自定义文件名、上传图片的后期处理等)、以及安全性进行初步的阐述。
- 多线程处理:如何使用同步类
- struts2中使用Blob类型处理图片上传保存在数据库中并在JSP页面中显示图片