洋食の日記

「だ・である」調ではなく「です・ます」調で書きはじめれば良かったなと後悔してる人のブログです

画像をNumo::NArrayで扱えるMagroにフィルタを追加した

はじめに

Rubyの画像処理ライブラリMagroに、フィルタをかけるメソッドを追加し、version 0.3.0としてリリースした。

magro | RubyGems.org | your community gem host

使い方

Magroは画像ファイルの読み書きにlibpngとlibjpegを必要とする。Magroをインストールすると、依存関係でNumo::NArrayがインストールされる。

$ brew install libpng libjpeg
$ gem install magro

フィルタを使うことでエンボス加工っぽいことをしてみる。

require 'magro'

img = Magro::IO.imread('sample.jpg')

kernel = Numo::DFloat[
  [ 1, 2, 1],
  [ 0, 0, 0],
  [-1,-2,-1]
]
img = Magro::Filter.filter2d(img, kernel, scale: 1, offset: 128)

Magro::IO.imsave('emboss.png', img)

Magro::Filter.filter2dメソッドに、画像とフィルタカーネルを渡す。引数としてscaleとoffsetがある。scaleはフィルタカーネルを正規化する値、offsetはフィルタ後に足す値となる。

はてなでアイコンに使用しているハンバーグの画像を、上記スクリプトに入れると次のようになる。

f:id:yoshoku:20200510013338p:plain

おわりに

追加したのは、フィルタをかけるためのメソッドのみで、ぼかしや先鋭化といったメソッドは追加しなかった。最初は、Pillowライクなものも検討したが、あれこれとフィルタを駆使するようなこともないかと思い、すっかり外してしまった。フィルタをかけるための畳み込みの実装には、いわゆるim2colを使用した(画像のブロックを並べて行列表現にすることで、画像とフィルタの畳み込みを行列積で実現する技法)。画像をNumo::NArrayで表現しているので、容易に実装できた。今後もできるだけミニマルに、できるだけRubyで実装してみようと思う。

github.com