概述
在处理大批量图像的过程中,由于raw data的分辨率很高,或者为多通道图像,不满足后续的处理要求。
为了提高图像的加载速度和处理速度,参考相关网络资源,这里给出了一个简单多线程处理框架。
部分主程序:main.cpp
#if 0
#include <process.h>
#include "comm_def.hpp"
#include "comm_fun.hpp"
#include "img_queue.hpp"
DWORD WINAPI ThreadProc1(LPVOID lpParam);
DWORD WINAPI ThreadProc2(LPVOID lpParam);
HANDLE hMutex;
Queue g_image_queue = NULL;
int g_import_finish = 0; //所有图像都加载完成
int g_process_finish = 0; //所有图像都处理完成
int g_temp_save_flag = 0; //是否保存模板
int export_image(QUEUE_DATA *queue_data)
{
int ret = 0;
int flag = 1;
WaitForSingleObject(hMutex, INFINITE);
if (isEmpty(g_image_queue))
{
cout<<"the queue is empty when exporting"<<endl;
ret = -1;
}
else
{
deQueue(g_image_queue, queue_data);
ret = 0;
}
ReleaseMutex(hMutex);
return ret;
}
void image_proc()
{
IplImage *p_image = NULL;
int import_finish;
char scan_data[8] = {0};
printf("going to create the template? y/n:");
scanf("%s",scan_data);
if (scan_data[0] == 'y' || scan_data[0] == 'Y')
{
g_temp_save_flag = 1;
}
else
{
initial_tmeplate();
g_temp_save_flag = 0;
}
QUEUE_DATA queue_data;
while (1)
{
if (0 == export_image(&queue_data))
{
cny_rec(queue_data.p_image, queue_data.file_name);
cvReleaseImage(&(queue_data.p_image));
}
else
{
WaitForSingleObject(hMutex, INFINITE);
import_finish = g_import_finish;
if (import_finish)
g_process_finish = 1;
ReleaseMutex(hMutex);
if (import_finish)
break;
else
Sleep(500);
}
}
return;
}
//将图像装在到队列
int import_image(const char *file_name, const char *file_path)
{
int ret = 0;
int flag = 1;
IplImage *p_image_read = cvLoadImage(file_path);
//获取图像缩放后,释放原图像
IplImage *p_image_zoom = NULL;
image_zoom(p_image_read, 1, 0.35, &p_image_zoom); //0.35
cvReleaseImage(&p_image_read);
//获取灰度图像后,释放缩放图像
QUEUE_DATA queue_data;
queue_data.p_image = cvCreateImage(cvGetSize(p_image_zoom), p_image_zoom->depth, 1);
memcpy(queue_data.file_name, file_name, sizeof(queue_data.file_name));
cvCvtColor(p_image_zoom, queue_data.p_image, CV_BGR2GRAY);
cvReleaseImage(&p_image_zoom);
char file_path_imp[128] = {0};
sprintf(file_path_imp, "%s\%s.bmp",PATH_IMP, file_name);
cvSaveImage(file_path_imp, queue_data.p_image);
while (flag)
{
WaitForSingleObject(hMutex, INFINITE);
if (isFull(g_image_queue))
{
cout<<"waiting in thread 1"<<endl;
}
else
{
enQueue(g_image_queue, queue_data);
flag = 0;
}
ReleaseMutex(hMutex);
Sleep(500);
}
//释放
cvReleaseImage(&(queue_data.p_image));
return ret;
}
void FindBmpFile(CString strFoldername)
{
CFileFind tempFind;
BOOL bFound; //判断是否成功找到文件
bFound=tempFind.FindFile(strFoldername
+
"\*.*");
//修改" "内内容给限定查找文件类型
CString strTmp;
//如果找到的是文件夹 存放文件夹路径
while(bFound)
//遍历所有文件
{
bFound=tempFind.FindNextFile(); //第一次执行FindNextFile是选择到第一个文件,以后执行为选择到下一个文件
if(tempFind.IsDots())
continue; //如果找到的是返回上层的目录 则结束本次查找
if(tempFind.IsDirectory())
//找到的是文件夹,则遍历该文件夹下的文件
{
continue;
strTmp="";
strTmp=tempFind.GetFilePath();
tempFind.FindFile(strTmp);
}
else
{
strTmp=tempFind.GetFileName(); //保存文件名,包括后缀名
// 在此处添加对找到文件的处理
char file_name[128] = {0};
char file_path[128] = {0};
sprintf(file_name, "%S", strTmp);
memset(file_name+10, 0x0, sizeof(file_name) - 10); //去除后缀
sprintf(file_path, "%S\%S", strFoldername,strTmp);
import_image(file_name, file_path);
printf("load "%s" successfullyn",file_path);
}
}
//没有文件可导入了
WaitForSingleObject(hMutex, INFINITE);
g_import_finish = 1;
ReleaseMutex(hMutex);
tempFind.Close();
return;
}
int main()
{
int exit = 0;
int state = 0;
HANDLE handle1;
HANDLE handle2;
//初始化队列
g_image_queue = createQueue(50);
handle1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
handle2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
CloseHandle(handle1);
CloseHandle(handle2);
hMutex = CreateMutex(NULL, false, NULL);
//waiting to load image
Sleep(1000);
//waiting
while (1)
{
WaitForSingleObject(hMutex, INFINITE);
state = isEmpty(g_image_queue);
exit = g_process_finish;
ReleaseMutex(hMutex);
if (exit && state)
{
Sleep(2000);
break;
}
else
{
//
cout<<"delay to exit in main()"<<endl;
Sleep(2000);
}
}
//销毁队列
disPoseQueue(g_image_queue);
return 0;
}
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
/*
while (0)
{
WaitForSingleObject(hMutex, INFINITE);
if (tickets > 0)
{
Sleep(1);
cout<<"thread1 :"<<tickets--<<endl;
}
ReleaseMutex(hMutex);
}
*/
FindBmpFile(PATH_ORIGINAL);
cout<<"thread1 exit"<<endl;
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParam)
{
int import_finish = 0;
/*
while (1)
{
WaitForSingleObject(hMutex, INFINITE);
if (tickets > 0)
{
Sleep(1);
cout<<"thread2 :"<<tickets--<<endl;
}
ReleaseMutex(hMutex);
}
*/
//给时间导入图片
//
Sleep(1000*25);
while (!import_finish)
{
WaitForSingleObject(hMutex, INFINITE);
import_finish = g_import_finish;
ReleaseMutex(hMutex);
Sleep(1000);
}
image_proc();
cout<<"thread2 exit"<<endl;
return 0;
}
#endif
队列源文件:image_queue.cpp
//http://blog.csdn.net/cdl2008sky/article/details/8300264
#include "img_queue.hpp"
int isEmpty(Queue q){
return q->size==0;
}
int isFull(Queue q){
return q->size==q->capacity;
}
Queue createQueue(int capacity){
Queue queue;
queue = (Queue)malloc(sizeof(lqueue));
if(queue == NULL){
return NULL;
}
//申请空间
queue->Array = (QUEUE_DATA *)malloc(sizeof(QUEUE_DATA)*capacity);
if(queue->Array == NULL ){
return NULL;
}
//清零
memset(queue->Array, 0x0, sizeof(QUEUE_DATA)*capacity);
queue->capacity = capacity;
queue->size = 0;
queue->front = 0;
queue->rear = -1;
return queue;
}
void makEmpty(Queue q){
q->size = 0;
q->rear = -1;
q->front = 0;
}
void disPoseQueue(Queue q){
if(q != NULL)
{
if (q->Array != NULL)
{
free(q->Array);
}
free(q);
}
}
/**这个方法实现循环队列,当rear到达尾端(入列),或者front到达尾端(出列),它又回到开头**/
int circularQ(int index,Queue q){
if(++index > q->capacity){
return 0;
}
return index;
}
/*入列*/
int enQueue(Queue q, QUEUE_DATA queue_data){
if(isFull(q)){
printf("Queue is Fulln");
return -1;
} else {
q->size ++;
q->rear = circularQ(q->rear,q);
q->Array[q->rear].p_image = cvCloneImage(queue_data.p_image);
memset(q->Array[q->rear].file_name, 0x0, STR_SIZE);
memcpy(q->Array[q->rear].file_name, queue_data.file_name, STR_SIZE);
return 0;
}
}
/*出列*/
int deQueue(Queue q, QUEUE_DATA *queue_data){
IplImage *temp_img;
char *temp_name;
if(isEmpty(q)){
printf("queue is Emptyn");
return -1;
} else {
q->size --;
temp_img = q->Array[q->front].p_image;
temp_name = q->Array[q->front].file_name;
queue_data->p_image = cvCloneImage(temp_img);
memcpy(queue_data->file_name, temp_name, STR_SIZE);
cvReleaseImage(&temp_img);
q->front = circularQ(q->front,q);
return 0;
}
}
/**取队列头元素**/
QUEUE_DATA *front(Queue q){
return &(q->Array[q->front]);
}
下载地址: http://download.csdn.net/detail/k_shmily/9583760
最后
以上就是大方墨镜为你收集整理的VS中图像处理多线程框架(导入队列、导出队列)的全部内容,希望文章能够帮你解决VS中图像处理多线程框架(导入队列、导出队列)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复