###前提・実現したいこと
VisualStudioでOpenCVを用いて、動画の各フレーム対して画像処理を行い、その結果を表示するwindowsフォームアプリケーションを作成しようとしています。
画像処理部をマルチスレッドにて実装したのですが、デバッグ中にフォームの位置を動かそうとした際に以下の問題が発生しました。
###発生している問題・エラーメッセージ
型 'System.AccessViolationException' の例外が System.Drawing.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした 追加情報: 保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。 この例外のハンドラーがある場合は、プログラムを安全に続行できます。
そのまま無理やりデバックを続行させるとFormのShowDialog()で
型 'System.Reflection.TargetInvocationException' のハンドルされていない例外が mscorlib.dll で発生しました 追加情報: 呼び出しのターゲットが例外をスローしました。
が出力されます
###該当のソースコード
C++
1//メインスレッド 2 private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { 3 button3->Enabled = false; 4 Thread^ t = gcnew Thread(gcnew ThreadStart(this, &MyForm::ImageProc)); 5 t->IsBackground = true; 6 t->Start(); 7 } 8//サブスレッド 9 private: System::Void ImageProc(){ 10 cv::Mat image; 11 cv::VideoCapture cap("movie.avi"); 12 if (!cap.isOpened()) { 13 return; 14 } 15 while (true){ 16 cap >> image; 17 if (image.empty()) { 18 break; 19 } 20 21 cvtColor(img, img, CV_BGR2GRAY); 22 23 /* 24 実際の処理 25 */ 26 27 cvtColor(img, img, CV_GRAY2BGR); 28 29 IntPtr ip(imgBGR.ptr()); //Mat画像バッファをintポインタに変換 30 Bitmap^ bmp; 31 bmp = gcnew Bitmap(image.cols, image.rows, image.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, ip); 32 33 BeginInvoke( 34 gcnew updateImageDelegate(this, &MyForm::UpdateImage), 35 bmp, image.cols, image.rows); 36 Sleep(10); 37 } 38 } 39 40 private: delegate System::Void updateImageDelegate(Bitmap^ bmp, int cols, int rows); 41 //画像の更新 42 private: System::Void UpdateImage(Bitmap^ bmp, int cols, int rows){ 43 Graphics^ gp = pictureBox1->CreateGraphics(); //グラフィックオブジェクト作成 44 gp->DrawImage(bmp, 0, 0, cols / 2, rows / 2); 45 //delete gp; 46 } 47
###確認していること
問題が発生した際の現在の関数は gp->DrawImage(bmp, 0, 0, cols / 2, rows / 2);
問題が発生するのはフォーム移動、最小化、ボタン操作、他のボタン操作により作成されたウィンドウを閉じる操作
上記操作をしても問題が発生するタイミングとしないタイミングがある
UpdateImageを
private: System::Void UpdateImage(Bitmap^ bmp, int cols, int rows){ Graphics^ gp = pictureBox1->CreateGraphics(); //グラフィックオブジェクト作成 gp->DrawImage(bmp, 0, 0, cols / 2, rows / 2); Sleep(100); }
に書き換えると2~3フレーム目でフォーム操作をしなくても問題が発生。Sleep(10)だと発生しないが、Sleepさせない時よりフォーム操作等により問題が発生する確率は上がっていると感じた。
以上からgp->DrawImageを実行中にイベントを引き起こすと発生するようなのですが、どのように変更したら良いのかわかりません。ご教授お願い致します。
###補足情報(言語/FW/ツール等のバージョンなど)
Microsoft Visual Studio Express 2013 for Windows Desktop
OpenCV 2.4.13

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/18 02:18