はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】ComputeShaderを使って画像処理100本ノックをしてみた【Q1~10】

はじめに

最近画像処理に少しハマっていて、こちらのGitHubにある画像処理100本ノックをやっています。

github.com

また画像処理は計算量が膨大になることが多いので、UnityのC#スクリプトのみだとなかなか厳しいものがあります。

そこでGPUという巨大パワーを授けてくれるComputeShaderを用いていきたいと思います。

docs.unity3d.com


今のところQ1~10の実装方法をブログで公開しているので、そちらをまとめて紹介していきます。

f:id:hanaaaaaachiru:20200214000920p:plain

ComputeShaderって?

画像処理100本ノックに入る前に、ComputeShaderってなんやねんという方もいると思うので簡単に説明をさせていただきます。

もしかしたらシェーダという単語を聞くと見た目がエモい感じのものを想像するのではないでしょうか。

f:id:hanaaaaaachiru:20200213234737p:plain
https://www.youtube.com/watch?v=7ToExWKVZW0&t=1208s

こういったTwitterなどでよくみるエモい感じのもののほとんどはSurfaceシェーダー頂点・フラグメントシェーダーです。

これらは描画する方法を自分で記述するものになります。

ただこれらとは少し毛色が違い、GPUを計算とかに使っちゃおうぜって奴がComputeShaderです。

CPUで計算をすれば良いじゃんと思う方もいるかもしれませんが、GPUは並列処理が得意なので計算を爆速化できることが多いという特徴があります。

また拡張子は.computeHLSL言語を用いています。

docs.unity3d.com

一覧

Q1.チャンネル入れ替え

最初は入門ということでRGBBGRに変換します。

はじめの一歩はいつでも難しいですよね。

f:id:hanaaaaaachiru:20200214001701p:plain

www.hanachiru-blog.com

Q2.グレースケール化

画像を白と黒のグラデーションで表現するためにグレースケール化をします。

結構いろんなものに応用できるので、マスターしておくと良いかもしれません。

f:id:hanaaaaaachiru:20200214002050p:plain

www.hanachiru-blog.com

Q3.2値化

画像を白と黒の2色だけで表現をする2値化をします。

グレースケールはグラデーションですが、こちらは2色のみです。

f:id:hanaaaaaachiru:20200214002309p:plain

www.hanachiru-blog.com

Q4.大津の2値化

もっと理論的にいい感じに2値化してくれるものが大津の2値化です。

ここの実装はもっと良くできるような気がするので、なにかより良い方法やご指摘がありましたらコメント等で教えていただけると嬉しいです。

f:id:hanaaaaaachiru:20200214002727p:plain

www.hanachiru-blog.com

Q5.HSV変換

RGBHSVという色相・彩度・明度で色を表現したものに変換するHSV変換をします。

よくお絵かきソフトなんかはRGBHSV両方対応しているものがありますが、内部的にはこのように実装されていたのかとちょっと感動です。

f:id:hanaaaaaachiru:20200214003012p:plain

www.hanachiru-blog.com

Q6.減色処理

色の階調数を減らす減色処理をします。

階調数は何段階で表すかということで、RGBはそれぞれ0~255の256階調で表されています。

f:id:hanaaaaaachiru:20200214003356p:plain

www.hanachiru-blog.com

Q7.平均プーリング

グリッド単位で画像を分割して、その領域内の平均値で埋める平均プーリングをします。

おそらくモザイクもこの処理で実装されているのではないでしょうか。

f:id:hanaaaaaachiru:20200214003659p:plain

www.hanachiru-blog.com

Q8.Maxプーリング

平均プーリングでは平均値で埋めましたが、最大値にしたものがMaxプーリングです。

これは平均プーリングに比べて全く使い道が想像できません。

f:id:hanaaaaaachiru:20200214003925p:plain

www.hanachiru-blog.com

Q9.ガウシアンフィルタ

以下のフィルタを用いて空間フィルタリングをしたものがガウシアンフィルタです。

f:id:hanaaaaaachiru:20200214004107p:plain

フィルタ関連はThe画像処理な感じがします。

f:id:hanaaaaaachiru:20200214004145p:plain

www.hanachiru-blog.com

Q10.メディアンフィルタ

ガウシアンフィルタと違って中央値を選ぶのがメディアンフィルタです。

中央値を求める際にどうしてもソートをする必要が出てきます。ソートには色んな方法があるので、最適化も奥が深そうですね。

f:id:hanaaaaaachiru:20200214004428p:plain

www.hanachiru-blog.com

さいごに

これは賛否ありそうですが、ComputeShaderからシェーダーを触れはじめるのも悪くないような気がします。

というのもSurfaceシェーダーや頂点・フラグメントシェーダーはあらかじめ作られたテンプレートを編集するイメージなのであまり仕組みを分からずに使いがちだと思います。

というか私も良く分かっていません。

しかしComputeShaderは1から作っていく感じなので、全体像を把握しやすいです。

またHLSL言語に慣れていくには程よいのではないでしょうか。


飽きていなければ画像処理100本ノックの続きを投稿すると思うので、良かったらそちらもみてみてください。

ではまた。