本文介绍MFC中图像采集及图像处理的多线程编方法。创建了三个线程,分别为图像采集、图像处理及图像显示线程。线程之间的共享数据有保存的图像链表和图像处理结果存储结构。

图像链表:list<Hobject> imgList;
存储结构体:
struct ResultContainer
{
Hobject result_img;
HTuple time_needed;
HTuple result_handle;
HTuple result_data;
};

创建4个事件保证线程同步性

HANDLE  fgStopEvent;
HANDLE  newImageEvent;
HANDLE  newResultEvent;
HANDLE  containerIsFreeEvent;

使用2个关键段保证共享数据使用的互斥性

CRITICAL_SECTION    newImageMutex;
CRITICAL_SECTION    resultDataMutex;

同时在头文件中加入私有成员变量:

HANDLE             dispThrHandle;        //Win32线程句柄
unsigned int       dispThreadId;         //Win32线程标识符
HANDLE             ipThrHandle;          //Win32线程句柄
unsigned int       ipThreadId;           //Win32线程标识符
HANDLE             fgThrHandle;          //Win32线程句柄
unsigned int       fgThreadId;           //Win32线程标识符
  1. 在初始化中进行关键段的初始化,创建线程等其他数据初始化过程:
    关键段初始化:
  InitializeCriticalSection(&newImageMutex);    InitializeCriticalSection(&resultDataMutex);

设置事件句柄以同步线程:

fgStopEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
newImageEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
newResultEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
containerIsFreeEvent =CreateEvent(NULL,FALSE,TRUE,NULL);

初始化共享数据:

resultData.time_needed = NULL;
resultData.result_img = NULL;
resultData.result_handle = NULL;
resultData.result_data = NULL;

其他:

ResetEvent(fgStopEvent);    //设置fgStopEvent为无信号状态
InitialGrabOfImage();       //图像采集初始化
  1. 设置一个启动按钮,开启线程,线程开启函数如下:
void CMultiThreading::StartThreads()
{//所有事件设置为初始状态ResetEvent(fgStopEvent);ResetEvent(newImageEvent);ResetEvent(newResultEvent);SetEvent(containerIsFreeEvent);imgList.clear();// 开启线程 dispThrHandle = (HANDLE)_beginthreadex(NULL,0, (unsigned (__stdcall *)(void*))&DISPRun, this,                  0,                 &dispThreadId);            ipThrHandle = (HANDLE)_beginthreadex(NULL, 0,                 (unsigned (__stdcall *)(void*))&IPRun,  this,                  0,                 &ipThreadId);              fgThrHandle = (HANDLE)_beginthreadex(NULL, 0,                 (unsigned (__stdcall *)(void*))&ImgAcqRun,    this,                 0,                   &fgThreadId);
}
  1. 设置一个停止按钮,停止所有线程,只需将停止事件设置为有信号状态:
SetEvent(fgStopEvent); 
  1. 图像采集线程:
void ImgAcqRun(void *pars)
{HTuple      sequenceName;Hobject     grabbedImage;Hlong       FGHandle;CMultiThreadingDlg *MultiThrDlg = (CMultiThreadingDlg*) pars;// ---------------------  INIT  ----------------------sequenceName = "datacode/ecc200/ecc200.seq";open_framegrabber("File",1,1,0,0,0,0,"default",-1,"default",-1,"default",sequenceName,"default",-1,-1,&FGHandle);// -----------------  WAIT FOR EVENTS  ---------------while (WAIT_OBJECT_0 != WaitForSingleObject((MultiThrDlg->fgStopEvent),0))    //Stop按钮没有触发{grab_image_async(&grabbedImage,FGHandle,-1);        EnterCriticalSection(&MultiThrDlg->newImageMutex);        // CriticalSect关键段if((MultiThrDlg->imgList).size()<MAX_BUFFERS)                     {                                                                                       (MultiThrDlg->imgList).push_back(grabbedImage);              }                                                                                      LeaveCriticalSection(&MultiThrDlg->newImageMutex);        // CriticalSectSetEvent(MultiThrDlg->newImageEvent);   //触发事件}// -----------------  RESET/CLOSE ALL HANDLES  -------ResetEvent( MultiThrDlg->newImageEvent);close_framegrabber(FGHandle);return;
}
  1. 图像处理线程:
