チューリング不完全

What are you afraid of? All you have to do is try.

FAX画像で学ぶMathematicaワンライナー画像処理

FAX Advent Calendar2日目の記事です。
FAXをやっていくということなので、Mathematicaで例の画像をいじり倒して見たいと思います。

画像の読み込み

まずはMathematicaで画像を読み込みます。

img = Import["https://dl.dropboxusercontent.com/u/330501/resource/lingr.com/fax.jpeg"]

f:id:aomori-ringo2:20131225020142p:plain

URLやローカルのパスを書くことで取り込むことができます。
このImport関数はMathematica ver.9の時点で177個の形式に対応しており、Mathematicaで扱える形に変換してくれます。BMPJPEGはもちろん、PDF, AVI, LaTeX, MIDI, Maya, 3ds, QuickTimeなどあらゆる方面の拡張子に対応しており、完全に頭がおかしい。

ヒストグラム

まずはさくっとヒストグラムを出しましょう。

ImageHistogram[img]

f:id:aomori-ringo2:20131225015855p:plain


オプションを与えることで別々に表示したりできます。

ImageHistogram[img, Appearance->"Separated"]

f:id:aomori-ringo2:20131225015911p:plain

画像の変換

Binarize[img]

二値化です。オプションにより閾値をいじったり、閾値を決定する手法を選択することもできます。
f:id:aomori-ringo2:20131225022208p:plain



ImageTransformation[img, Sqrt]

与えられた関数(この場合はSqrt)によって、画素の位置を変換します。
自己主張強い感じになりましたね。
f:id:aomori-ringo2:20131225021452p:plain



f[x_, y_] := 
  With[{r = N@Sqrt[(x - .5)^2 + (y - .5)^2], 
    a = ArcTan[x - .5, y - .5], R = .5}, rn = r*r/R;
   {rn*Cos[a] + .5, rn*Sin[a] + .5}];
ImageTransformation[img, f[#[[1]], #[[2]]] &]

少しがんばることで魚眼レンズのような効果も作れます。
f:id:aomori-ringo2:20131226005141p:plain



ImagePerspectiveTransformation[img, {{0.9, 0.1, 0}, {0.3, 0.9, -0.1}, {0, 0.1, 1}}]

アフィン変換とか言うやつです。
f:id:aomori-ringo2:20131225021356p:plain

フィルタ

数が多すぎるので、適当にいくつか紹介。

Erosion(収縮処理)

Erosion[img, 2]

f:id:aomori-ringo2:20131226020046p:plain

Dilation(膨張処理)

Dilation[img, 2]

f:id:aomori-ringo2:20131226020058p:plain

木炭デッサン効果

ImageEffect[img, "Charcoal"]

f:id:aomori-ringo2:20131226020111p:plain

ポスタリゼーション

ImageEffect[img, {"Posterization", 5}]

f:id:aomori-ringo2:20131226020124p:plain



その他にもClosing, Opening, ガウシアンフィルタ、中央値フィルタ、油絵効果、ソラリゼーション・・・などなどとにかくいっぱいあります。
こんな感じで画像処理を簡単に書けるわけです。

特徴抽出

EdgeDetect[img]

エッジ抽出です。抽出手法はデフォルトだとCannyが使用され、Sobel, ShenCastanを選択することもできます。
f:id:aomori-ringo2:20131226014021p:plain



Show[img, Graphics[{Thick, Yellow, Line/@ImageLines[EdgeDetect[img]]}]]

ImageLinesは線分を抽出する関数です。上記コードは、エッジ抽出した結果から線分をもとめ、それを元々の画像と重ねあわせて描画します。
パラメータを変えることにより、線分がとれすぎたりとれなさすぎたりします。
f:id:aomori-ringo2:20131226013113p:plain



この他に交差点抽出、特徴点抽出などの関数があります。

文字認識

TextRecognize[img, Language="Japanese"]

画像から文字を抽出します。ファックス画像からは残念ながら抽出できませんでした。もともと英語圏のソフトですから、縦書きには弱いようです。
横書きの日本語が含まれた画像でやってみましょう。
f:id:aomori-ringo2:20131225004044p:plain

イラスト部分からヘンなものまで読み取ってしまっていますが、「進捗どうですか」が取得できていることがわかりますね。


おまけ: キャプチャ

CurrentImage[]

CurrentImageと書くだけでWebカメラの画像を取り込むことができます。


CurrentImageで取得した画像はこれまでの画像と同じように扱えるため、画像処理をかけていくことができます。

EdgeDetect[CurrentImage[]]

エッジ抽出された私です。
f:id:aomori-ringo2:20131226021003p:plain




これをDynamicに渡すと画像ストリーム取り込みとなり、Webカメラの画像をリアルタイムで表示します。

Dynamic[CurrentImage[]]

実行すると、Mathematica上でWebカメラの映像が見えるようになります。楽です。

まとめ