「OpenCVDebug日記」の編集履歴(バックアップ)一覧はこちら
「OpenCVDebug日記」(2008/10/15 (水) 12:44:08) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
#contents
*"cv099.dllがない"と言われて動かない
1.原因
OpenCVのバージョン変更をプログラムが理解していない。
2.解決方法
(1)リンカの中間ファイルの削除
タスクバー→ビルト→ソリューションのリビルド
で中間ファイルを削除しプロジェクト全体をリビルドする。
(2)開発環境の再設定
開発環境を再起動させる。
*cvReleaseImageHeaderが誤動作する
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Unknown error code -49 (Deallocation error)
in function cvFree_, C:\User\VP\opencv\cxcore\src\cxalloc.cpp(129)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.現象
Bumblebee2を使った連続処理(廊下・障害物検出)において
cvReleaseImageHeader( &DispImageH81D );
cvReleaseImageHeader( &iplDispImage );
と二つ関数が並んでいた時、デバック中上のcvReleaseImageHeader( &DispImageH81D );が動作すると下の&iplDispImageの中身がおかしくなる。で、その式を動作させると上記のエラーメッセージが出てくる。
&DispImageH81Dと&iplDispImageの順序を上下逆にすると下になったIplImageHeaderの値がおかしくなる。
3.原因
このプログラムは前回メモリリークによる連続処理の中断というバグを潰していた。その時点では問題なく動作していたのでそのあと“いらない部分”の削除を行った。その時必要な部分も削除してしまったと思われる。
4.対策
動くバージョンと動かないバージョンを見比べて必要と思われる部分の洗い出しを行う。
5.解決策
cvReleaseImageHeader( &DispImageH81D );、cvReleaseImageHeader( &iplDispImage );の二つをコメントアウトした。
動くバージョンでは画像の解放はほとんど行っていなかったが長時間の連続動作にも耐えられた。
ImageHeaderの解放は以前からうまくいっていなかったので今後も注意する必要がある。
*メモリが "written" にならない
1.エラーメッセージ
---------------------------
PTracker.exe - アプリケーション エラー
---------------------------
"0x77bdb9b5" の命令が "0x7f7d7e81" のメモリを参照しました。メモリが "written" になることはできませんでした。
プログラムを終了するには [OK] をクリックしてください
プログラムをデバッグするには [キャンセル] をクリックしてください
---------------------------
OK キャンセル
---------------------------
2.現象
Bumblebee2を使った連続処理(廊下・障害物検出)において2フレームほど経過すると上記のエラーが発生し処理が止まる。デバッグモードにならない。"0x77bdb9b5" や "0x7f7d7e81"と言われてもどこだか分らない。
3.原因:不明
4.解決方法
直前の変更点である
IplImage *planes[2];
planes[0] = h_plane = cvCreateImage (cvGetSize (src), 8, 1);
planes[1] = s_plane = cvCreateImage (cvGetSize (src), 8, 1);
cvReleaseImage (&planes[0]);// 解放するとメモリが読み込めなくなる
cvReleaseImage (&planes[1]);
のcvReleaseImageをコメントアウトした。マジでわけわからん。教訓が得られそうにないのがなおさらキツイ。
*cvCompareHistがBad argument になる
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Bad argument (Invalid histogram header[s])
in function cvCompareHist, C:\User\VP\opencv\cv\src\cvhistogram.cpp(414)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.現象
Bumblebee2を使った連続処理(廊下・障害物検出)において
(1)プログラム自体は動作するがカメラを動かしたりすると(画面が激しく変化すると?)上記のエラーが出て処理が止まる。
(2)デバッグするとcvCompareHistを使っている関数などが指定される(結果的にはこれはあまり意味がなかった)
(3)ただしデバッグごとにcvCalcArrHist以外の部分(「ソースコードを表示できない」と言われたこともある)が指定されたりと症状が一定しなかった。
(3)必ず特定のフレームで処理が終わった。一回の処理は通るのでデバッグモードでは解決できないタイプだった。
3.原因・解決方法
メモリの解放忘れ。
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines= 0;
でCV関連の構造体を定義していたが
cvClearSeq(lines);
cvReleaseMemStorage(&storage);
の解放を忘れていた。
4.まとめ・教訓
(1)1,2回なら処理が通っている点
(2)42フレームまで処理し43フレーム目で必ず止まる点
(3)HoughImageをcvReleaseImageしたら処理可能フレーム数が128まで増えた点
以上の点から"定義した何か"の解放忘れであることは予想できたはず。今回はエラーメッセージにこだわりすぎてcvCompareHist関連ばかり調べていたせいで解決が遅れた。現象そのものをもっとよく吟味するべきであった。
10.Link
[[MemStrageやSeqの解放について>http://www.eml.ele.cst.nihon-u.ac.jp/~momma/wiki/wiki.cgi/OpenCV/%E7%9B%B4%E7%B7%9A%E3%81%AE%E3%83%95%E3%82%A3%E3%83%83%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0.html]]
[[OpenCVの Bad argument について>http://opencv.jp/document/opencvref_cxcore.html]]
[[OpenCV の cvCompareHist について>http://opencv.jp/opencv/document/opencvref_cv_histograms.html#decl_cvCompareHist]]
[[Wikipedia「メモリリーク」>http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF]]
[[Wikipedia「動的メモリ確保」>http://ja.wikipedia.org/wiki/%E5%8B%95%E7%9A%84%E3%83%A1%E3%83%A2%E3%83%AA%E7%A2%BA%E4%BF%9D]]
[[c++プログラムメモリリークについて>http://www.ipa.go.jp/security/awareness/vendor/programming/b06_05_main.html]]
*画像処理を画像の下半分に限定したい場合
※元画像のサイズ:320×240とする
1.CvRectを定義
CvRect rect1;
rect1.x = 0;
rect1.y = 120;
rect1.width = 320;
rect1.height = 120;
2.ROI使用
cvSetImageROI( 入力画像 , rect1 );
3.何らかの処理
lines = cvHoughLines2( 入力画像 , storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 80, 0, 0 );
*画像変換まとめ
1.チャンネル変換
cvCvtColot使用。1ch⇔3ch , 4ch→3ch , Header→Image の変換を確認。
2.Header→Image 変換
cvCvtColot使用
3.Image→Header変換、Header→Header変換
(1)HeaderA = HeaderB;で直接代入。
(2)HeaderA = cvCloneImage( HeaderB );で変換
4.cvCopyはImageどうしでないと使えない。cvCopy( HeaderA , HeaderB );はできない。
*#include "ipl.h" の前に #include "cv.h" を入れるとどうなるか
1.現象
error C2011: '_IplImage' : 'struct' 型の再定義
error C2143: 構文エラー : '}' が '定数' の前にありません。
など ipl.h 関係のエラーがたくさん出る。他にも highgui.h , cvaux.h などのエラーも出た。
*IplImageのチャンネル数を変える
1.目的
使用するIplImageが4チャンネルでは顔検出が使えないので3チャンネルに減らしたい。
2.方法〔cvCvtColorを使う〕
※RecordImage内でgrabImageThreadはまだ始まっていない場合
// 画像データ取得
GrabImage();
cvSetImageData( ColorImage4ch, triColorImage.data, ColorImage4ch->widthStep );
// ColorImageへ3チャンネル化
cvCvtColor( ColorImage4ch, ColorImageHsv, CV_BGR2HSV );//CV_BGR2BGRが使えないのでとりあえずHSV(3チャンネル)へ変換
cvCvtColor( ColorImageHsv, ColorImage, CV_HSV2BGR );//改めてBGR(3チャンネル)へ変換
3.注意点
grabImageThread( LPVOID lpParameter )内でも同様の処理が必要
// 画像データ取得
GrabImage();
// ColorImageへ3チャンネル化
cvCvtColor( ColorImage4ch, ColorImageHsv, CV_BGR2HSV );//CV_BGR2BGRが使えないのでとりあえずHSV(3チャンネル)へ変換
cvCvtColor( ColorImageHsv, ColorImage, CV_HSV2BGR );//改めてBGR(3チャンネル)へ変換
ただし、cvSetImageData( ColorImage4ch, triColorImage.data, ColorImage4ch->widthStep );は元から書かれていない。なぜ?結局どうやってflyCaputureや triclops からIplImage へ変換しているのか謎は残る。GrabImage で全て済ませるとは思えないんだが…cvSetImageData( ColorImage4ch, triColorImage.data, ColorImage4ch->widthStep );がなぜない?
*Median filterが使えない
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Unsupported format or combination of formats (Median filter only supports 8uC1, 8uC3 and 8uC4 images)
in function cvSmooth, C:\User\VP\opencv\cv\src\cvsmooth.cpp(1092)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.原因
エラーメッセージの通り、8ビット1~4チャンネルの画像しか使えない。
3.解決方法
16ビットの視差画像の雑音を除去したかったのだが、諦める…か。
*ラべリングが遅い
0.注意
平面検出の「PSF遅すぎ」の項で別の原因について言及しているので参照すること。
1.現象
1500ms以上の処理時間がかかっている。
2.原因
cvGetReal2D( 入力画像, y, x );
cvSet2D( 入力画像, y, x, cvScalarAll( 255.0 ) );
のOpenCVを使った画像のピクセルへのアクセスは低速で連続処理への使用は推奨されない。
3.解決方法
ピクセル値の取得
cvGetReal2D( 入力画像, y, x );
↓
pixl = (unsigned char)入力画像->imageData[y * 入力画像->widthStep + x];
ピクセルへの値格納
cvSet2D( label_dst, y, x, cvScalarAll( 255.0 ) );
↓
出力画像->imageData[y * 出力画像->widthStep + x] = (char)値L;
4.Link
http://opencv.jp/sample/basic_structures.html
*cvAndが使えない
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Formats of input arguments do not match ()
in function icvLogic, C:\User\VP\opencv\cxcore\src\cxlogic.cpp(415)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.現象
コンパイルは通るが実行するとエラーメッセージが出て処理が終わる。めんどいタイプ。cvAndをコメントアウトすると動作する。
3.原因
cvAnd( 入力画像1 , 入力画像2 , 出力画像[マスク] , NULL )
で入力画像1と入力画像2のチャンネル数が違った。
4.解決方法
入力画像1と入力画像2のチャンネル数を合わせる。それだけ。
*cvHaarDetectObjectsが使えない
1.症状
コンパイルは通るが実行するとエラーメッセージが出て処理が終わる。めんどいタイプ。cvHaarDetectObjectsをコメントアウトすると動作する。
2.原因
faces = cvHaarDetectObjects (src_gray, cascade, storage, 1.11, 4, 0, cvSize (40, 40));
の2番目の引数cascadeが入っていないため発生した。
const char *cascade_name = "haarcascade_frontalface_default.xml";
でOpenCV備え付けのファイルを使用しようとしていたがこれではできない模様。
3.解決方法
const char *cascade_name = "C:/Program Files/OpenCV/data/haarcascades/"haarcascade_frontalface_default.xml";
こんな感じでフルパス入れたらできた。パスが¥(えん)マークでなく/(すらっしゅ)で区切ってあることに注意。
もしくは作業しているディレクトリに"haarcascade_frontalface_default.xmlを探して直接コピペする方法でも解決できた。
4.補足(cvHaarDetectObjectsで読み込むXMLファイルについて)
haarcascade_frontalface_default.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
の三種類で顔を検出可能なことを確認。微妙に検出精度が違う。色々試してみるべし。
*cvSaveImageが使えない3
1.error messege
---------------------------
OpenCV GUI Error Handler
---------------------------
Unspecified error (could not save the image)
in function cvSaveImage, C:\~~\opencv\otherlibs\highgui\loadsave.cpp
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
--------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
1.5.現象
cvSaveImageで画像を保存する際、Flag.hファイルで画像ファイルに名前を加えようとすると上記のエラーメッセージが出る。
2.原因→不明w
3.解決方法
色々な言葉を入れていたら直った。原因、原理一切不明。
*cvSaveImageが使えない2
1.エラーメッセージ(現象)
---------------------------
OpenCV GUI Error Handler
---------------------------
Unspecified error (could not find a filter for the specified extension)
in function cvSaveImage, C:\~~~~~~
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
例によってビルドでは拾われないタイプ。
2.原因
保存するファイル形式はファイル名につける拡張子によって決まる。ここでサポートされている拡張子を正しく指定しなかったため。
今回のプログラムでは入力画像を[.sift]という特殊な拡張子を用いて区別していたが保存時もその名前をそのまま使用していた。
3.解決策
保存用のファイル名を指定する。
4.Link
http://co-coa.sakura.ne.jp/index.php?OpenCV%2FReference
*cvSaveImageが使えない
1.症状
カメラから取得した視差画像をcvSaveImageで保存すると画面で見たものとは異なる画像が保存される。
2.原因
OpenCVの仕様でcvSaveImageで保存できるのは,8 ビット 1チャンネル,あるいは 8 ビット3 チャンネル('BGR' の順)画像だけであるらしい。視差画像は16ビットであった。
3.解決策
データの「16ビット表現」から「8ビット表現」への「スケール変換」は「cvConvert関数」を用いるらしい。
4.Link
http://opencv.jp/document/opencvref_highgui.html
http://wiki.livedoor.jp/mikk_ni3_92/d/%A5%A8%A5%C3%A5%B8%B8%A1%BD%D02
http://opencv.jp/opencv/document/opencvref_cxcore_arithmetic.html#decl_cvConvertScale
*cvConvertScaleが使えない
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Null pointer (The image has NULL data pointer)
in function cvGetMat, C:\User\VP\opencv\cxcore\src\cxarray.cpp(2794)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.症状
コンパイルは通るが実行すると上記のエラーメッセージが出て処理が終わる。めんどいタイプ。cvConvertScaleをコメントアウトすると動作する。
3.原因
cvConvertScaleはImageHeaderでは使えない。
引数に用いる画像の定義ミスだった。
cvConvertScaleは引数に(入力画像,出力画像)を入れるが、この画像を両方ImaggeHeaderとして定義してしまっていた。
4.解決策
結果を出力する出力画像はImageとして定義を書き換えた。
ImageHeaderで定義されている視差画像をImage化する方法は調査中。
*cvConvertScaleが使えない2
1.やりたかったこと
16ビット→8ビット画像への変換。(16bit→8bit変換)
16ビット(65536階調)の画像を8ビット(256階調)画像に変換したい。
cvSaveImageでは16ビットの画像を保存できないから。
2.症状
コンパイル、実行は可能だが結果画像が白色(255)になってしまう。
3.原因
cvCvtScale( 入力画像 , 出力画像 ); // 入力画像 = 16bit , 出力画像 = 8bit
上の形では変換されない。
cvCvtScale( 入力画像 , 出力画像 , scale, shift );
cvCvtScaleは本来上記の形である。
デフォルトはscale = 1 , shift = 0 なので何も書かないと16bitの値(65536階調)の値がそのまま8bitの画像に入ってしまう。
4.解決策
cvCvtScale( 入力画像 , 出力画像 , 0.00390625 , 0 );
※0.00390625 = 1/256 = 1/2^16*2^8 の意味
5.まとめ(反省点)
scale, shiftの存在は早くから知っていたので適当な値を入れて試してみれば解決は早かったかもしれない。調査の優先順位の付け方に経験が足りなかった。
6.Link
http://opencv.jp/opencv/document/opencvref_cxcore_arithmetic.html
http://tessy.org/wiki/index.php?%B9%D4%CE%F3%A4%C8%B2%E8%C1%FC%A4%CE%CA%D1%B4%B9#ded1b6b1
http://www.vrac.iastate.edu/575x/S07/doku.php?id=foo:homework:hw3
http://code.google.com/p/eyepatch/source/diff?r=97&format=side&path=/trunk/MotionClassifier.cpp
*cvCopyが使えない3
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Null pointer (The image has NULL data pointer)
in function cvGetMat, C:\User\VP\opencv\cxcore\src\cxarray.cpp(2794)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.原因
cvCopyはcvCopy( Header , Header );はできない。
3.解決方法
(1)HeaderA = HeaderB;で直接代入する。
(2)HeaderA = cvCloneImage( HeaderB );で変換
*cvCopyが使えない2
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Formats of input arguments do not match ()
in function cvCopy, C:\User\VP\opencv\cxcore\src\cxcopy.cpp(415)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
または
---------------------------
PTracker.exe - アプリケーション エラー
---------------------------
例外 unknown software exception (0x80000003) がアプリケーションの 0x060612c6 で発生しました。
プログラムを終了するには [OK] をクリックしてください
プログラムをデバッグするには [キャンセル] をクリックしてください
---------------------------
OK キャンセル
---------------------------
2.原因
コピー元配列とコピー先配列は,同じ型,同じ次元,同じサイズでなければならない。IplImageのチャンネル数が違っていた。
3.解決方法
cvCopyで使用する入出力Imageの定義を調べる。
(1)デバッグを使用
(2)Imageを指定
(3)channelを確認
(4)変更
ただしデバッグでcvCopyの部分を表示しない場合もある。今後は怪しいIplImageを特定して[ cvCopy( ~~IplImage ]で検索かけた方がいいかも。
*cvCopyが使えない
1.症状
コンパイルは通るが実行するとエラーメッセージが出て処理が終わる。
2.原因
コピー元配列とコピー先配列は,同じ型,同じ次元,同じサイズでなければならない。ImageHeaderをImageにコピーしようとしていた。
3.解決
ImageHeader→Image変換
*IplImageの開放について
Webカメラから直接取得するために使用したIplImageはcvReleaseImage( &captureImage )などで開放する必要はない。
なぜならcvCreateImageなどでIplImageの領域確保を行ってないため。
*ImageHeaderとは?
1.概要
要するに
CreateImage : ヘッダの作成とデータ領域の確保
CreateImageHeade : メモリ確保と初期化を行い,IplImage 構造体を返す
の似たような動作をする二つの関数が存在して違いがわからん。
2.予想
Image ∋ ImageHeader
の関係か?調査続行
3.Link
http://opencv.jp/opencv/document/opencvref_cxcore_init.html
*MiniBeeで画像のレクティファイが出来ない(調査中)
#comment_num2
#contents
*"cv099.dllがない"と言われて動かない
1.原因
OpenCVのバージョン変更をプログラムが理解していない。
2.解決方法
(1)リンカの中間ファイルの削除
タスクバー→ビルト→ソリューションのリビルド
で中間ファイルを削除しプロジェクト全体をリビルドする。
(2)開発環境の再設定
開発環境を再起動させる。
*cvReleaseImageHeaderが誤動作する
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Unknown error code -49 (Deallocation error)
in function cvFree_, C:\User\VP\opencv\cxcore\src\cxalloc.cpp(129)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.現象
Bumblebee2を使った連続処理(廊下・障害物検出)において
cvReleaseImageHeader( &DispImageH81D );
cvReleaseImageHeader( &iplDispImage );
と二つ関数が並んでいた時、デバック中上のcvReleaseImageHeader( &DispImageH81D );が動作すると下の&iplDispImageの中身がおかしくなる。で、その式を動作させると上記のエラーメッセージが出てくる。
&DispImageH81Dと&iplDispImageの順序を上下逆にすると下になったIplImageHeaderの値がおかしくなる。
3.原因
このプログラムは前回メモリリークによる連続処理の中断というバグを潰していた。その時点では問題なく動作していたのでそのあと“いらない部分”の削除を行った。その時必要な部分も削除してしまったと思われる。
4.対策
動くバージョンと動かないバージョンを見比べて必要と思われる部分の洗い出しを行う。
5.解決策
cvReleaseImageHeader( &DispImageH81D );、cvReleaseImageHeader( &iplDispImage );の二つをコメントアウトした。
動くバージョンでは画像の解放はほとんど行っていなかったが長時間の連続動作にも耐えられた。
ImageHeaderの解放は以前からうまくいっていなかったので今後も注意する必要がある。
*メモリが "written" にならない
1.エラーメッセージ
---------------------------
PTracker.exe - アプリケーション エラー
---------------------------
"0x77bdb9b5" の命令が "0x7f7d7e81" のメモリを参照しました。メモリが "written" になることはできませんでした。
プログラムを終了するには [OK] をクリックしてください
プログラムをデバッグするには [キャンセル] をクリックしてください
---------------------------
OK キャンセル
---------------------------
2.現象
Bumblebee2を使った連続処理(廊下・障害物検出)において2フレームほど経過すると上記のエラーが発生し処理が止まる。デバッグモードにならない。"0x77bdb9b5" や "0x7f7d7e81"と言われてもどこだか分らない。
3.原因:不明
4.解決方法
直前の変更点である
IplImage *planes[2];
planes[0] = h_plane = cvCreateImage (cvGetSize (src), 8, 1);
planes[1] = s_plane = cvCreateImage (cvGetSize (src), 8, 1);
cvReleaseImage (&planes[0]);// 解放するとメモリが読み込めなくなる
cvReleaseImage (&planes[1]);
のcvReleaseImageをコメントアウトした。マジでわけわからん。教訓が得られそうにないのがなおさらキツイ。
*cvCompareHistがBad argument になる
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Bad argument (Invalid histogram header[s])
in function cvCompareHist, C:\User\VP\opencv\cv\src\cvhistogram.cpp(414)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.現象
Bumblebee2を使った連続処理(廊下・障害物検出)において
(1)プログラム自体は動作するがカメラを動かしたりすると(画面が激しく変化すると?)上記のエラーが出て処理が止まる。
(2)デバッグするとcvCompareHistを使っている関数などが指定される(結果的にはこれはあまり意味がなかった)
(3)ただしデバッグごとにcvCalcArrHist以外の部分(「ソースコードを表示できない」と言われたこともある)が指定されたりと症状が一定しなかった。
(3)必ず特定のフレームで処理が終わった。一回の処理は通るのでデバッグモードでは解決できないタイプだった。
3.原因・解決方法
メモリの解放忘れ。
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines= 0;
でCV関連の構造体を定義していたが
cvClearSeq(lines);
cvReleaseMemStorage(&storage);
の解放を忘れていた。
4.まとめ・教訓
(1)1,2回なら処理が通っている点
(2)42フレームまで処理し43フレーム目で必ず止まる点
(3)HoughImageをcvReleaseImageしたら処理可能フレーム数が128まで増えた点
以上の点から"定義した何か"の解放忘れであることは予想できたはず。今回はエラーメッセージにこだわりすぎてcvCompareHist関連ばかり調べていたせいで解決が遅れた。現象そのものをもっとよく吟味するべきであった。
10.Link
[[MemStrageやSeqの解放について>http://www.eml.ele.cst.nihon-u.ac.jp/~momma/wiki/wiki.cgi/OpenCV/%E7%9B%B4%E7%B7%9A%E3%81%AE%E3%83%95%E3%82%A3%E3%83%83%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0.html]]
[[OpenCVの Bad argument について>http://opencv.jp/document/opencvref_cxcore.html]]
[[OpenCV の cvCompareHist について>http://opencv.jp/opencv/document/opencvref_cv_histograms.html#decl_cvCompareHist]]
[[Wikipedia「メモリリーク」>http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF]]
[[Wikipedia「動的メモリ確保」>http://ja.wikipedia.org/wiki/%E5%8B%95%E7%9A%84%E3%83%A1%E3%83%A2%E3%83%AA%E7%A2%BA%E4%BF%9D]]
[[c++プログラムメモリリークについて>http://www.ipa.go.jp/security/awareness/vendor/programming/b06_05_main.html]]
*画像処理を画像の下半分に限定したい場合
※元画像のサイズ:320×240とする
1.CvRectを定義
CvRect rect1;
rect1.x = 0;
rect1.y = 120;
rect1.width = 320;
rect1.height = 120;
2.ROI使用
cvSetImageROI( 入力画像 , rect1 );
3.何らかの処理
lines = cvHoughLines2( 入力画像 , storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 80, 0, 0 );
*画像変換まとめ
1.チャンネル変換
cvCvtColot使用。1ch⇔3ch , 4ch→3ch , Header→Image の変換を確認。
2.Header→Image 変換
cvCvtColot使用
3.Image→Header変換、Header→Header変換
(1)HeaderA = HeaderB;で直接代入。
(2)HeaderA = cvCloneImage( HeaderB );で変換
4.cvCopyはImageどうしでないと使えない。cvCopy( HeaderA , HeaderB );はできない。
*#include "ipl.h" の前に #include "cv.h" を入れるとどうなるか
1.現象
error C2011: '_IplImage' : 'struct' 型の再定義
error C2143: 構文エラー : '}' が '定数' の前にありません。
など ipl.h 関係のエラーがたくさん出る。他にも highgui.h , cvaux.h などのエラーも出た。
*IplImageのチャンネル数を変える
1.目的
使用するIplImageが4チャンネルでは顔検出が使えないので3チャンネルに減らしたい。
2.方法〔cvCvtColorを使う〕
※RecordImage内でgrabImageThreadはまだ始まっていない場合
// 画像データ取得
GrabImage();
cvSetImageData( ColorImage4ch, triColorImage.data, ColorImage4ch->widthStep );
// ColorImageへ3チャンネル化
cvCvtColor( ColorImage4ch, ColorImageHsv, CV_BGR2HSV );//CV_BGR2BGRが使えないのでとりあえずHSV(3チャンネル)へ変換
cvCvtColor( ColorImageHsv, ColorImage, CV_HSV2BGR );//改めてBGR(3チャンネル)へ変換
3.注意点
grabImageThread( LPVOID lpParameter )内でも同様の処理が必要
// 画像データ取得
GrabImage();
// ColorImageへ3チャンネル化
cvCvtColor( ColorImage4ch, ColorImageHsv, CV_BGR2HSV );//CV_BGR2BGRが使えないのでとりあえずHSV(3チャンネル)へ変換
cvCvtColor( ColorImageHsv, ColorImage, CV_HSV2BGR );//改めてBGR(3チャンネル)へ変換
ただし、cvSetImageData( ColorImage4ch, triColorImage.data, ColorImage4ch->widthStep );は元から書かれていない。なぜ?結局どうやってflyCaputureや triclops からIplImage へ変換しているのか謎は残る。GrabImage で全て済ませるとは思えないんだが…cvSetImageData( ColorImage4ch, triColorImage.data, ColorImage4ch->widthStep );がなぜない?
*Median filterが使えない
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Unsupported format or combination of formats (Median filter only supports 8uC1, 8uC3 and 8uC4 images)
in function cvSmooth, C:\User\VP\opencv\cv\src\cvsmooth.cpp(1092)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.原因
エラーメッセージの通り、8ビット1~4チャンネルの画像しか使えない。
3.解決方法
16ビットの視差画像の雑音を除去したかったのだが、諦める…か。
*ラべリングが遅い
0.注意
平面検出の「PSF遅すぎ」の項で別の原因について言及しているので参照すること。
1.現象
1500ms以上の処理時間がかかっている。
2.原因
cvGetReal2D( 入力画像, y, x );
cvSet2D( 入力画像, y, x, cvScalarAll( 255.0 ) );
のOpenCVを使った画像のピクセルへのアクセスは低速で連続処理への使用は推奨されない。
3.解決方法
ピクセル値の取得
cvGetReal2D( 入力画像, y, x );
↓
pixl = (unsigned char)入力画像->imageData[y * 入力画像->widthStep + x];
ピクセルへの値格納
cvSet2D( label_dst, y, x, cvScalarAll( 255.0 ) );
↓
出力画像->imageData[y * 出力画像->widthStep + x] = (char)値L;
4.Link
http://opencv.jp/sample/basic_structures.html
*cvAndが使えない
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Formats of input arguments do not match ()
in function icvLogic, C:\User\VP\opencv\cxcore\src\cxlogic.cpp(415)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.現象
コンパイルは通るが実行するとエラーメッセージが出て処理が終わる。めんどいタイプ。cvAndをコメントアウトすると動作する。
3.原因
cvAnd( 入力画像1 , 入力画像2 , 出力画像[マスク] , NULL )
で入力画像1と入力画像2のチャンネル数が違った。
4.解決方法
入力画像1と入力画像2のチャンネル数を合わせる。それだけ。
*cvHaarDetectObjectsが使えない
1.症状
コンパイルは通るが実行するとエラーメッセージが出て処理が終わる。めんどいタイプ。cvHaarDetectObjectsをコメントアウトすると動作する。
2.原因
faces = cvHaarDetectObjects (src_gray, cascade, storage, 1.11, 4, 0, cvSize (40, 40));
の2番目の引数cascadeが入っていないため発生した。
const char *cascade_name = "haarcascade_frontalface_default.xml";
でOpenCV備え付けのファイルを使用しようとしていたがこれではできない模様。
3.解決方法
const char *cascade_name = "C:/Program Files/OpenCV/data/haarcascades/"haarcascade_frontalface_default.xml";
こんな感じでフルパス入れたらできた。パスが¥(えん)マークでなく/(すらっしゅ)で区切ってあることに注意。
もしくは作業しているディレクトリに"haarcascade_frontalface_default.xmlを探して直接コピペする方法でも解決できた。
4.補足(cvHaarDetectObjectsで読み込むXMLファイルについて)
haarcascade_frontalface_default.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
の三種類で顔を検出可能なことを確認。微妙に検出精度が違う。色々試してみるべし。
*cvSaveImageが使えない3
1.error messege
---------------------------
OpenCV GUI Error Handler
---------------------------
Unspecified error (could not save the image)
in function cvSaveImage, C:\~~\opencv\otherlibs\highgui\loadsave.cpp
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
--------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
1.5.現象
cvSaveImageで画像を保存する際、Flag.hファイルで画像ファイルに名前を加えようとすると上記のエラーメッセージが出る。
2.原因→不明w
3.解決方法
色々な言葉を入れていたら直った。原因、原理一切不明。
*cvSaveImageが使えない2
1.エラーメッセージ(現象)
---------------------------
OpenCV GUI Error Handler
---------------------------
Unspecified error (could not find a filter for the specified extension)
in function cvSaveImage, C:\~~~~~~
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
例によってビルドでは拾われないタイプ。
2.原因
保存するファイル形式はファイル名につける拡張子によって決まる。ここでサポートされている拡張子を正しく指定しなかったため。
今回のプログラムでは入力画像を[.sift]という特殊な拡張子を用いて区別していたが保存時もその名前をそのまま使用していた。
3.解決策
保存用のファイル名を指定する。
4.Link
http://co-coa.sakura.ne.jp/index.php?OpenCV%2FReference
*cvSaveImageが使えない
1.症状
カメラから取得した視差画像をcvSaveImageで保存すると画面で見たものとは異なる画像が保存される。
2.原因
OpenCVの仕様でcvSaveImageで保存できるのは,8 ビット 1チャンネル,あるいは 8 ビット3 チャンネル('BGR' の順)画像だけであるらしい。視差画像は16ビットであった。
3.解決策
データの「16ビット表現」から「8ビット表現」への「スケール変換」は「cvConvert関数」を用いるらしい。
4.Link
http://opencv.jp/document/opencvref_highgui.html
http://wiki.livedoor.jp/mikk_ni3_92/d/%A5%A8%A5%C3%A5%B8%B8%A1%BD%D02
http://opencv.jp/opencv/document/opencvref_cxcore_arithmetic.html#decl_cvConvertScale
*cvConvertScaleが使えない
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Null pointer (The image has NULL data pointer)
in function cvGetMat, C:\User\VP\opencv\cxcore\src\cxarray.cpp(2794)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.症状
コンパイルは通るが実行すると上記のエラーメッセージが出て処理が終わる。めんどいタイプ。cvConvertScaleをコメントアウトすると動作する。
3.原因
cvConvertScaleはImageHeaderでは使えない。
引数に用いる画像の定義ミスだった。
cvConvertScaleは引数に(入力画像,出力画像)を入れるが、この画像を両方ImaggeHeaderとして定義してしまっていた。
4.解決策
結果を出力する出力画像はImageとして定義を書き換えた。
ImageHeaderで定義されている視差画像をImage化する方法は調査中。
*cvConvertScaleが使えない2
1.やりたかったこと
16ビット→8ビット画像への変換。(16bit→8bit変換)
16ビット(65536階調)の画像を8ビット(256階調)画像に変換したい。
cvSaveImageでは16ビットの画像を保存できないから。
2.症状
コンパイル、実行は可能だが結果画像が白色(255)になってしまう。
3.原因
cvCvtScale( 入力画像 , 出力画像 ); // 入力画像 = 16bit , 出力画像 = 8bit
上の形では変換されない。
cvCvtScale( 入力画像 , 出力画像 , scale, shift );
cvCvtScaleは本来上記の形である。
デフォルトはscale = 1 , shift = 0 なので何も書かないと16bitの値(65536階調)の値がそのまま8bitの画像に入ってしまう。
4.解決策
cvCvtScale( 入力画像 , 出力画像 , 0.00390625 , 0 );
※0.00390625 = 1/256 = 1/2^16*2^8 の意味
5.まとめ(反省点)
scale, shiftの存在は早くから知っていたので適当な値を入れて試してみれば解決は早かったかもしれない。調査の優先順位の付け方に経験が足りなかった。
6.Link
http://opencv.jp/opencv/document/opencvref_cxcore_arithmetic.html
http://tessy.org/wiki/index.php?%B9%D4%CE%F3%A4%C8%B2%E8%C1%FC%A4%CE%CA%D1%B4%B9#ded1b6b1
http://www.vrac.iastate.edu/575x/S07/doku.php?id=foo:homework:hw3
http://code.google.com/p/eyepatch/source/diff?r=97&format=side&path=/trunk/MotionClassifier.cpp
*cvCopyが使えない3
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Null pointer (The image has NULL data pointer)
in function cvGetMat, C:\User\VP\opencv\cxcore\src\cxarray.cpp(2794)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
2.原因
cvCopyはcvCopy( Header , Header );はできない。
3.解決方法
(1)HeaderA = HeaderB;で直接代入する。
(2)HeaderA = cvCloneImage( HeaderB );で変換
*cvCopyが使えない2
1.エラーメッセージ
---------------------------
OpenCV GUI Error Handler
---------------------------
Formats of input arguments do not match ()
in function cvCopy, C:\User\VP\opencv\cxcore\src\cxcopy.cpp(415)
Press "Abort" to terminate application.
Press "Retry" to debug (if the app is running under debugger).
Press "Ignore" to continue (this is not safe).
---------------------------
中止(A) 再試行(R) 無視(I)
---------------------------
または
---------------------------
PTracker.exe - アプリケーション エラー
---------------------------
例外 unknown software exception (0x80000003) がアプリケーションの 0x060612c6 で発生しました。
プログラムを終了するには [OK] をクリックしてください
プログラムをデバッグするには [キャンセル] をクリックしてください
---------------------------
OK キャンセル
---------------------------
2.原因
コピー元配列とコピー先配列は,同じ型,同じ次元,同じサイズでなければならない。IplImageのチャンネル数が違っていた。
3.解決方法
cvCopyで使用する入出力Imageの定義を調べる。
(1)デバッグを使用
(2)Imageを指定
(3)channelを確認
(4)変更
ただしデバッグでcvCopyの部分を表示しない場合もある。今後は怪しいIplImageを特定して[ cvCopy( ~~IplImage ]で検索かけた方がいいかも。
*cvCopyが使えない
1.症状
コンパイルは通るが実行するとエラーメッセージが出て処理が終わる。
2.原因
コピー元配列とコピー先配列は,同じ型,同じ次元,同じサイズでなければならない。ImageHeaderをImageにコピーしようとしていた。
3.解決
ImageHeader→Image変換
*IplImageの開放について
Webカメラから直接取得するために使用したIplImageはcvReleaseImage( &captureImage )などで開放する必要はない。
なぜならcvCreateImageなどでIplImageの領域確保を行ってないため。
*ImageHeaderとは?
1.概要
要するに
CreateImage : ヘッダの作成とデータ領域の確保
CreateImageHeade : メモリ確保と初期化を行い,IplImage 構造体を返す
の似たような動作をする二つの関数が存在して違いがわからん。
2.予想
Image ∋ ImageHeader
の関係か?調査続行
3.Link
http://opencv.jp/opencv/document/opencvref_cxcore_init.html
*MiniBeeで画像のレクティファイが出来ない(調査中)
1.解決策
triclops内にレクティファイイメージがあるはず…