void IPRun(void *pars)
{HTuple      T1,resultHandles,T2;Hobject     result_data, image;CString     sVal;HANDLE      eventHandle[2];struct ResultContainer ResultDataIP;CMultiThreadingDlg *MultiThrDlg = (CMultiThreadingDlg*) pars;     // --------------------  INIT ------------------------//图像初始化操作// -----------------  WAIT FOR EVENTS  ---------------eventHandle[0] = (*MultiThrDlg).newImageEvent; eventHandle[1] = (*MultiThrDlg).fgStopEvent;  while (WAIT_OBJECT_0 == WaitForMultipleObjects(2,eventHandle,FALSE,INFINITE)){EnterCriticalSection(&MultiThrDlg->newImageMutex);      // CriticalSectimage =  (MultiThrDlg->imgList).front();    MultiThrDlg->imgList.pop_front();   LeaveCriticalSection(&MultiThrDlg->newImageMutex);        // CriticalSectcount_seconds(&T1);//图像处理过程count_seconds(&T2);ResultDataIP.time_needed   = 1000*(T2[0].D() - T1[0].D());ResultDataIP.result_img    = image;  ResultDataIP.result_handle = resultHandles;ResultDataIP.result_data   = result_data;   WaitForSingleObject(MultiThrDlg->containerIsFreeEvent,INFINITE);EnterCriticalSection(&MultiThrDlg->resultDataMutex);
// CriticalSect     MultiThrDlg->resultData = ResultDataIP;
// CriticalSect                LeaveCriticalSection(&MultiThrDlg->resultDataMutex);     ResetEvent(MultiThrDlg->containerIsFreeEvent);SetEvent( MultiThrDlg->newResultEvent); }// -----------------  RESET/CLOSE ALL HANDLES  -------ResetEvent(MultiThrDlg->newResultEvent);return;
}
  1. 显示线程:
void DISPRun(void *pars)
{HTuple      time,resultHandles,i;Hobject     result_data, image;CString     sVal;Hlong       wWindowID;CRect       rect; HANDLE      eventHandle[2];struct ResultContainer rData;CMultiThreadingDlg *MultiThrDlg = (CMultiThreadingDlg*) pars;wWindowID = (Hlong)MultiThrDlg->ipWinStatic.m_hWnd;MultiThrDlg->ipWinStatic.GetClientRect(&rect);// --------------------  INIT  -----------------------set_check("~father");open_window(0,0,rect.Width(),rect.Height(),wWindowID,"visible","", &(MultiThrDlg->windowID));set_check("father");set_window_attr("border_width",0);set_part(MultiThrDlg->windowID,0,0,MultiThrDlg->height-1,MultiThrDlg->width-1);set_color((MultiThrDlg->windowID),"green");set_line_width(MultiThrDlg->windowID,3);eventHandle[0] = ((*MultiThrDlg).newResultEvent); eventHandle[1] = ((*MultiThrDlg)).fgStopEvent;  // -----------------  WAIT FOR EVENTS  ---------------while (WAIT_OBJECT_0 == WaitForMultipleObjects(2,eventHandle,FALSE,INFINITE)){   EnterCriticalSection(&MultiThrDlg->resultDataMutex);      // CriticalSectrData = MultiThrDlg->resultData;                          // CriticalSectLeaveCriticalSection(&MultiThrDlg->resultDataMutex);      SetEvent(MultiThrDlg->containerIsFreeEvent);                 time               = rData.time_needed;image              = rData.result_img;  resultHandles      = rData.result_handle;result_data         = rData.result_data;    disp_obj(image,HTuple(MultiThrDlg->windowID));sVal.Format("%4.2f",time[0].D());(MultiThrDlg->ipProcTime).SetWindowText(sVal + " ms");disp_obj(symbolXLDs,HTuple(MultiThrDlg->windowID));for (i=0; i<=(resultHandles.Num())-1; i+=1){(MultiThrDlg->ipImgLabel).SetWindowText(decodedDataStrings[i]);}  }// -----------------  RESET/CLOSE  ALL HANDLES  ------close_window(MultiThrDlg->windowID);SetEvent(MultiThrDlg->containerIsFreeEvent);MultiThrDlg->ipProcTime.SetWindowText("");return;
}

