新着記事

OpenCVのcoreライブラリMatについて見てみた。

2021年5月29日IT,OpenCV

OpenCVのcoreライブラリMatについて見てみた

OpenCVを用いた画像処理において知らないといけないcv::Matについてちょっと調べてみた。
ぼくのPC環境は以下のようになってます。

Visual studio 2015 64 bit
OpenCV 3.4.1
os : windows 10 64bit pro
cpu : i7 7700k
ram : 16gb
gpu : GTX 1060 6g

cv::Matの画像データの扱いについて

OpenCV環境下で画像データを扱うにはまず欠かせないMatを見ていきます。
Matはチャンネルとサイズとタイプの3つから構成されていて、この3つのデータを変えて出力される画像を拡大・縮小・変形、座標データの取得、データの書き込みなどなどいろいろなAPIや関数を組み合わせることによって出来上がるのが処理結果なのである。
とりあえず、下のソースコードをコード内にコピペして起動してみよう。OpenCVのインストール方法やVisualstudioの使い方等は自分で調べたり、OpenCV3.4.1のインストールと設定の方法についてはこのサイトでも解説しているよ。でも適当だからあまり参考にならないから、別のサイトを推奨。
サンプルコード

#include <opencv2\core.hpp>
#include <iostream>
int main() {
cv::Mat a;
std::cout << "channels: " << a.channels() << std::endl;
std::cout << "size: " << a.size() << std::endl;
std::cout << "type: " << a.type() << std::endl;

return 0;
}

サンプルコードの解説として、include<opencv2/core.hpp>では、名前の通り、OpenCV2ファイル内にあるcore.hppを取り込んでいるよ。
coreの中身は主に画像や行列のデータ構造の提供をしているよ。他には配列の操作に用いるものやユーザーの操作を楽にさせるためのユーティリティー等々入っているよ。

include <iostream>はC++を扱っている人は知ってると思うけど、C++のライブラリだよ。オラクルさんで解説されているからURLを張っておくよ。https://docs.oracle.com/cd/E19957-01/805-7889/6j7duaiiq/index.html

次にMatについてだよ。とりあえず、OpenCVの関数を呼び出すときは最初にcv::を入れることを忘れないでね。ちなみに省略することもできるよ。using namespace cv;をinclude行下あたりかつmainの外に入れておくことでcv::Matじゃなく、Matと入れるだけで呼べるよ。

std::cout << “channels: " << a.channels() << std::endl;
std::cout << “size: " << a.size() << std::endl;
std::cout << “type: " << a.type() << std::endl;

の部分なんだけど、ここではMatのインスタンスの中身を見るために呼び出しているよ。さっきのサンプルコードを走らせたら下のような結果が出ると思う。

channel又はscalar= 色の数
size = 画像の大きさ
type = バイト数
のようにOpenCVでは、3つの要素から構成されているよ。下で詳しく解説するよ。

Sponsored Links

チャンネルとは

主に色を表現するために扱われる部分で、チャンネルが1の状態だと白から黒までの情報を扱うような感じになるよ。また、1チャンネルの符号無し8ビット長だと0~255までの数値で白から黒までの輝度的表現を取り扱うことができるよ。ようするにグレースケール(白黒画像)ということ。そんで、3チャンネルになるとRGB(レッド・グリーン・ブルー)を表現方法として扱われるようになるよ。

サイズとは

画像の大きさと考えていいよ。~キロバイトとかそういう意味じゃなくて画像の大きさ、ドット部分の占有数的なことだよ。例えば、100*100だとそのピクセル数を持ったデータということだよ。このピクセルひとつひとつにRGBデータが入っているのだ。

タイプとは

C++でいうところのデータ型だよ。unsigned char型ならば CV_8Uと指定するよ。(OpenCVで指定されている数字でも可)ここで1つのピクセルに何バイト使うか決まるよ。

Matクラスのインスタンス数値を指定して生成

