日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

opencv 多线程加速_线程池给你写好了,想加速拿来用就行哈

發(fā)布時(shí)間:2023/12/1 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv 多线程加速_线程池给你写好了,想加速拿来用就行哈 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

圖像拼接實(shí)現(xiàn)見

OpenCV源碼系列|圖像拼接1

OpenCV源碼系列|圖像拼接2

耗時(shí)在調(diào)用函數(shù)

Mat pano;?Ptr?stitcher?=?Stitcher::create(mode);?Stitcher::Status?status?=?stitcher->stitch(imgs,?pano)

能否將這一步放進(jìn)線程池里進(jìn)行加速呢?

1. 測試函數(shù):

#include "t.h"#include #include #include #include #include #include #include #include"opencv2/imgproc/imgproc.hpp"#include "opencv2/imgcodecs.hpp"#include "opencv2/stitching.hpp"#include "omp.h"using namespace cv;using namespace std;Mat img=imread("./1.png");//線程池初始化void threadpool_init(threadpool_t *pool, int threads);//往線程池中加入任務(wù)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);//任意添加自己的代碼實(shí)現(xiàn)void* mytask(void *arg){ clock_t start,end; start=clock(); Mat pano; Ptr stitcher = Stitcher::create(mode); Stitcher::Status status = stitcher->stitch(imgs, pano); if (status != Stitcher::OK) { cout << "Can't stitch images, error code = " << int(status) << endl; exit(0); } imwrite(result_name, pano); cout << "stitching completed successfully\n" << result_name << " saved!"; free(arg); end=clock(); cout<<"圖像拼接時(shí)間: "<double)(end-start)/CLOCKS_PER_SEC<< return NULL;}//測試代碼int main(int argc, char* argv[]){ clock_t start,end; start=clock(); int retval = parseCmdArgs(argc, argv); if (retval) return EXIT_FAILURE; threadpool_t pool; //初始化線程池,最多三個(gè)線程 threadpool_init(&pool, 10); // int i; //創(chuàng)建十個(gè)任務(wù) //for(i=0; i < 10; i++) // { int *arg = new int((sizeof(int))); *arg = 0; threadpool_add_task(&pool, mytask, arg); // } threadpool_destroy(&pool); end=clock(); cout<<"多線程運(yùn)行時(shí)間: "<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; start=clock(); 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; } //在像素較大時(shí)候,開啟這個(gè)模式 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; //實(shí)際測試 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 << "Can't read image '" << argv[i] << "'\n"; return EXIT_FAILURE; } //對圖片進(jìn)行裁剪 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); } } end=clock(); cout<<"圖像讀取時(shí)間: "<double)(end-start)/CLOCKS_PER_SEC<< return EXIT_SUCCESS;}

線程池對應(yīng)的定義與實(shí)現(xiàn)

2. c.h

#ifndef _CONDITION_H_#define _CONDITION_H_#include //封裝一個(gè)互斥量和條件變量作為狀態(tài)typedef struct condition{ pthread_mutex_t pmutex; pthread_cond_t pcond;}condition_t;//對狀態(tài)的操作函數(shù)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);#endif

3. 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);}//固定時(shí)間等待int condition_timedwait(condition_t *cond, const struct timespec *abstime){ return pthread_cond_timedwait(&cond->pcond, &cond->pmutex, abstime);}//喚醒一個(gè)睡眠線程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"//封裝線程池中的對象需要執(zhí)行的任務(wù)對象typedef struct task{ void *(*run)(void *args); //函數(shù)指針,需要執(zhí)行的任務(wù) void *arg; //參數(shù) struct task *next; //任務(wù)隊(duì)列中下一個(gè)任務(wù)}task_t;//下面是線程池結(jié)構(gòu)體typedef struct threadpool{ condition_t ready; //狀態(tài)量 task_t *first; //任務(wù)隊(duì)列中第一個(gè)任務(wù) task_t *last; //任務(wù)隊(duì)列中最后一個(gè)任務(wù) int counter; //線程池中已有線程數(shù) int idle; //線程池中kongxi線程數(shù) int max_threads; //線程池最大線程數(shù) int quit; //是否退出標(biāo)志}threadpool_t;//線程池初始化void threadpool_init(threadpool_t *pool, int threads);//往線程池中加入任務(wù)void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg);//摧毀線程池void threadpool_destroy(threadpool_t *pool);#endif

