2

TBBを使用してOpenCVで記述された画像マッチングコードを並列化しようとしています。問題は、私によると、マッチング(左の画像に5x5ウィンドウを作成し、右のピクセルごとにマッチを探す)は本質的に読み取り専用の操作であり、現在、内側のループを(つまり、指定された高さで)並列化しようとしていることです。異なるピクセルから異なるスレッドへ)。驚いたことに、cvSetImageROIコマンドは並行して実行すると壊れます。これがコードです。

//Code below just carves out a window(5x5) at a current width which is to be matched
cvSetImageROI(leftImageROI, cvRect(curWidth - 2, 0, 5, 5));
IplImage* currentROI = cvCreateImage(cvSize(5, 5), leftImageROI->depth, leftImageROI->nChannels);
cvCopy(leftImageROI, currentROI);                   
cvResetImageROI(leftImageROI);

画像を読み取っているだけなので、これはすべてスレッドセーフに見えますが、コードがクラッシュします。動作しますが、最初にロックをかけると。誰かが助けることができますか?

4

1 に答える 1

7

setImageROI()は読み取り専用操作ではありません。明らかに、それは画像の状態を変えているので。クラッシュしない場合でも、一部のコピー操作は(別のスレッドによって設定された)間違ったROIで動作します。

問題の解決策は、OpenCV C++APIを使用することです。

IplImageの代わりにcv::Matがあります。次に、次のようなコードを使用できます。

// given: cv::Mat image
// returns: cv::Mat dest
cv::Rect roi(curWidth - 2, 0, 5, 5);
cv::Mat local(image, roi);
cv::Mat dest(...);
local.copyTo(dest);

では、なぜこれがスレッドセーフなのですか?もちろん、元の画像の状態は変更されません。代わりに、ROIは新しいスレッドローカルマトリックスヘッダーに書き込まれます。

于 2011-04-06T09:59:37.047 に答える