今回はJuliaImagesのQuickstartから配列と画像の関係を見てみます。結果をすぐに確認するために、前回みたうちのIJuliaを前提にします。
画像データの型
JuliaImages
では、(元の配列の型によらず)画像データを0(黒)-1(白)の範囲で扱うための特別な型を用意しています。例えば、N0f8
は8-bit整数値を1/255でスケーリングしたかのように振る舞います。
ちなみにN0f8
はNomalized, with 0 integer bits and 8 fractional bitsを意味しており、N0f16
だと16-bit depthの画像用になります。
はじめのうちはUInt8での256の階調を0-1で扱うのには違和感があるかもしれませんが、慣れると実際のデータ型によらずに統一的に数値処理できるようになるので便利なんだと思います。
配列 -> 画像
colorview
を使います。必要に応じてnormedview
も使います。
グレー画像化
JuliaImagesでは画像はあくまで配列なので、次のように配列を定義しておきます。
img = [0.0 0.1 0.2
0.3 0.4 0.5]
colorviewを使った場合
この配列からグレー画像をするにはGray
とcolorview
を使うと便利です。colorview
を使うと、元の配列への参照(view)を保持します。
imgg = colorview(Gray, img)
試しに参照元の配列を操作して画像が変わるかを見てみたのが次のスクリーンショットです。img
を操作するとimgg
の左上の色が変わったのが分かるでしょうか。
colorviewを使わない場合
色情報似たような結果はcolorview
を使わずに作ることもできますが、次の方法は配列のコピーが発生するためimgを操作してもimgcは変化しません。
imgc = Gray.(img)
UInt8の配列から画像作成
画像データは0-1に収まっていなければならないので、normedview
を使います。これはrawview
(後述)の逆ですね。
imgUInt8 = rand(UInt8, 2, 3)
Nimg = normedview(imgUInt8)
img = colorview(Gray, Nimg)
カラー画像化
次にカラー画像を見ていきます。RGBに変換する際、元の配列の1次元のサイズは3である必要があります。
img = rand(3, 2, 3)
@assert isequal(size(img, 1), 3)
imgc = colorview(RGB, img)
@assert size(imgc) == (2, 3) # viewのサイズを確認
あとはグレー画像のときと同様です。
RGB値へのアクセス
各ピクセルのRGB値には、それぞれr, g, bのメンバーとして取得できます。C++でOpenCVを使うときの感じですね。
p = imgc[1, 1]
r, g, b = p.r, p.g, p.b
画像 -> 配列
channleviewを使います。
グレー画像から配列へ
imgg = rand(Gray, 2, 3)
img = channelview(imgg)
channelview
はcolorview
のちょうど逆ですね。img
は元の画像データへの参照なので、img
を操作すればimgg
も変化します。
元の型での参照
channelview
は0-1にスケーリングした(かのような)配列を返しますが、元の画像データがUInt8の場合、直接その型でデータを見たくなるかもしれません。そんな時は、channelview
に加えてさらにrawview
を使います。rawview
の作用は前述のnormedviewの逆ですね。
img = rand(Gray{N0f8}, 2, 3)
imgv = rawview(channelview(img))
カラー画像から配列へ
チャネル数の分だけ1次元目の要素が大きくなる点にさえ気をつければグレー画像とほぼ同じ。
img = rand(RGB{N0f8}, 2, 3)
imgv = channelview(img)
@assert size(imgv) == (3, 2, 3)
まとめ
配列の画像化、もしくはその逆への変換で使ったものは下記の通りです。
- 配列 -> 画像
- colorview (画像化)
- normedview (正規化)
- 画像 -> 配列
- channelview (配列化)
- rawview (元のデータ型での参照、正規化の逆)
次はFilteringでに行こうかな。