5. t.cpp

#include "t.h"#include #include #include #include #include //創(chuàng)建的線程執(zhí)行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++; //等待隊(duì)列有任務(wù)到來 或者 收到線程池銷毀通知 while(pool->first == NULL && !pool->quit) { //否則線程阻塞等待 printf("thread %d is waiting\n", (int)pthread_self()); //獲取從當(dāng)前時(shí)間,并加上等待時(shí)間, 設(shè)置進(jìn)程的超時(shí)睡眠時(shí)間 clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += 2; int status; status = condition_timedwait(&pool->ready, &abstime); //該函數(shù)會(huì)解鎖,允許其他線程訪問,當(dāng)被喚醒時(shí),加鎖 if(status == ETIMEDOUT) { printf("thread %d wait timed out\n", (int)pthread_self()); timeout = 1; break; } } pool->idle--; if(pool->first != NULL) { //取出等待隊(duì)列最前的任務(wù),移除任務(wù),并執(zhí)行任務(wù) task_t *t = pool->first; pool->first = t->next; //由于任務(wù)執(zhí)行需要消耗時(shí)間,先解鎖讓其他線程訪問線程池 condition_unlock(&pool->ready); //執(zhí)行任務(wù) t->run(t->arg); //執(zhí)行完任務(wù)釋放內(nèi)存 free(t); //重新加鎖 condition_lock(&pool->ready); } //退出線程池 if(pool->quit && pool->first == NULL) { pool->counter--;//當(dāng)前工作的線程數(shù)-1 //若線程池中沒有線程,通知等待線程(主線程)全部任務(wù)已經(jīng)完成 if(pool->counter == 0) { condition_signal(&pool->ready); } condition_unlock(&pool->ready); break; } //超時(shí),跳出銷毀線程 if(timeout == 1) { pool->counter--;//當(dāng)前工作的線程數(shù)-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;}//增加一個(gè)任務(wù)到線程池void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg){ //產(chǎn)生一個(gè)新的任務(wù) task_t *newtask = (task_t *)malloc(sizeof(task_t)); newtask->run = run; newtask->arg = arg; newtask->next=NULL;//新加的任務(wù)放在隊(duì)列尾端 //線程池的狀態(tài)被多個(gè)線程共享,操作前需要加鎖 condition_lock(&pool->ready); if(pool->first == NULL)//第一個(gè)任務(wù)加入 { pool->first = newtask; } else { pool->last->next = newtask; } pool->last = newtask; //隊(duì)列尾指向新加入的線程 //線程池中有線程空閑,喚醒 if(pool->idle > 0) { condition_signal(&pool->ready); } //當(dāng)前線程池中線程個(gè)數(shù)沒有達(dá)到設(shè)定的最大值,創(chuàng)建一個(gè)新的線性 else if(pool->counter < pool->max_threads) { pthread_t tid; pthread_create(&tid, NULL, thread_routine, pool); pool->counter++; } //結(jié)束,訪問 condition_unlock(&pool->ready);}//線程池銷毀void threadpool_destroy(threadpool_t *pool){ //如果已經(jīng)調(diào)用銷毀,直接返回 if(pool->quit) { return; } //加鎖 condition_lock(&pool->ready); //設(shè)置銷毀標(biāo)記為1 pool->quit = 1; //線程池中線程個(gè)數(shù)大于0 if(pool->counter > 0) { //對于等待的線程,發(fā)送信號喚醒 if(pool->idle > 0) { condition_broadcast(&pool->ready); } //正在執(zhí)行任務(wù)的線程,等待他們結(jié)束任務(wù) while(pool->counter) { condition_wait(&pool->ready); } } condition_unlock(&pool->ready); condition_destroy(&pool->ready);}

6. 顯示:

總結(jié)

以上是生活随笔為你收集整理的opencv 多线程加速_线程池给你写好了,想加速拿来用就行哈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。