今日は4章の練習問題をやります。
1.a 動画を読み込み、「そのままの画像」、「グレイスケールに変換した画像」、「Cannyフィルタを実行した画像」をそれぞれウィンドウに名前をつけて表示する。
1.b 上記3つの画像を1つの画像に並べて表示する。(高さは同じ、幅が3倍の画像)
作ったものを実行した画面が下記のとおりとなります。
上3つが、それぞれ別のウィンドウに表示したもので、
下の横長のウィンドウが、3つの画像を1つにまとめたものです。
ソースコードは別館の方に置いてあります。
今回、グレースケール化とCannyフィルタはすぐできたのですが、
3つの画像を1つにまとめるのに少し時間がかかりました。
最初はIplImageのヘッダを作って、画像データのポインタをcvPtr2Dで取得すれば大丈夫かなと思ってコードを組んだのですが、コピーして出来上がった画像は、1枚の画像が3枚にスライスされて並べられたような状態になりました。
色々いじった結果、widthStepの値を元の画像の3倍にするとうまくいきました。
widthStepは、次の行の最初のピクセル(例えば0,0から0,1)へのバイト数を表しているようです。widthStepは何かなーと以前から思っていましたが、今回この練習問題で理解することができました。
以下のコードは、3つの画像ヘッダに、データポインタを割り当てるところの部分的なコードとなります。
IplImage* src; src=cvQueryFrame(capture); //グレイスケールとCanny用 IplImage* imgGray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); IplImage* imgCanny=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); //3つの画像を1つにまとめるためのもの IplImage* imgFusion=cvCreateImage(cvSize(src->width*3,src->height),IPL_DEPTH_8U,3); IplImage* headerSrc=cvCreateImageHeader(cvGetSize(src),IPL_DEPTH_8U,3); IplImage* headerGray=cvCreateImageHeader(cvGetSize(src),IPL_DEPTH_8U,3); IplImage* headerCanny=cvCreateImageHeader(cvGetSize(src),IPL_DEPTH_8U,3); //ヘッダに、imgFusionの画像データのポインタの先頭、1/3,2/3の位置を指定する headerSrc->widthStep=src->widthStep*3; headerSrc->origin=src->origin; headerSrc->imageData=(char *)cvPtr2D(imgFusion,0,0,NULL); headerGray->widthStep=src->widthStep*3; headerGray->origin=src->origin; headerGray->imageData=(char *)cvPtr2D(imgFusion,0,src->width,NULL); headerCanny->widthStep=src->widthStep*3; headerCanny->origin=src->origin; headerCanny->imageData=(char *)cvPtr2D(imgFusion,0,src->width*2,NULL);
ではまた。
0 件のコメント:
コメントを投稿