网站做seo多少钱,河北省建设工程网站,中国新闻社是什么级别,企业网站建设的常见流程为图像拼接实现见#xff1a;OpenCV源码系列|图像拼接1OpenCV源码系列|图像拼接2耗时在调用函数#xff1a;Mat pano; Ptr stitcher Stitcher::create(mode); Stitcher::Status status stitcher-stitch(imgs, pano)能否将这一步放进线程池里进行加速呢#xff1f;1. 测试… 图像拼接实现见OpenCV源码系列|图像拼接1OpenCV源码系列|图像拼接2耗时在调用函数 Mat pano; Ptr stitcher Stitcher::create(mode); Stitcher::Status status stitcher-stitch(imgs, pano)能否将这一步放进线程池里进行加速呢1. 测试函数#include t.h#include #include #include #include #include #include #include #includeopencv2/imgproc/imgproc.hpp#include opencv2/imgcodecs.hpp#include opencv2/stitching.hpp#include omp.husing namespace cv;using namespace std;Mat imgimread(./1.png);//线程池初始化void threadpool_init(threadpool_t *pool, int threads);//往线程池中加入任务void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg);//摧毁线程池void threadpool_destroy(threadpool_t *pool);bool divide_images false;Stitcher::Mode mode Stitcher::PANORAMA;vector imgs;string result_name result.jpg;void printUsage(char** argv);int parseCmdArgs(int argc, char** argv);//任意添加自己的代码实现void* mytask(void *arg){ clock_t start,end; startclock(); Mat pano; Ptr stitcher Stitcher::create(mode); Stitcher::Status status stitcher-stitch(imgs, pano); if (status ! Stitcher::OK) { cout Cant stitch images, error code int(status) endl; exit(0); } imwrite(result_name, pano); cout stitching completed successfully\n result_name saved!; free(arg); endclock(); cout图像拼接时间: double)(end-start)/CLOCKS_PER_SEC return NULL;}//测试代码int main(int argc, char* argv[]){ clock_t start,end; startclock(); int retval parseCmdArgs(argc, argv); if (retval) return EXIT_FAILURE; threadpool_t pool; //初始化线程池最多三个线程 threadpool_init(pool, 10); // int i; //创建十个任务 //for(i0; i 10; i) // { int *arg new int((sizeof(int))); *arg 0; threadpool_add_task(pool, mytask, arg); // } threadpool_destroy(pool); endclock(); cout多线程运行时间: double)(end-start)/CLOCKS_PER_SEC return EXIT_SUCCESS; //return 0;}void printUsage(char** argv){ cout Images stitcher.\n\n Usage :\n argv[0] [Flags] img1 img2 [...imgN]\n\n Flags:\n --d3\n internally creates three chunks of each image to increase stitching success\n --mode (panorama|scans)\n Determines configuration of stitcher. The default is panorama,\n mode suitable for creating photo panoramas. Option scans is suitable\n for stitching materials under affine transformation, such as scans.\n --output \n The default is result.jpg.\n\n Example usage :\n argv[0] --d3 --try_use_gpu yes --mode scans img1.jpg img2.jpg\n;}int parseCmdArgs(int argc, char** argv){ clock_t start,end; startclock(); if (argc 1) { printUsage(argv); return EXIT_FAILURE; } for (int i 1; i argc; i) { //查看帮助 if (string(argv[i]) --help || string(argv[i]) /?) { printUsage(argv); return EXIT_FAILURE; } //在像素较大时候开启这个模式 else if (string(argv[i]) --d3) { divide_images true; } else if (string(argv[i]) --output) { result_name argv[i 1]; i; } else if (string(argv[i]) --mode) { //仅仅是重叠度高的可用 if (string(argv[i 1]) panorama) mode Stitcher::PANORAMA; //实际测试 scans 模式比 panorama 适用范围更为广泛 else if (string(argv[i 1]) scans) mode Stitcher::SCANS; else { cout Bad --mode flag value\n; return EXIT_FAILURE; } i; } else { //终端读取一系列图片 Mat img imread(argv[i]); if (img.empty()) { cout Cant read image argv[i] \n; return EXIT_FAILURE; } //对图片进行裁剪 if (divide_images) { Rect rect(0, 0, img.cols / 2, img.rows); imgs.push_back(img(rect).clone()); rect.x img.cols / 3; imgs.push_back(img(rect).clone()); rect.x img.cols / 2; imgs.push_back(img(rect).clone()); } else imgs.push_back(img); } } endclock(); cout图像读取时间: double)(end-start)/CLOCKS_PER_SEC return EXIT_SUCCESS;}线程池对应的定义与实现2. c.h#ifndef _CONDITION_H_#define _CONDITION_H_#include //封装一个互斥量和条件变量作为状态typedef struct condition{ pthread_mutex_t pmutex; pthread_cond_t pcond;}condition_t;//对状态的操作函数int condition_init(condition_t *cond);int condition_lock(condition_t *cond);int condition_unlock(condition_t *cond);int condition_wait(condition_t *cond);int condition_timedwait(condition_t *cond, const struct timespec *abstime);int condition_signal(condition_t* cond);int condition_broadcast(condition_t *cond);int condition_destroy(condition_t *cond);#endif3. c.cpp#include c.h//初始化int condition_init(condition_t *cond){ int status; if((status pthread_mutex_init(cond-pmutex, NULL))) return status; if((status pthread_cond_init(cond-pcond, NULL))) return status; return 0;}//加锁int condition_lock(condition_t *cond){ return pthread_mutex_lock(cond-pmutex);}//解锁int condition_unlock(condition_t *cond){ return pthread_mutex_unlock(cond-pmutex);}//等待int condition_wait(condition_t *cond){ return pthread_cond_wait(cond-pcond, cond-pmutex);}//固定时间等待int condition_timedwait(condition_t *cond, const struct timespec *abstime){ return pthread_cond_timedwait(cond-pcond, cond-pmutex, abstime);}//唤醒一个睡眠线程int condition_signal(condition_t* cond){ return pthread_cond_signal(cond-pcond);}//唤醒所有睡眠线程int condition_broadcast(condition_t *cond){ return pthread_cond_broadcast(cond-pcond);}//释放int condition_destroy(condition_t *cond){ int status; if((status pthread_mutex_destroy(cond-pmutex))) return status; if((status pthread_cond_destroy(cond-pcond))) return status; return 0;}4. t.h#ifndef _THREAD_POOL_H_#define _THREAD_POOL_H_//线程池头文件#include c.h//封装线程池中的对象需要执行的任务对象typedef struct task{ void *(*run)(void *args); //函数指针需要执行的任务 void *arg; //参数 struct task *next; //任务队列中下一个任务}task_t;//下面是线程池结构体typedef struct threadpool{ condition_t ready; //状态量 task_t *first; //任务队列中第一个任务 task_t *last; //任务队列中最后一个任务 int counter; //线程池中已有线程数 int idle; //线程池中kongxi线程数 int max_threads; //线程池最大线程数 int quit; //是否退出标志}threadpool_t;//线程池初始化void threadpool_init(threadpool_t *pool, int threads);//往线程池中加入任务void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg);//摧毁线程池void threadpool_destroy(threadpool_t *pool);#endif5. t.cpp#include t.h#include #include #include #include #include //创建的线程执行void *thread_routine(void *arg){ struct timespec abstime; int timeout; printf(thread %d is starting\n, (int)pthread_self()); threadpool_t *pool (threadpool_t *)arg; while(1) { timeout 0; //访问线程池之前需要加锁 condition_lock(pool-ready); //空闲 pool-idle; //等待队列有任务到来 或者 收到线程池销毁通知 while(pool-first NULL !pool-quit) { //否则线程阻塞等待 printf(thread %d is waiting\n, (int)pthread_self()); //获取从当前时间并加上等待时间 设置进程的超时睡眠时间 clock_gettime(CLOCK_REALTIME, abstime); abstime.tv_sec 2; int status; status condition_timedwait(pool-ready, abstime); //该函数会解锁允许其他线程访问当被唤醒时加锁 if(status ETIMEDOUT) { printf(thread %d wait timed out\n, (int)pthread_self()); timeout 1; break; } } pool-idle--; if(pool-first ! NULL) { //取出等待队列最前的任务移除任务并执行任务 task_t *t pool-first; pool-first t-next; //由于任务执行需要消耗时间先解锁让其他线程访问线程池 condition_unlock(pool-ready); //执行任务 t-run(t-arg); //执行完任务释放内存 free(t); //重新加锁 condition_lock(pool-ready); } //退出线程池 if(pool-quit pool-first NULL) { pool-counter--;//当前工作的线程数-1 //若线程池中没有线程通知等待线程(主线程)全部任务已经完成 if(pool-counter 0) { condition_signal(pool-ready); } condition_unlock(pool-ready); break; } //超时跳出销毁线程 if(timeout 1) { pool-counter--;//当前工作的线程数-1 condition_unlock(pool-ready); break; } condition_unlock(pool-ready); } printf(thread %d is exiting\n, (int)pthread_self()); return NULL;}//线程池初始化void threadpool_init(threadpool_t *pool, int threads){ condition_init(pool-ready); pool-first NULL; pool-last NULL; pool-counter 0; pool-idle 0; pool-max_threads threads; pool-quit 0;}//增加一个任务到线程池void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg){ //产生一个新的任务 task_t *newtask (task_t *)malloc(sizeof(task_t)); newtask-run run; newtask-arg arg; newtask-nextNULL;//新加的任务放在队列尾端 //线程池的状态被多个线程共享操作前需要加锁 condition_lock(pool-ready); if(pool-first NULL)//第一个任务加入 { pool-first newtask; } else { pool-last-next newtask; } pool-last newtask; //队列尾指向新加入的线程 //线程池中有线程空闲唤醒 if(pool-idle 0) { condition_signal(pool-ready); } //当前线程池中线程个数没有达到设定的最大值创建一个新的线性 else if(pool-counter pool-max_threads) { pthread_t tid; pthread_create(tid, NULL, thread_routine, pool); pool-counter; } //结束访问 condition_unlock(pool-ready);}//线程池销毁void threadpool_destroy(threadpool_t *pool){ //如果已经调用销毁直接返回 if(pool-quit) { return; } //加锁 condition_lock(pool-ready); //设置销毁标记为1 pool-quit 1; //线程池中线程个数大于0 if(pool-counter 0) { //对于等待的线程发送信号唤醒 if(pool-idle 0) { condition_broadcast(pool-ready); } //正在执行任务的线程等待他们结束任务 while(pool-counter) { condition_wait(pool-ready); } } condition_unlock(pool-ready); condition_destroy(pool-ready);}6. 显示