見出し画像

R|imagerパッケージで画像処理

R Advent Calendar 2018の21日目の記事です( ˆoˆ )

imagerとは

Rで画像処理を行うためのライブラリ。
CImgというC++ライブラリがベースになっています。

この記事でわかること

インストール
画像の表現 (cimgクラス)
画像の加工(リサイズ・トリミング)
複数の画像を組み合わせる
 GIFアニメーションを作成

インストール

> install.packages("imager")
> library(imager)

※ macOS ユーザーはXQuartzを入れる必要がある
※ ビデオを扱いたい場合やBMP、TIFF、PNG、JPEG以外の形式でインポート・保存したい場合はImageMagickffmpegをインストールしておく必要がある

画像の表現 (cimgクラス)

こちらの画像を読み込んで画像がどう表現されているのか見ていきます。
(実家のわんこです 🐶)

# 画像のロード
> doggy <- load.image("imgs/doggy.jpg")

# クラスの確認
> class(doggy)
[1] "cimg"         "imager_array" "numeric"

> doggy
Image. Width: 750 pix Height: 937 pix Depth: 1 Colour channels: 3

> head(as.data.frame(doggy))
  x y cc     value
1 1 1  1 0.2235294
2 2 1  1 0.2078431
3 3 1  1 0.2078431
4 4 1  1 0.2235294
5 5 1  1 0.2235294
6 6 1  1 0.2352941

imagerは画像を扱うため4次元配列からなるcimgというクラスを使用します。
Colour channels(cc)は色チャネルといい、画像の色情報を表します。
例えば RGB画像であれば赤、緑、青の3チャネル、RGBA画像であれば透明度を加えた4チャネルです。

# JPGだと3チャネル
> doggy_jpg <- load.image('imgs/doggy.jpg')
> doggy_jpg
Image. Width: 750 pix Height: 937 pix Depth: 1 Colour channels: 3 

# 透過PNGだと4チャネル
> boar_png <- load.image('imgs/boar.png')
> boar_png
Image. Width: 1000 pix Height: 1000 pix Depth: 1 Colour channels: 4 

さらに犬の画像をグレースケール画像に変換すると、Colour channelsは輝度を表す1チャネルで表現されます。

# 犬画像をグレースケール
> gray_doggy <- grayscale(doggy)

> gray_doggy
Image. Width: 750 pix Height: 937 pix Depth: 1 Colour channels: 1

# 各ピクセルの値を確認
> gray_doggy[ , , 1, 1 ][1:5,1:5]
          [,1]      [,2]      [,3]      [,4]      [,5]
[1,] 0.1403529 0.1332549 0.1293333 0.1559216 0.1996863
[2,] 0.1246667 0.1214902 0.1175686 0.1299216 0.1722353
[3,] 0.1265490 0.1293333 0.1206275 0.1225098 0.1526275
[4,] 0.1371765 0.1402353 0.1363137 0.1299216 0.1447843
[5,] 0.1363137 0.1402353 0.1456078 0.1408235 0.1427451

グレースケール画像の場合、各ピクセルの値は1 (白) 〜 0 (黒) で表現されます。

画像の加工

■ リサイズ(resize/imresize
ピクセル数を減少・増加させ、画像を縮小・拡大する

# resize: x,yのサイズを指定してリサイズ
> resize(doggy,round(width(doggy)/2),round(height(doggy)/2)) %>% plot

# imresize: 倍率を指定してリサイズ
> imresize(doggy, .5) %>% plot

■ トリミング(imsub)
画像の必要な箇所を切り取る

# わんこ画像の上部カット
> imsub(doggy, y > 187) %>% plot

複数の画像を組み合わせる

グレースケールした犬画像とエフェクト画像を組み合わせてみましょう。
imagerは複数の画像を加算、乗算など様々な方法で画像を組み合わせることができます。

■ add: 画像の加算

# 犬画像をグレースケール
# ※ エフェクト画像とチャネル数を揃えるため+まんが風にしたかったため
> gray_doggy <- grayscale(resized_doggy)

# imlistでエフェクト画像と犬画像(cimg)をリスト化
> l1 <- imlist(resize_effect1, gray_doggy)

# 画像の加算
> add(l1) %>% plot

何か主張している犬ができた。

■ mult: 画像の乗算

# 画像の乗算
mult(l1) %>% plot

■ parmin:値の小さいピクセルを優先する

> parmin(l1) %>% plot

■ parmax:値の大きいピクセルを優先する

> parmax(l1) %>% plot


GIFアニメーションを作成

動きがあるファイルも作れてしまうようです。
先程作成したエフェクト画像と犬画像を使用してGIFアニメーションを作ってみようかと思います。

# 異なるエフェクトと犬を合成
l1 <- imlist(resize_effect1, gray_doggy)
l2 <- imlist(grayscale(resize_effect2), gray_doggy)
l3 <- imlist(grayscale(resize_effect3), gray_doggy)
doggies <- imlist(parmin(l1), parmin(l2), parmin(l3))

> dd <- "./doggy_video"
> fnames <- sprintf("%s/image-%i.png",dd,1:length(doggies))

# 各フレームを異なる画像ファイルとして保存
> invisible(map2(doggies, fnames, function(im,f) save.image(im,f)))
> f <- tempfile(fileext=".gif")

# GIF作成
> make.video(dd,f)

やたら主張の激しい犬ができた!
ちょっと目がちかちかするので調整する。

お、なんかいいのでは(何がだろう)。
まだまだ出来ることはたくさんありそうですが今回はここまで。

🐶 -- 🐶 -- 🐶 -- 🐶 -- 🐶

途中から方向性を見失った気がするけれども、よくわからない達成感が得られた。もうすぐ今年も終わるし許してほしい 👼

imagerを使いたいシーンとしては画像分析のために画質を下げたり必要な箇所を切り取ったりする場合も多いのかなと思います。
みなさんが来年も快適な画像処理・解析を行えますように^^

明日は @kilometer00さんの記事ですね、Enjoy!

参考文献

imager: an R package for image processing
・ Package ‘imager’
 GitHub

統計の本、もしくはわんこにおいしいお菓子を買うのに使わせていただきます( *ˆoˆ* )