2021年3月26日金曜日

【C#,OpenCV】ぼかしフィルタを使ってみる

引き続きOpenCvSharpを使って勉強してみています。
今回はフィルタ処理などを使ってみようかと思います。

平滑化(ぼかし)フィルタなどですね。
今回は以下のようなものを使ってみようと思います。

・平滑化フィルタ
・ガウシアンフィルタ
・中央値フィルタ
・バイラテラルフィルタ

よくわかっていない部分があるので間違っているかもしれませんが、
まあ、とりあえずやってみましょ。



フィルタってなんぞ…

画像処理でよく使われるフィルタ。
有名どころで言ったら、平滑化フィルタ(ぼかし)でしょうか?
1画素はRGBの構成で作られていますが、
複数画素に対して特定の行列計算をして、結果の色を出力する処理がフィルタですね。

平滑化フィルタはわかりやすく、範囲内画素の平均値を取るみたいですが、
ガウシアンフィルタとかバイラテラルフィルタは別の計算をしているらしいですね。
OpenCVの公式ページでもいろいろ説明されていますが、
じぇんじぇんわからなかったです。

かろうじて平滑化フィルタと中央値フィルタはわかりそうかな…。

平滑化フィルタ

フォトショップとかにある「ぼかし」フィルタですね。
特定の範囲(3×3とか5×5とか…)に対して、色を平均化するようです。
平均化した結果、色がにじんでぼやあってぼかしがかかるんですね。

OpenCvSharpでは下記のような形で使用できます。
Mat src = Cv2.ImRead("source.jpg");
Mat dst = new Mat();
Cv2.Blur( src, dst, new OpenCvSharp.Size(5,5) ); 


結果としてはこんな感じになりますね。 
10×10のサイズでぼかしを行ってみています。
このサイズだと大分ぼやけますね。



ガウシアンフィルタ

注目する画素との距離に応じて重みづけして計算するらしい…です。
一応見たけど計算式がよくわかりませんでした!
なんでも、このガウシアンフィルタは画像の白色雑音の除去に適しているのだとか。

特定のノイズに対して除去に向いたフィルタがあるということですかね。

下記のような形で使用することができます。
Mat src = Cv2.ImRead("source.jpg");
Mat dst = new Mat();
Cv2.GaussianBlur( src, dst, new OpenCvSharp.Size(5, 5), 0 );

結果としてはこんな感じになりますね。
境界を荒らすような状態にしてかけてみましたが、その部分を少し和らげているような…
使い方としてあっているんでしょうか?(適当)



中央値フィルタ

平滑化フィルタでは範囲内画素の平均値を使用していましたが、
中央値フィルタでは範囲内画素の中央値を取得するようです。
なんでも、このような処理をすると、ごま塩ノイズのような
画像に対して特異なノイズを取り除くことに向いた処理ができるそうです。

OpenCvSharpでは下記のような形で使用できます。
この時の範囲指定は奇数である必要があるらしいです。
Mat src = Cv2.ImRead("source.jpg");
Mat dst = new Mat();
Cv2.MedianBlur( src, dst, 5 );

結果としてはこんな感じになりますね。
平滑化で使用した画像に白い点々を追加しています。
フィルタをかけた結果、これが取り除かれるような感じでしょうか。


バイラテラルフィルタ

ここまでのフィルタは画像のエッジごとぼかしてしまうのですが、
バイラテラルフィルタというのはエッジを保存しつつ、画像をぼかせるらしいです。
人の画像の輪郭を残しつつ、その内部をぼかす…というようなことですかね。

ただ、複雑な分、他のフィルタに比べると処理速度が遅いらしいです。

OpenCvSharpでは下記のような形で使用できます。
Mat src = Cv2.ImRead("source.jpg");
Mat dst = new Mat();
Cv2.BilateralFilter( src, dst, 9, 75, 75 );

結果としてはこのような感じになりますね。
元画像にエッジをかけたものに対して行ってみています。
人と背景の境界などははっきりしたまま、背景模様や帽子の模様などに
若干ぼやかすようなフィルタがかかっているのが分かりますでしょうか?



おわり

ぼかし方に関してもいろんな種類があるんですね。
自分は正直、ここでいう平滑化フィルタくらいしか知りませんでした。
ガウシアンフィルタやバイラテラルフィルタなどは用途に応じて使う感じでしょうか?

撮影したカメラ画像に対して、
ガウシアンフィルタ等のフィルタでノイズを除去した上で、
物体検知とかの処理を行っていく…んでしょうか?

場合によっては、フィルタを自作する必要もあるんでしょうね。
その画像に応じて「何か」を除去、もしくは抽出するような…。

この辺はまだまだ勉強が必要ですね。




0 件のコメント:

コメントを投稿