图像采集及处理多线程编程相关推荐

  1. 多线程编程技术开发资料

    多线程编程技术开发资料 目录 Win32 多线程的性能(1)... 1 Win32 多线程的性能(2)... 10 关于多线程的一些细节... 23 用VC++5.0 实 现 多 线 程 的 调 度  ...

  2. C 多线程编程之在类中使用多线程(thread)的方法

    一.thread的基本用法 参见C++使用thread类多线程编程 . 二.类外使用多线程,访问类的成员 这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数. #inc ...

  3. Linux多线程管理: 多线程编程

    多线程编程 mind-Mapping保存有一下导图的xmind文件,可直接获取 互斥变量 互斥对象 ptrhead相关接口 条件变量 future异步访问类 async类 promise类 packa ...

  4. [转]Linux 的多线程编程的高效开发经验

    Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...

  5. Java多线程编程实战:模拟大量数据同步

    背景 最近对于 Java 多线程做了一段时间的学习,笔者一直认为,学习东西就是要应用到实际的业务需求中的.否则要么无法深入理解,要么硬生生地套用技术只是达到炫技的效果. 不过笔者仍旧认为自己对于多线程 ...

  6. 20180829-Java多线程编程

    Java 多线程编程 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分. 程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...

  7. java多线程编程01---------基本概念

    一. java多线程编程基本概念--------基本概念 java多线程可以说是java基础中相对较难的部分,尤其是对于小白,次一系列文章的将会对多线程编程及其原理进行介绍,希望对正在多线程中碰壁的小 ...

  8. 如何实现C++中的多线程编程

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文整理自:知乎用户yikang知乎专栏 Part 1. 基本概念 ...

  9. 多线程编程有什么用途_C++ 多线程编程 (一)

    What is thread? In computer science, a thread of execution is the smallest sequence of programmed in ...

最新文章

  1. 在Vim中有没有一种方法可以在不将文本放入寄存器的情况下删除?
  2. oracle备份归档文件,oracle 如何不备份已经备份的归档
  3. 一个项目部署多个节点会导致锁失效么_Redis分布式锁
  4. LeetCode 1566. 重复至少 K 次且长度为 M 的模式
  5. 飞行器真的是计算机!
  6. 求一个任意实数c的算术平方根g_中考总复习实数知识点
  7. OpenCV4每日一练day13:双目相机校正
  8. POJ3764 字典树
  9. MPAndroidChart的BarChart用法
  10. ubuntu 安装 mujoco-py
  11. 2021 年职业院校技能大赛“网络安全”项目 江西省比赛任务书
  12. matlab数字和字符串转换
  13. BZOJ 3772 精神污染 主席树+欧拉序
  14. 推荐花椒直播服务端的 4 个开源项目
  15. 【题解】【LibreOJ Round #6】花团 LOJ 534 时间线段树分治 背包
  16. CC2640R2F BLE5.0 蓝牙协议栈GATTServApp模块
  17. 在计算机领域中 ascii码,在计算机领域中,ascii码用一个字节来干什么
  18. 登陆拦截页面报错:localhost 将您重定向的次数过多。 尝试清除 Cookie. ERR_TOO_MANY_REDIRECTS
  19. Web前端,CSS中盒子模型的组成,了解掌握盒子模型的边框、内边距、外边距
  20. 极客 android,一款开源的Android极客应用(来一起学习kotlin)

热门文章

  1. 【微信小程序】---- redux 在原生微信小程序的使用实例
  2. 音视频处理 ffmpeg初级开发 命令行工具-实用命令
  3. Python数据分析||基于逻辑回归的糖尿病视网膜病变的影响因素分析
  4. jQuery简单实线钟表并随机钟表数字颜色
  5. ​《Python知识手册》更新到V4.1版
  6. 微信扫码支付---模式一(PC端,解决中文乱码)
  7. ARM汇编指令MRS和MSR
  8. 如何设计出完美的动画技术架构
  9. 六零导航页(LyLme Spage)导航网站源码
  10. vue_music:歌手singer.vue页面