图像采集及处理多线程编程

来源:互联网 发布:js获取fileupload路径 编辑:程序博客网 时间:2024/05/17 08:20

本文介绍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(NULL0,                 (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);        // CriticalSect    SetEvent(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);      // CriticalSect    image =  (MultiThrDlg->imgList).front();        MultiThrDlg->imgList.pop_front();       LeaveCriticalSection(&MultiThrDlg->newImageMutex);        // CriticalSect    count_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);      // CriticalSect    rData = MultiThrDlg->resultData;                          // CriticalSect    LeaveCriticalSection(&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;}
原创粉丝点击