2011/03/01

詳解OpenCVの練習問題(4)

3章の練習問題は大体終わったので、
今日は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 件のコメント:

コメントを投稿