OpenCVの重要な型 Mat
OpenCVでは画像をMat型として扱う。
Matの扱い方がわかれば、画像を自由に操れる。
ここでは、「知っておくと得するMat豆知識」をご紹介しよう。
Matの要素を取得
Mat image(Size(100, 200), CV_8U, Scalar::all(0)); uchar pixel = image.at<uchar>(100, 50);素朴なプログラムでは各要素にアクセスすることが多くなる。
at<データ型>(y, x) だ。データ型を指定する必要があるってことと、x, yの順番が逆なことに注意だ。
どうして(x, y)じゃないのか?
それは行列だから。(行、列)の順に指定するのだ。
(ちなみにメモリ上でも行ごとにまとまっている。 のちのち重要になってくる知識)
このatはデバッグモードだと非常に遅い。リリースモードだとそれなりに高速に動く。
全要素にアクセスする際は速度も気になる。
高速にピクセルにアクセスする方法も用意されている。
しかし、それよりも本当に全要素にアクセスする必要があるか、考察しよう。
Matのデータ型を変換する
CV_8Uでは0から255の整数しか扱えず、負値や255を超える値、小数点が扱えない。
そういうときはデータ型を変更しよう。
そういうときはデータ型を変更しよう。
Mat image(Size(100, 200), CV_8U, Scalar::all(0)); Mat tmp; image.convertTo(tmp, CV_32F, 1.0/255);第3引数を1.0/255としたのは、スケールを変えるため。
CV_8Uでは画像は0から255までの整数で表現される。
CV_32F、つまりfloat型にしたときには255という数字に特別な意味はなく、0から1の実数値で扱いたい。
そこですべての値に1.0/255を掛けたのだ。
Matをコピーする
Mat image(Size(100, 200), CV_8U, Scalar::all(0)); // 完全なコピー Mat tmp1 = image.clone(); // 画像のサイズとデータ型のみコピー Mat tmp2(image.size(), image.type(), Scalar::all(127));
コピーはクローン関数で行う。
同じ大きさ、同じデータ型のMatを作成する機会は多いので、合わせて覚えておこう。
Matの一部を選択する
Mat image(Size(100, 200), CV_8U, Scalar::all(0)); // 矩形領域(x, y, width, height)を選択 Mat regionOfImage(image, Rect(x, y, width, height)); // 第x列選択 Mat colOfImage = image.col(x); // 第y行選択 Mat rowOfImage = image.row(y);
選択してもコピーされるわけではない。
選択したMatの一部に対してのみ、処理を行うことができる。
GaussianBlur(regionOfImage, regionOfImage, Size(5, 5), 1.0);
0 件のコメント:
コメントを投稿