2013年3月21日木曜日

cv::Matを初期化する方法


void Initialize()
{
// 要素がすべて 100 の width160, height100 の画像
Mat src1 = Mat::ones(100,160,CV_8U) * 100;
imshow("src1", src1);
waitKey(0);

// 要素がすべて 0 の width160, height100 の画像
Mat src2 = Mat::zeros(cv::Size(160,100), CV_8U);
imshow("src2", src2);
waitKey(0);

// 定数で初期化する1
Mat src3(100,160,CV_8U, cv::Scalar(100));
imshow("src3", src3);
waitKey(0);

// 定数で初期化する2
Mat src4(100,160,CV_8U, cv::Scalar(100));
src4 = cv::Scalar(100);
imshow("src4", src4);
waitKey(0);

// 定数で初期化する3
Mat src5 = Mat::ones(100,160,CV_8U);
src5 *= 100;
imshow("src5", src5);
waitKey(0);

// 定数で初期化する4
Mat src6 = Mat::zeros(100,160,CV_8U);
src6 += 100;
imshow("src6", src6);
waitKey(0);

// Cの配列で初期化する1
uchar data1[100*160];
for(int i=0;i<100*160;i++)
{
data1[i] = uchar(i%255);
}
Mat src7(100,160,CV_8U,data1);
CV_Assert(src7.refcount == NULL);
imshow("src7", src7);
waitKey(0);

// Cの配列で初期化する2
float data2[100*160];
for(int i=0;i<100*160;i++)
{
data2[i] = float((i%255)/255.0);
}
Mat src8(100,160,CV_32F,data2);
CV_Assert(src8.refcount == NULL);
imshow("src8", src8);
waitKey(0);
};

初期化する方法を8個記述した。

8bitの要素を持つモノクロの画像は、CV_8Uというtypeで表される。
32bit単精度浮動小数点数(float)の要素を持つモノクロ画像は、CV_32Fというtypeで表される。
画像の世界でよく使われるのは、1チャンネル(モノクロ)では以下のtypeが挙げられる。
uint8_t = unsigned char = CV_8U
uint16_t = unsigned short = CV_16U

cv::Matで作られたインスタンスは 「*=」や「+=」の演算子を使うことが可能である。
http://docs.opencv.org/modules/core/doc/basic_structures.html#matrixexpressions

Cの配列で初期化するときは、CV_Assertが必要らしい。

私が初めにつまづいたのは、最初の例の画像の幅(width)と高さ(height)の順番である。
私の知りうる多くの参考書には、width、heightの順に紹介されており、Matクラスもそうなっているものと思い込んでいた(頃があった)。Matクラスでwidthとheightをそれぞれ指定するときは、rows(行、高さ、height)、cols(列、幅、width)の順番で指定しなければならない。Matクラスは本来行・列のためのクラスなのだから、当然と言えば当然である。

ちなみに、2つ目の例にあるように、Sizeクラスを使って指定するときは、width方向(cols、列)、height方向(rows、行)の順である。後に出てくるPointクラスを使う時も同じである。注意してほしい。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。