前回からScilabのツールボックスIPCVの手習ひ開始。この手の処理ならOpenCV使えばとも思うけど、OpenCVは巨大かつ進化が早いっす。お惚け老人は遥か以前のOpenCVバージョンで止まってます。その点、IPCVはScilabの中ではドキュメントが充実している方で、かつ枯れてる感じがします。お惚け老人には好適?
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※Windows11上のScilab2024.0.0およびScilab上のツールボックスを使用させていただいております。(今回より別件シリーズとScilabバージョンを合わせました。)
Scilab IPCV
ツールボックスの解説ページが以下に。
(老人にとっての少し以前まで)力が入って開発されていた感じですが、最近はちょっと力抜けているんじゃないの、という感じのツールボックスです。Scilabのツールボックスには作っている途中で力が抜けたようなものも散見される中、一通りできてデバッグも進んだ後止まっている感じ(個人の感想デス)なツールボックスです。
Image Analysis and Statistics
用途が用途なので大量な関数が含まれます。その中から、前回、「いつものお猿様」のお顔を解析するのにヒストグラムを描いてます。そこで今回はヒストグラムを描くimhist関数が含まれる Image Analysis and Statistics というカテゴリに含まれる関数を手習ひ。ヒストグラムは、ビンの幅を変えたり、画像の一部に適用したりといろいろあろうかと思いますが、前回やっているので今回は割愛っす。
-
- improfile
- impixel
- mean2
- std2
- stdev2
- corr2
- edge
インタラクティブな解析関数2つ
まずはインタラクティブな解析関数です。improfileとな。画像上の2点を指定して2点を結ぶ直線にそった解析を行うとともに、2点の座標など返してくれるものです。「風船玉」の例題が以下に。
S = imread(fullpath(getIPCVpath() + "/images/balloons.png")); [xc, yc, pixval] = improfile(S);
左側は赤の風船、右側は水色ですな。
続くは、インタラクティブな画素選択の impixel です。これを使えば、オリジナル画面のここからここまで取り出そう、なんて時にお楽?
S = imread(fullpath(getIPCVpath() + "/images/balloons.png")); [xc, yc, pixval] = impixel(S);
赤い風船のところにお印を多数つけました。なお左クリックで印をつけて、最後は右クリックで終わらせるみたい。
戻り値は以下のようです。
普通はこんなに乱雑にアチコチ指定せず、矩形で囲む予定の2点とかだろうけど。
なお、御覧のとおり、上記のインタラクティブな関数は上のように「マルチチャンネル」(色がついている)データに対しても動作OKです。一方、これからやる下の関数どもは単純な2次元データ(1色のみ)用デス。
統計関数ども
最初に練習するのは平均値を得る mean2 関数です。2次元だから2なのかな~。知らんけど。前回も使った「いつものお猿様」の画像(元はカラーなので白黒に変換して)に適用する操作が以下に。
imBaboon = imread(fullpath(getIPCVpath() + "/images/baboon.png")); imGray = rgb2gray(imBaboon); mean2(imGray)
平均値あれば標準偏差あり、しかし標準偏差を計算する関数は2つもあります。std2 と stdev2 ね。なにか違いが?と思ったのだけれども見当たらず。歴史的あるいは大人の事情?適用したところが以下に。
つづいて、相関係数をもとめる corr2 です。画像2つから計算しますが、1チャンネル(単色)画像であるだけでなく、画像サイズもそろっていないとあきません。以下の処理例では、前回もやったお猿様のガウシアンフィルタ(ボカシ)画像を元のオリジナル画像と比較してます。
fG = fspecial('gaussian', 5, 0.5); imG = imfilter(imGray, fG); corr2(imGray, imG)
限りなく1に近いけれども、ちゃんと差はあると。
エッジ検出
前回もソーベルフィルタとかエッジ検出用の関数やってますが、今回の edge 関数はフィルタかけた後で「閾値」と比べて0か1かの判断までしてしまうものです。適用するフィルタやそのパラメータなども多数。まずは canny フィルタ適用の場合。
E = edge(imGray, 'canny', [0.06, 0.2]); imshow(E);
結果の画像が以下に。もっと「キッパリ」したお猿様を期待したのだけれどもこれはよく分からんなあ(個人の感想っす。
一方、prewitt フィルタを適用するシーケンスが以下に。
E = edge(imGray, 'prewitt'); imshow(E);
いい感じでないかい?