未分類

【Q.1-10】画像処理100本ノックの解法を全部載っける

はじめに

みなさんは、「画像処理100本ノック」というものを知っていますか?

画像処理100本ノックを作ったった

こちらは、OpenCVというライブラリを使って画像処理の問題をひたすら解いていく!というものです。

僕はDeep Learningを用いて画像認識をしようと思ったのですが、画像処理などの前処理の技術も高めなければいけないと思い、解いてみようと思った次第です。

なぜ僕がこのような記事を作成しようと思った理由として、「検索しても解説や解法がほとんど載っていない」ということが挙げられます。もちろん、作成者のAnswerCodeはあります。しかし、あくまでも「コード」なので解説はありません。このような背景から「じゃあ僕が解説作ってやる!」となった次第です。

画像処理100本ノックをやる人の支えになれば幸いです。

本記事について

100本ノックということで100問ありますが、1問1問長いので10問ずつに区切ります。

part1(1-10):ここ

part2(11-20):https://chizuchizu.com/2019/05/08/knock-2/

part3(21-30):https://chizuchizu.com/2019/05/13/knock-3/

part4(31-40):作成中

part5(41-50):まだ

part6(51-60):まだ

part7(61-70):まだ

part8(71-80):まだ

part9(81-90):まだ

part10(91-100):まだ

本記事は

https://qiita.com/yoyoyo_/items/2ef53f47f87dcf5d1e14

https://github.com/yoyoyo-yo/Gasyori100knock

yoyoyo_さんの画像処理100本ノックの問題を使用しています。

注意

実行環境

  • Python3.7.3
  • OpenCV 4.1
  • Numpy

です。PythonとCV2のバージョンは多少違っていても動作すると思います。(Python2だと仕様も違うからそこはアレだけど

加えて、データ読み込みのところです。

pathとありますが、C\から始まる文字列です。

問題では”imori.jpg”のようになっていますが、僕の環境ではファイルパスを入れないと上手くいかなかったので注意して下さい。

一言二言

僕の解説がわからなかったり、アドバイス等ありましたら気軽にコメント、Twitterにでもリプ、DM下さい。僕は専門家ではないので、不十分なところもあると思います……

Q.1-10

Q.1 チャンネル入れ替え

imgは3次元の行列です。行列のスライスについては調べてみて下さい。

「:」は全てという意味です。

imgはBGRの順番に並んでいるので、それを入れ替えれば終わりです。

Q.2 グレースケール化

重要なところは

img2.astype(np.uint8)

です。ここではimg2の要素をnp.uint8に変換しています。

といってもどういうことかわかりませんよね。

その1行前で小数の入った掛け算をしているため、img2の要素には小数が入っている可能性があります。しかし、画像は小数が入ると表示されなくなってしまうので整数(uint8)に変換して表示できるようにしています。

Q.3 二値化

愚直にforで回しても出来ますが、どうせなら楽な方でやりましょう。

np.where関数は便利なので覚えておきましょう!

np.where(①,②,③)

  1. 条件式
  2. 条件がTrueだったときの要素
  3. 条件がFalseだったときの要素

Q.4 大津の二値化

大津の二値化です。先程はtを128としていましたが、こちらは最適なtを探すコードになります。ちょっとコードが複雑になってきましたね。

クラス内の分散は求めなくても大丈夫です。

zeros_likeは()の中にある配列と同じshapeのゼロ行列です。

大体のことはコメントに記載したので、それを参考に見てみて下さい。

Q.5 HSV変換

これは中々大変でした。自分でも解いたんですけど、フォロワーの人に教えてもらい何とか完成したんですが、コードが汚すぎたのでAnswerコードにコメントを付け足しました。

array[…, 1]

はarrayの最後のみを指定している。どういうことかというと、仮にarrayが3次元配列だとしたら、

array[:, :, 1]

と同じことをやっているだけである。

最後の次元のみを指定したいときに使える。

HSV変換は面倒です。本当に。僕は1時間では解ききれませんでした。(処理が大変)

解説コードの凄いと思ったところは、最後の条件式をlistでまとめているところですね。コードが複雑にならないようにまとめてあります。

僕は愚直にforとifを多用していました。

これはまた解くかもしれません。いつの間にか自分のコードにすり替わってるかもしれませんw

大体のことはコメントに書いたのでそれを参考にしてみてください。

Q.6 減色処理

これは比較的簡単?な方かなーと思います。

NumPyで一気にやる方法もありますが、見づらいっていうのとそもそも僕がNumPyを使いこなせてないという理由で愚直にループ回してます。

Q.7 平均プーリング

8×8の配列を取って平均をとるだけですが、その8×8の配列を上手く取得する所が難しいかもしれません。[a:b]でaからb-1までをスライス出来るのでそれを上手く使ってコードを書いていくと出来ます。

ちなみにoは2次元配列になります。

2次元以上の配列はnp.min()やnp.max()を使いましょう。

min()やmax()等の元々Pythonにある関数だとエラーが出ます。

もちろんパラメータを指定すれば出来ますが、簡単なのはNumPyです。

Q.8 Maxプーリング

先程のコードの平均を最大値にするだけです。

Q.9 ガウシアンフィルタ

これは大変でした。やる作業が多いですね……。ただ、一度出来れば何となくで組めるので良い問題だと思います。

パディングで何をするかと言うと、

周りを0で囲みます。

ガウシアンフィルタでは3×3の重み付けが必要です。端にある要素はそのままでは画素を決められません。そのためにパディングして周辺画素があるような状態にします。

あと、K(重み)の合計が1になるように調整するのを忘れると画素がおかしくなります。

忘れずに書いてくださいねw

Q.10 メディアンフィルタ

上のガウシアンフィルタではフィルターに重みを掛けていましたが、今回は平均をとるだけなので簡単になりました。

np.medianで平均が取れるのでそれを使って色々やっていきます。

ガウシアンフィルタを理解すれば後のフィルタは楽勝です。(多分)

10問終わって

画像処理と書いてありますが、大体はNumPyを使った行列演算処理です。

解法は1つではありません。たくさんあります。あくまでもこれは自分が思いついたコード(HSVだけは違うけど)というだけであって解説とは掛け離れているものもあります。

色んな解き方で解くのも面白いと思うのでぜひ一度トライしてみてからAnswerコードやこの記事を見てみて下さい。

まずは10問だけですが、100問目まで解いていきたいと思います。(暇潰しにもなってるw)

あと、不定期ですが画像処理100本ノックを解く配信もしてるので興味があれば^^

お読み頂きありがとうございました。

随時解説を更新していくので、更新されたらまた見に来てもらえると嬉しいです。

訂正

2019年5月6日

Q.10 メディアンフィルタのコメントで平均と記載していましたが、中央値の誤りです。

chizuchizu_blog にコメントする コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です