問題1:
byte型の3チャネルをもつ、100x100サイズの配列を作る。
問題2:
cvCircleを使って、その中に円を描画する。
問題3:
cvPtr2Dを使って、緑の四角形を描画する。
問題4:
ポインタ計算を使って、(20,5)と(40,20)の間に緑の四角形を描画する。
ソースコードは別館の方に置いてあります。
問題1の解説:
OpenCVではcvCreateMat( int rows, int cols, int type ); を使うことで、行列を作ることができます。今回はbyte型の3チャネルなので、CV_8UC3を指定します。
CvMat* matArray=cvCreateMat(100,100,CV_8UC3);
で、3チャネル、byte型、100 x 100サイズの行列を作ることができます。
CvMat* matArray=cvCreateMat(100,100,CV_8UC3);
で、3チャネル、byte型、100 x 100サイズの行列を作ることができます。
OpenCVのリファレンスによると、チャネルの型は下記のような書式で定義されているようです。
CV_<ビット深度>{U|S|F}C<チャネル数>
問題2の解説:
cvCircleは、
void cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
という関数になっていて、imgのcenterに半径radiusの円を描きます。線の色はcolor、線の幅はthickness、線の種類はlineTypeで指定できます。
今回は円を書くだけなので、
cvCircle(matArray,cvPoint(50,50),20,CV_RGB(255,0,0),1,8,0);
で(50,50)の位置に円を書くことができます。
問題3の解説:
cvPtr2D関数は、指定した配列の行、列へのポインタを返してくれます。
uchar* cvPtr2D(const CvArr* arr, int idx0, int idx1, int* type=NULL);
typeはオプションで、NULLを入れなかった場合は配列の要素の型情報が出力されるようです。
今回は型情報は必要無いので、
uchar *ptr;
ptr=(uchar *)cvPtr2D(matArray,y,x,NULL);
*ptr=255;
でy行x列の値を255に設定することができます。
ただし、OpenCVはBGRBGRBGR...というようにメモリ上にデータを格納しているので、緑のチャネルを指定する場合はptrに1を加える必要があります。
問題4の解説:
私もあまり分かってないポインタ演算。
CvMat構造体のヘッダを見ると、
int type;
int step;
int* refcount;
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data;
//以下省略
となっています。
このunionというのは共用体というもので、定義してあるもののうち、どれか1種類を格納できる、というものです。詳しくは共用体・union/構造体との違い@C/C++StudyRoom を参照ください。
今回の配列はbyte型のデータ配列なので、uchar* ptrにデータが入っているはずです。
というわけで、
matArray->data.ptr[0]
でデータの先頭、つまり(0,0)の青チャネルにアクセスできます。
同じように、
matArray->(x+y*matArray->cols)*3+1]=255;
で(x,y)の緑チャネルの値を255に設定することができました。
ポインタ演算が一番高速だとは思うのですが、ポインタ計算がちょっと大変ですね。
ではまた。
問題3の解説:
cvPtr2D関数は、指定した配列の行、列へのポインタを返してくれます。
uchar* cvPtr2D(const CvArr* arr, int idx0, int idx1, int* type=NULL);
typeはオプションで、NULLを入れなかった場合は配列の要素の型情報が出力されるようです。
今回は型情報は必要無いので、
uchar *ptr;
ptr=(uchar *)cvPtr2D(matArray,y,x,NULL);
*ptr=255;
でy行x列の値を255に設定することができます。
ただし、OpenCVはBGRBGRBGR...というようにメモリ上にデータを格納しているので、緑のチャネルを指定する場合はptrに1を加える必要があります。
問題4の解説:
私もあまり分かってないポインタ演算。
CvMat構造体のヘッダを見ると、
int type;
int step;
int* refcount;
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data;
//以下省略
となっています。
このunionというのは共用体というもので、定義してあるもののうち、どれか1種類を格納できる、というものです。詳しくは共用体・union/構造体との違い@C/C++StudyRoom を参照ください。
今回の配列はbyte型のデータ配列なので、uchar* ptrにデータが入っているはずです。
というわけで、
matArray->data.ptr[0]
でデータの先頭、つまり(0,0)の青チャネルにアクセスできます。
同じように、
matArray->(x+y*matArray->cols)*3+1]=255;
で(x,y)の緑チャネルの値を255に設定することができました。
ポインタ演算が一番高速だとは思うのですが、ポインタ計算がちょっと大変ですね。
ではまた。
0 件のコメント:
コメントを投稿