さっきはMat a だけで生成したけど、次はデータの大きさを指定して生成するよ。下のコードをコピペして起動してみてね。

#include <opencv2\core.hpp>
#include <iostream>
#include<opencv2\highgui.hpp>
int main() {
cv::Mat a(200,200, CV_8UC4, cvScalar(255,0,0));
std::cout << "channels: " << a.channels() << std::endl;
std::cout << "size: " << a.size() << std::endl;
std::cout << "type: " << a.type() << std::endl;

cv::imshow("a", a);
cv::waitKey();

return 0;
}

どうだろうか、今回はaに対して200*200の大きさを与えてタイプをCV_8UC4にして、色部分にRGBのBに255を与えた。一番左が255でRと間違えてしまいがちだけど、OpenCVではBGRになるよ。ここ面倒くさいよね。でも間違えないようにしないと色がぐちゃぐちゃになってしまうんだ。結果はどうだろう。小さい青いウィンドウが出てきたと思う。処理を終了させるにはウィンドウをアクティブ状態にして何かしらのキーをおすことで終了されるよ。

cv::Mat a(200,200, CV_8UC4, cvScalar(255,0,0));
重要な部分はこれ、200,200では大きさを指定して、CV_8UC4でタイプを指定、cvScalar()では色を指定しているよ。255,0,0はGBRの順で表現されるよ。今回は青を255としているから、一面が青で表示されるよ。

処理結果がこれ
コンソール画面

cv::imshowでの画像データ表示

コンソール画面では4チャンネルでサイズ[200*200]、typeが24になっているね。
4チャンネルってことはRGB(GBR)を透明度(透過)を表しているので、4チャンネルになる。サイズはimshowでの画像データ表示結果のウィンドウの大きさのことだよ。そして、type24でいうのが、OpenCVのライブラリ内であらかじめ決められた構造を呼び出しているのだよ。ようするに24番目がCV_8UC4ということだこれは、符号無し(マイナス無し)のチャンネル4つを表しているのだ。あと、ここで型情報の定数まとめが記載されているので、ここを参考サイトとして張っておくよ。http://d.hatena.ne.jp/arche_t/20090120/1232445728

cv::imshowとcv::waitkeyとは

最後の部分に出てきたcv::imshowとcv::waitkeyについて教えるよ。
まず、これだけは押さえておいてほしい。この二つはニコイチで扱うことを前提としていること。
imshowのcv::imshow(“a", a);の"a"ではウィンドウの名前を決めている。試しにここを変えて起動してみるとウィンドウの名前が変更されていると思う。そしてそのあとに記述されている,aは、表示する画像の引数を表している。

waitkeyはキー入力を待つ関数とともに、OpenCVのウィンドウ部の更新をする機能も持っている。つまり、imshowでウィンドウを呼び出したとしても、更新機能の無いimshowだけでは再描画されないでエラーを吐いてしまったり、画像同士の重ね合わせる場合に変な動作を引き起こしてしまったり、サイズ変更やウィンドウの移動を行う際に処理がずれていってしまう可能性があるわけだ。ようするに、とりあえずこの二つはニコイチとして扱うと思っておいたほうがいい。

オススメの本

ちょっとお高いけど、OpenCVについて大体網羅した本が日本語で出ていたので、紹介するよ。

この本では今回解説した内容よりもふかーーく解説されているし、APIの解説を1つ1つしているのでページ数もスゴい。読むところはページ数でいうと900ページくらいはあったような気がする。ぼくもこの本を見て勉強しているけど、度忘れしたり、わからない部分とかを調べる際に辞書として重宝しているゾ。唯一ヤバい点は表紙が蛾であることぐらい。ようするにオススメゾ。

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識 

Left Caption

底辺

RGBがGBRてこんがらがるわ。CUDAAPI使ったらコピー処理の記述が逆だらもっとわからなくなるゾ。おつぽばいぴち。

IT,OpenCV

Posted by ichiryuteihen