RGB分離&RGB値で画像を2値化して恐竜君を抽出してみる
前回はMATLABの便利な機能を使って、以下の画像をリサイズ後にグレースケール化して、白黒で2値化した。
以下が前回画像処理したもの↓ 一応、恐竜君だけ良い感じに抽出するのが目的だったのだが、上に線が入っていたり、恐竜君も一部消えていたりしてちょっと微妙な感じ。
元の画像を眺めていて思ったのだが、恐竜君はRGBのうちG(緑)の成分が多そうなので、R、G、Bに着目して閾値を決めて2値化した方が良い感じに恐竜君を抽出できるのでは…?
ということで、今回は元のRGB 8bitの画像をR、G、Bにそれぞれ分離したうえで閾値を手動で決めて2値化してみたい。
開発環境
MATLAB online
MATLAB R2022a
Image Processing Toolbox
画像をRGB分離する
まずは前回アップロードした画像を行列Aとして読み込み、前回と同様に半分のサイズにリサイズしておく。※リサイズは別にやらなくても良いのだが、ちょっと画像が大きくて扱いずらいため…
A = imread('dinosaur.jpg'); Asmall = imresize(A, 0.5);
Asmallは画像の縦サイズ×横サイズ×3(RGB)の3次元行列で、各要素にはunsigned int 8bitのデータが入っている。まずはこれをR、G、Bごとに分ける。MATLABの通常の行列操作で3つに分けても良いのだが、Image Processing Toolboxが使えるならimsplitという関数を使えば、以下のようにサクッとR、G、Bに分離することができる。
[R,G,B] = imsplit(Asmall);
以下のようにワークスペースごとにR、G、Bのデータが保存されている。
imsplitの詳細は以下を参照。
https://jp.mathworks.com/help/images/ref/imsplit.html
せっかくなので、R、G、Bをそれぞれグレースケールの画像にして並べて比較してみる。といっても、これもmotageという関数を使えばサクッとできる。
montage({R,G,B},'Size',[1 3]);
表示させてみたのが以下の画像。左からR、G、Bを画像化したものになる。この画像を見ていて思ったのは、恐竜君はGの成分が多いというより、Rの成分が極端に少ないのが特徴のようだ。ということで、今回はこのRの成分に着目して、自分で閾値を決めて2値化してみたいと思う。
閾値を決めて画像を2値化する
先ほど分離したRを使って、適当な閾値を決めて白黒の2値化をやってみる。自分で閾値を決める時は、以下のように不等号を使ってシンプルに指定することができる。試しに50を閾値として2値化して、imtoolで表示してみる。
BW = R < 50; imtool(BW);
表示してみたのが以下の画像。上の方で机の端も少し検出されているが、恐竜君を塊としてしっかり抽出できているのでなかなか良い感じ。
ちなみに、今回はRGBのまま分離して恐竜君を抽出してみたが、一般的にはRGBで検出するより、HSVに変換して閾値を設定して検出した方が明るさの影響を受けにくいので、抽出がうまくいくケースが多いようだ。
ということで、次回はRGB→HSV空間への変換や、HSVでの抽出などをやってみて、今回のRGBの結果と比較してみたい。
参考文献
この本のMATLAB/Simulink 6か月ライセンスを使ってやってます↓
MATLAB/Simulink記事まとめ
MATLABとSimulinkの記事は以下にまとめてます。