画像処理におけるマルチスレッドの利活用(OpenCV編)

次のエントリではもうちょい具体的なソースコードを書く.かも.といった手前,別のエントリは書けないということで,具体的なコードを書いてみる.

今回のコードはC言語OpenCVを使った例.動作確認はしていないので注意*1.なお,キャプチャ部分はOpenCV.jpのサンプルコードからパクリました.

ちなみにCreateThread(windows.h)を使っているのでWindows専用です.

#include <windows.h>
#include <cv.h>
#include <highgui.h>

// スレッドに渡すデータをまとめた構造体
struct captureparam{
  CvCapture *capture;
  IplImage *temp;
};

// スレッドで実行する処理(画像のキャプチャ)
void capturethread(struct captureparam* cap){
  cap->temp = cvQueryFrame (cap->capture);  
}

int main(int argc, char *argv[]){
  CvCapture *capture=NULL; // キャプチャ用の構造体
  IplImage *temp=NULL;     // 画像(撮影予約用「temp画像」)
  IplImage *img=NULL;      // 画像(実際の処理で使う「画像」)

  // GUIの初期化
  cvInitSystem(argc,argv);
  cvNamedWindow("captured",CV_WINDOW_AUTOSIZE);

  // キャプチャ用構造体の初期化
  capture = cvCreateCameraCapture (0);

  // 1枚目の画像の準備
  temp = cvQueryFrame (capture);
  img=cvCloneImage(temp);
  
  // スレッドに渡すデータの準備
  struct captureparam cap;
  cap->cam=capture;
  cap->temp=temp;
  
  // メインループ
  while((char)cvWaitKey(10)!='q'){
    // “撮影予約”処理.スレッド作成し,ハンドルを保持する
    HANDLE h=CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) capturethread, &cap, 0,NULL);
    
    
    // ここから img を使った時間のかかる画像処理
    // このとき,tempの方をいじってはいけません



   
    cvShowImage("captured",img);
    // ここまで
    
    // 先ほど撮影予約した処理が終わっているか?
    //(撮影が終わるまで待つ)
    WaitForSingleObject(h);
    
    // スレッドはさようなら
    CloseHandle(h);
    
    // 撮影した「temp画像」を処理で使う「画像」へコピー
    cvReleaseImage(&img);
    img=cvCloneImage(temp);
  }

  // いろいろ終了処理
  cvReleaseCapture (&capture);
  cvDestroyWindow("captured");
  cvReleaseImage(&img);
  return 0;
}

追記
画像処理におけるマルチスレッドの利活用(OpenCV編):Linux版を書きました.Linuxユーザはこのpthread版を見てください.

*1:だれか報告してもらえると助かります