はじめに
PythonではOpenCVとScikit-imageという画像処理ライブラリがある。これらライブラリでは、画像データをNumPyのndarrayで表す。
>>> from skimage import io >>> img = io.imread('lena.png') >>> type(img) <class 'numpy.ndarray'>
同じような感じで、画像データをNumo::NArrayで扱うものが欲しくなったので作り始めた。名前は、Image ProcessingからとってMagroとした(Gem名を考えているときに、ふと「そういえば鮪ペイントって昔あったよな」と思い出したのもあって)。実はまだ、pngとjpegを読み書きすることしかできないが...
magro | RubyGems.org | your community gem host
インストール
Magroでは、pngとjpegの読み書きにlibpngとlibjpegを使用するため、これらを先にインストールする。メジャーなライブラリなので、なにかしらパッケージがある(環境によってはすでにインストールされている場合もある)。
$ brew install libpng libjpeg
Ubuntuなどlinux系であれば適当なパッケージマネージャで:
$ sudo apt-get install libpng-dev libjpeg-dev
Magroは、gemコマンドでインストールできる。
$ gem install magro
使い方
Magroでは、まだ、pngやjpeg画像の読み書きしかできない。画像の形式はファイル名の拡張子で判定している。例えば、有名なRGBなPNG画像ファイルをグレイスケールにするならば、以下のようになる。
[1] pry(main)> require 'magro' => true [2] pry(main)> img = Magro::IO.imread('lena.png') => Numo::UInt8#shape=[512,512,3] [[[226, 137, 125], [226, 137, 125], [223, 137, 133], ... [3] pry(main)> gray = img.median(axis: 2) => Numo::UInt8#shape=[512,512] [[137, 137, 137, 136, 138, 129, 138, 134, 140, 136, 135, 134, 130, 139, ...], [137, 137, 137, 136, 138, 129, 138, 134, 140, 136, 135, 134, 130, 139, ...], [137, 137, 137, 136, 138, 129, 138, 134, 140, 136, 135, 134, 130, 139, ...], ... [4] pry(main)> Magro::IO.imsave('lena_gray.png', gray) => true
画像データはNumo::UInt8で表現されるので、Red ChainerのConvolution Netsに投げるとか、Numo::DFloatなベクトルに変換してRumaleのRandom Forestに投げるとかできる。
おわりに
Rubyの画像処理ライブラリとしては、RMagickをはじめImageMagickをbindingしたものや、OpenCVをbindingしたものがある。OpenCVでは、画像をCvMatというOpenCVの行列型で表現する。行列の表現がNumo::NArrayでなくてもOKで、画像を行列で欲しい場合は、RubyであればOpenCVのbindingが良い(ただし対応しているOpenCVのバージョンは2系の様子)。
Magroは、PythonのScikit-Imageや、C言語のVLFeatあたりの雰囲気を目指して、あまり大きくならない程度に開発する予定。次は、画像にフィルタをかけるには、畳み込み演算が必要で、そのためのフーリエ変換をなにかしら組み込むとかかなぁ。