c++でopencvでのキャプチャ キャリブレーションでエラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tinotina

c++でopencvでのキャプチャ キャリブレーションでエラー

#1

投稿記事 by tinotina » 8年前

Windows10
VS2015
opencv2.4.11
の環境で

キャプチャしながらキャリブレーションしたらどうかと思って

http://electronics.extrem.ne.jp/cpp/ope ... eocapture/

http://opencv.jp/sample/camera_calibration.html
を併せて
以下のコードのようにしました。
エラー無しでビルドできるのですが
途中で
*src_img = rev_frame;
の部分で以下のエラーが発生します。

ハンドルされない例外が 0x00007FF7D80D7508 (opencvsample.exe) で発生しました: 0xC0000005: 場所 0x0000000000000000 への書き込み中にアクセス違反が発生しました。

lplimage cvmat 間の変換が問題だと思ったので
http://bicycle.life.coocan.jp/takamints ... conversion
を参考にしたんですが上手く動作していません。

どうしたらエラーをなくせるのか 教えて下さい。
どうぞよろしくお願いいたします。

int
main(int argc, char *argv[])
{
//IplImage *src_img, *dst_img;
CvMat *intrinsic, *distortion;
CvFileStorage *fs;
CvFileNode *param;
IplImage *mapx = cvCreateImage(cvSize(640, 480), IPL_DEPTH_32F, 1);
IplImage *mapy = cvCreateImage(cvSize(640, 480), IPL_DEPTH_32F, 1);

//if (argc < 2 || (src_img = cvLoadImage(argv[1], CV_LOAD_IMAGE_COLOR)) == 0)
// return -1;
//dst_img = cvCloneImage(src_img);

cv::VideoCapture cap(2);
// 様々な設定...
cap.set(CV_CAP_PROP_FRAME_WIDTH, 640);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
// カメラがオープンできたかの確認
if (!cap.isOpened())
{
printf("%s\n", "CameraOpenErr");
return -1;
};
while (1) {
cv::Mat frame;
cv::Mat rev_frame;

//IplImage frame, rev_frame;

do {
cap >> frame; // キャプチャ
} while (frame.empty()); //正しくキャプチャされるまで待つ

    //cv::imshow("Capture", frame); // 表示

cv::flip(frame, rev_frame, 1);


fs = cvOpenFileStorage("C:/temp/c++/nCal/camera.xml", 0, CV_STORAGE_READ);
param = cvGetFileNodeByName(fs, NULL, "intrinsic");
intrinsic = (CvMat *)cvRead(fs, param);
param = cvGetFileNodeByName(fs, NULL, "distortion");
distortion = (CvMat *)cvRead(fs, param);
cvReleaseFileStorage(&fs);

// (1)歪み補正のためのマップ初期化
cvInitUndistortMap(intrinsic, distortion, mapx, mapy);
// (2)歪み補正
//cvRemap(src_img, dst_img, mapx, mapy);
IplImage *src_img = 0;
IplImage *dst_img=0;
cv::imshow("Capture", rev_frame);
cvWaitKey(1);
*src_img = rev_frame;

cvRemap(src_img, dst_img, mapx, mapy);

cvNamedWindow("Distortion", CV_WINDOW_AUTOSIZE);
cvShowImage("Distortion", src_img);
cvNamedWindow("UnDistortion", CV_WINDOW_AUTOSIZE);
cvShowImage("UnDistortion", dst_img);
//cvWaitKey(0);

cvDestroyWindow("Distortion");
cvDestroyWindow("UnDistortion");
cvReleaseImage(&src_img);
cvReleaseImage(&dst_img);
cvReleaseImage(&mapx);
cvReleaseImage(&mapy);
cvReleaseMat(&intrinsic);
cvReleaseMat(&distortion);

return 0;
}

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#2

投稿記事 by usao » 8年前

IplImageに変換しなければならない理由が謎ですが,それはそれとして…

IplImgeとcv::Mat間の変換に関して,参考にしたというリンク先とは違うことをしていますよね.
(もう一度参考先の記述を確認されてはいかがでしょうか.)

コード:

IplImage SrcImg = frame;  //IplImageに変換した結果を受け取る
...
cvRemap( &SrcImg, dst_img, mapx, mapy );  //※dst_imgが指す先に画像バッファの実体が必要では?
...
//SrcImgについてはcvReleaseImage()しない
という形にすれば良いのではないかと思います.

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#3

投稿記事 by みけCAT » 8年前

ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
tinotina さんが書きました: *src_img = rev_frame;
の部分で以下のエラーが発生します。

ハンドルされない例外が 0x00007FF7D80D7508 (opencvsample.exe) で発生しました: 0xC0000005: 場所 0x0000000000000000 への書き込み中にアクセス違反が発生しました。
tinotina さんが書きました: IplImage *src_img = 0;
IplImage *dst_img=0;
cv::imshow("Capture", rev_frame);
cvWaitKey(1);
*src_img = rev_frame;
エラーの原因は0 (無効なポインタ)で初期化したポインタをそのままデリファレンスしていることのようなので、
そのようなやってはいけないことをやらないコードに修正すればいいでしょう。
(OpenCVに詳しくなく、具体的な方法はわかりません。ごめんなさい。)
オフトピック
tinotina さんが書きました:     //cv::imshow("Capture", frame); // 表示
あってはいけない場所に全角スペースがあります。
コンパイラによってはコンパイルできてしまうのかもしれませんが、気持ち悪いですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tinotina

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#4

投稿記事 by tinotina » 8年前

usao さんが書きました:IplImageに変換しなければならない理由が謎ですが,

サンプルコードをたたき台にしないといけない超初心者でございまして
opencv1.0仕様の関数(補正の部分) とopencv2.4仕様(キャプチャの部分)の関数が混ざっているんです。
理想は どちらかに統一したいのですが 思うようなサンプルに行き当たらないもので
「接ぎ木」をしたような不細工なことになっちゃってます。
変換しないといけないのは そうしないとイメージが受け渡せないんです。 

IplImgeとcv::Mat間の変換に関して,参考にしたというリンク先とは違うことをしていますよね.
(もう一度参考先の記述を確認されてはいかがでしょうか.)

コード:

IplImage SrcImg = frame;  //IplImageに変換した結果を受け取る
...
cvRemap( &SrcImg, dst_img, mapx, mapy );  //※dst_imgが指す先に画像バッファの実体が必要では?
...
//SrcImgについてはcvReleaseImage()しない
という形にすれば良いのではないかと思います.
ところが 何故かエラーが出るんです。

IplImage *src_img = 0;

src_img = rev_frame;

と、分けたらエラーが出ないんです。

tinotina

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#5

投稿記事 by tinotina » 8年前

みけCAT さんが書きました:ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
tinotina さんが書きました: *src_img = rev_frame;
の部分で以下のエラーが発生します。

ハンドルされない例外が 0x00007FF7D80D7508 (opencvsample.exe) で発生しました: 0xC0000005: 場所 0x0000000000000000 への書き込み中にアクセス違反が発生しました。
tinotina さんが書きました: IplImage *src_img = 0;
IplImage *dst_img=0;
cv::imshow("Capture", rev_frame);
cvWaitKey(1);
*src_img = rev_frame;
エラーの原因は0 (無効なポインタ)で初期化したポインタをそのままデリファレンスしていることのようなので、
そのようなやってはいけないことをやらないコードに修正すればいいでしょう。
(OpenCVに詳しくなく、具体的な方法はわかりません。ごめんなさい。)
オフトピック
tinotina さんが書きました:     //cv::imshow("Capture", frame); // 表示



あってはいけない場所に全角スペースがあります。
コンパイラによってはコンパイルできてしまうのかもしれませんが、気持ち悪いですね。
本当ですね・・・
レム行なので 削除しました。
ご指摘ありがとうございます。

もしかしてなんですが opencv2.4.11で検証してますので opencv3.1に変えて走らせてみます。

ビルドできて 動作時に出るエラーって もしかしてバージョンが原因かなって 思えてきました。

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#6

投稿記事 by usao » 8年前

tinotina さんが書きました:
ところが 何故かエラーが出るんです。

IplImage *src_img = 0;

src_img = rev_frame;

と、分けたらエラーが出ないんです。
意味が把握できません.
その記述だと
cv::MatからIplImage*に変換できません 的なコンパイルエラーが出そうに見えますが.


cv::Matのoperator IplImage()の戻り値をIplImage型の変数に代入する

OpenCVの関数群は IplImage* 型を引数に取るので,前記IplImage型変数を指すポインタを引数に渡す

という手順にすべきではないかということを申し上げたつもりなのですが,
その方法ではダメなのでしょうか?
オフトピック
>理想は どちらかに統一したいのですが 思うようなサンプルに行き当たらないもので

質問への直接的な回答ではありませんが…
C++(cv::Matを使う)系と,C(IplImageを使う)系とで 大抵同じような名前の関数とかが存在しますので,
OpenCVのリファレンスで片方の側の関数名を検索すると他方の関数名等が見つかったりします.
例えば,
cvRemap() ←→ cv::remap()
cvInitUnditortMap() ←→ cv::initUndistortRectifyMap()
みたいな.
(後者はなにやらRecrificationの機能がくっついてますが)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#7

投稿記事 by みけCAT » 8年前

tinotina さんが書きました:ところが 何故かエラーが出るんです。

IplImage *src_img = 0;

src_img = rev_frame;

と、分けたらエラーが出ないんです。
意味が分かりません。
まず、何に対しての「ところが」ですか?
次に、「分けたら」とはどういうことですか?
このコードと元のエラーが出るコードの違いは、行が削除されている他に、
ヌルポインタをデリファレンスしてエラーを出すかわりにポインタ変数をデリファレンスせず、それ自体に何かを代入していることであるように見えます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tinotina

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#8

投稿記事 by tinotina » 8年前

みけCAT さんが書きました:
tinotina さんが書きました:
意味が分かりません。
まず、何に対しての「ところが」ですか?
次に、「分けたら」とはどういうことですか?
言葉足らずですみません。

IplImage SrcImg = rev_frame;

だと
「rev_frame」の下に赤い波線が表示され
「"cv::Mat" から "IplImage *" への適切な変換関数が存在しません」
という エラーが発生します。

IplImage *src_img = 0;

src_img = rev_frame;

と、して ビルド→ソリューションでコード分析を実行 したら
その時点ではエラーが出ないということなんです。

・・・二つのコードは 同じような意味と思ったんです。
厳密にはもちろん違いますけれど。

tinotina

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#9

投稿記事 by tinotina » 8年前

オフトピック
>理想は どちらかに統一したいのですが 思うようなサンプルに行き当たらないもので

質問への直接的な回答ではありませんが…
C++(cv::Matを使う)系と,C(IplImageを使う)系とで 大抵同じような名前の関数とかが存在しますので,
OpenCVのリファレンスで片方の側の関数名を検索すると他方の関数名等が見つかったりします.
例えば,
cvRemap() ←→ cv::remap()
cvInitUnditortMap() ←→ cv::initUndistortRectifyMap()
みたいな.
(後者はなにやらRecrificationの機能がくっついてますが)
おっしゃるように C(IplImageを使う)系のコードをもとにC++(cv::Matを使う)系に統一する方向で
やってみます。
ありがとうございます。

tinotina

Re: c++でopencvでのキャプチャ キャリブレーションでエラー

#10

投稿記事 by tinotina » 8年前

おかげさまで 出来ました。

usaoさま みけCATさま 大変お世話になりました。
本当にありがとうございました。

コード:

int
main(int argc, char *argv[])
{
	int capnum = 0 ;

	cv::VideoCapture cap(2);

	if (!cap.isOpened())
	{
		printf("%s\n", "CameraOpenErr");
		return -1;
	};

	cv::Mat K;
	cv::Mat distCoeffs;
	cv::FileStorage fs("C:/temp/c++/nCal/camera.xml", CV_STORAGE_READ);
	fs["intrinsic"] >> K;
	fs["distortion"] >> distCoeffs;

	while (1) {
		cv::Mat frame;
		cv::Mat rev_frame;
		cv::Mat dst_img;

		do {
			cap >> frame;
		} while (frame.empty());

		cv::flip(frame, rev_frame, 1);
		
		cv::imshow("Reverse", rev_frame); 
		cvWaitKey(1);

		cv::undistort(rev_frame, dst_img, K, distCoeffs);

		cv::imshow("Distortion", dst_img); 
	}
	cvDestroyWindow("Distortion");
	cvDestroyWindow("Reverse");
	//cvReleaseImage(dst_img);
	//cvReleaseImage(rev_frame);
	//cvReleaseImage(frame);
}

閉鎖

“C言語何でも質問掲示板” へ戻る