フォルダ内の重複画像を取り除きたい(2)

NNC Utilsで指定可能なハッシュ方法の説明を追記しておきます。

Hash方法

Average hash

画像を縮小した後に全画素の平均値を取得します。縮小画像の画素が求めた平均値よりも明るい(1)か暗い(0)かを元にハッシュ値を生成します。

画像の全体的な輝度や若干の色調補正が加わっていても、同じ画像と見なすことが出来ますが、縮小した結果が似たような画像だと適切な区別ができなくなります。

Perceptual hash

画像を縮小した後にDCT(離散コサイン変換)をかけます。求めた結果から低周波成分を取り出し、中央値を取得します。高周波成分を取り除くという事は、画像からノイズ(小さな差異)を取り除くという事になります。

求めた低周波成分領域から中央値よりも大きい(1)か小さい(0)かを元にハッシュ値を求めます。

一旦周波数に変換すると、直接の画素的な位置情報が失われてしまいますが、全体的に似ている(同じ様な周波数を含んでいるか)かどうかを区別する際に使用します。

Perceptual hash (simple)

Perceptual hashと同じですが、DCTの計算を一回、中央値を使わずに平均値を使用しています。

Difference hash

画像を縮小した後に、左右の画素同士を比較して、どちらが明るいかを求めます。

Average hashは画素全体の輝度から平均を求めるため、細かな差異が埋もれてしまう場合がありますが、こちらを使用するとうまく拾い出せる場合があります。

画像の一部分部分だけが異なっているものを区別したい場合に有効ですが、比率が異なる画像を違うものとみなしてしまう場合や、ノイズを有効な画素と見なしてしまう場合があります。

ある画像と同じ画像をJPEGで圧縮して劣化させた画像を同じものと見なしたい場合には良い結果が得られません。

Difference hash (vertical)

Difference hashと同じですが、画像比較を上下で行います。

Wavelet hash

画像を縮小した後に輝度情報を0.0〜1.0の範囲に変換し、wavelet変換(haar)を行います。変換結果から低周波成分の結果を取得し、中央値を求めます。

求めた低周波成分領域から中央値よりも大きい(1)か小さい(0)かを元にハッシュ値を求めます。

Perceptual hashと似たような処理ですが、waveletはDCTに比べてより適切な分解を行うことが出来るため、Perceptualよりも適切な区別が期待できます。

imagehashが使用できるアルゴリズムで最も重い処理となります。

.

ニューラルネットワークで要素抽出

Autoencoder

ニューラルネットワークは画像を認識させる際に、元情報よりも低次元で表現するようにネットワークを構成することが出来ます。

そのような低次元で表現された空間には、学習に使用した情報の要素が詰まっているとも言えます。

要素が詰まっているのですから、その情報を抜き出して再び画像にすれば、ニューラルネットワークが思っている物の片鱗を見ることが出来る…かもしれません。

技法的にはオートエンコーダと呼ばれるものなのですが、画像認識に使用しているヴィヴィオ達の画像を使用して計算させてみました。

Autoencoderを通したヴィヴィオ達

結果は以下のような感じです。

   

多分、リリカルなのはVividをよく知っている人であれば、誰か答えられるのではないかと思います。

今回は100次元で表現してみましたが、多分もっと少ない要素で表現出来そうで、ヴィヴィオ達は見た目だけでもかなり分類しやすそうに感じます。(…ってプロの方がそうなる様にデザインされているわけですから、そりゃそうなりますね。)

次元数を下げるほどぼやけた画像になっていき、極端に下げると「黄色っぽい」「みどりっぽい」だけの画像になります。

学習結果の応用

この学習は、

  • 「ヴィヴィオの絵」 + 「ヴィヴィオ」
  • 「アインハルトの絵」 + 「アインハルト」
  • 「リオの絵」 + 「リオ」
  • 「コロナの絵」 + 「コロナ」

という入力で学習させましたので、以下の様な入力を受け付けます。

  • 「ヴィヴィオの絵」 + 「アインハルト」
  • 「写真」 + 「ヴィヴィオ」

これを使えば、入力された画像をヴィヴィオっぽくしたり、アインハルトっぽくしたりする事が出来そうです。

試しに自分の絵を使って実行してみたものがこちら。

  •  =  + ヴィヴィオ
  •  =  + アインハルト
  •  =  + リオ
  •  =  + コロナ

…心の目で見ればなっているような、なっていないような。

今回やったことを図にすると、以下の様になります。

 学習させます。

 学習結果とヒントを使い、絵を加工。

Azure上でnnablaを動かしてみました

現在使用しているAzure環境にnnablaをインストールして、ウェブアプリを作成してみました。

nnablaはSONY Neural Network Consoleでも使用されているもので、比較的簡単にニューラルネットワークを利用出来るのですけど、学習した結果をどう使うかがなかったので、サンプルを兼ねて作ってみました。

VE Detect

https://www.mizunagi-works.com/gadgets/ve_detect/index.html

 しょっぱなから誤判定するデータを与えていたりして

言い訳っぽいのですけど、これは学習データが少ないのと「アインハルトかヴィヴィオのどちらか」を判定させるように学習させた結果となります。

例えばおにぎりの画像を与えたときでも必ずどちらかという判定します。(どちらでもないという回答を出すようには学習させていません)

Azureへの導入

ニューラルネットワークというと、強力なGPUを使用する負荷の高いアプリケーションに感じられるかもしれません。

確かに計算量は多いのですが、処理が重たいのは学習をする時で、学習済み結果を利用するのはそんなに重くありません。

(今回作成したニューラルネットワークの構成が単純というのもあります)

自分が使用しているAzure上のVMはA1 Basicでかなり非力(下から2番目)なのですが、学習結果を利用するにあたってはそこまで負荷はありませんでした。

SONY NNCによるネットワークの作成と学習

こんなネットワークにしてみました。

10,000回ほど学習させました。

プログラムの作成

学習が完了すると、学習結果が保存されたフォルダにparameters.h5というファイルが生成されています。

学習済みモデルを利用するにはこのh5ファイルと、NNCからエクスポートしたPythonスクリプトが必要となります。

スクリプトはちょっと長めですのでGitHubに置いておきました。

bottleを使用していますので、ローカルでこっそり楽しむことが可能です。

.

Neural Network Libraryで遊んでみる

SONYのNeural Network Libraryを使ってみてのメモとか。

NNLで画像を読み込みたい場合

モデルに画像を読み込ませるには、nnabla.utils.data_source_loaderモジュールで読み込ませる事が出来ます。

Pillowで読み込んだ画像をNNLで扱える構造にしたい場合

numpyモジュールを使います。

 

ISO-2022-JP-MSからCP932への変換

使用する機械はあまりなさそうでうけど、ISO-2022-JP-MS(JIS)からCP932(SHIFT-JIS)へ変換するコードを、以下のサイトに掲載されているプログラムを移植してみました。

http://www.geocities.jp/hoku_hoshi/TIPPRG/tipprg03.html

プログラム本体

テストデータ

テスト方法

上記の様なテストデータをUTF-8で作成して、iconvやnkfを使用してjis形式のファイルに変換します。

iconvの場合

nkfの場合

.

Neural Network Consoleでキャラ判定

SONYが公開しているNeural Network Console を使用して、キャラクター判定をさせてみました。

NNCはWindows用なのですが、学習させたモデルの利用はMac(Anaconda + Python 3.6)でも動作しました。

ヴィヴィオとアインハルトのみですので適当に答えても50%の確率なので、あまり面白みはないけど…

Neural Network Console

https://dl.sony.com/ja/

SONYが公開しているニューラルネットワークを作成するためのGUI環境です。

今回は以下のようなネットワークを作成してみました。

 ネットワーク構成

 学習状況(2000Epoch)

画像データはBingの画像検索を使用してヴィヴィオとアインハルトの画像を収集しました。

画像については以下のルールで生成しています。

  • 変身前か変身後は関係なくキャラクター毎に30枚程度を用意
  • 描かれているキャラクターは一人だけ(背景はあってもなくてもよい)
  • 画像サイズは64×64に縮小(パディングは0(黒)で行う)

画像はかなり少ないのですが2000Epoch程学習をさせて、評価を行います。

評価方法

NNC上でも評価出来るのですが、生成したモデルをPythonやC++から使用することが出来ます。

今回は以下のようなコードを生成しました。

学習結果はフォルダにHDF5形式で格納されていますので、そのまま使用することが出来ます。

ソースコードもNNCが生成したものをそのまま使用可能となっています。

評価に使用するデータ

画像は自分が描いた2枚の画像を使用してみました。

 ヴィヴィオ( vivio = 1 )

 アインハルト( einhald = 0 )

実行結果

 0.978

 0.042

0に近いほどアインハルト、1に近いほどヴィヴィオという判定が出るように学習させましたので、どうやら正しく判定してくれたようです。

自分以外の絵でも試してみましたが、正答率は80%ぐらいでした。

.

文書の類似度判定(3)

データベースに文書を保存するまでが出来たので、やっと本題の類似度判定を。

データベースから文書を取り出して学習と判定を行う

やっていることは、データベースから二文字以上の名詞を取り出して学習用データを生成して、与えたキーワード、文書に似ている(近いベクトルのもの)を取得しています。

実行すると以下のような結果が表示されます。

学習させた文書は、Pixiv百科事典からキャラクター名の項目をテキスト化したものを与えています。

ヴィヴィオに関連するものとして、

  • アインハルト
  • リンネ・ベルリネッタ

といったキーワードが出力されています。

与えた文書量が少なく、文書自体も短いためなんとなくうまくいっているようないないような。

文書の類似度判定(2)

まずはjanomeを使用して形態素解析を行います。

カスタム辞書を指定していますが、指定しなくても動作します。

janomeによる形態素解析

word2vecを使用するには形態素解析したデータをもとに分かち書きを作成する必要があります。

毎回形態素解析をして生成しても良いですが、ここでは形態素解析をした結果をデータベースに一旦保存した後、必要な情報を取得できるようにしてみます。

janomeによる形態素解析とデータベースへの保存

前述のコードを修正してデータベース(ここではsqlite3)へ保存するようにしたもの。

.

potraceGUI for Win32を公開しました

GitHubで公開しているpotrace_guiのバイナリパッケージを作成してみました。

セットアップ等はありませんので、zipファイルを展開して適当な場所に配置してください。(もしかしたらデスクトップに展開した場合はちゃんと動作しないかも)

Download

PotraceGUI for WIn32

potraceGUI.zip

.

(ウイルスチェックはVirusBarrierを使用しています)

アーカイブ内に以下の物が同梱済です。

potrace – Transforming bitmaps into vector graphics

http://potrace.sourceforge.net/

potrace_guiの説明

コマンドラインツールであるpotraceに簡易GUIを追加したものです。簡易的ですがプレビュー機能を搭載していますので、コマンドライン上でトライ&エラーを何度も繰り返すよりは楽…かもしれません。

potrace_gui使用方法

アプリケーションの起動

potrace_gui.exeを起動すると以下の様なWindowが表示されます。コマンドプロンプトが一緒に立ち上がってきますが無視してください。

 起動してすぐの状態

ファイルの読み込み

左上ツールバーのOpen()をクリックすると、ファイル選択ダイアログが表示されますので、変換したいビットマップ画像を指定して下さい。

しょぼいですがBMPファイルしか扱えませんので、元画像はビットマップファイルに変換しておいてください。カラー画像も読み込めますが、あらかじめモノクロ化しておいた方がより良い出力結果が得られます。

 レヴィとコロナちゃん

読み込みが完了すると、右側にプレビューが表示されます。プレビュー画面はスクロールさせたりドラッグする事で領域を切り替えることが出来ます。

 これ(BMP画像に変換したもの)を変換しました。

ファイルの変換

読み込んだ状態のままだと、やや線が細いため黒の部分をより多く抽出させてみます。

左側メニューにある「-k, –blacklevel」という項目を、0.5から0.85に変更してから、refresh(をクリックするか、Ctrl+Rでプレビューが更新されます。AutoRefresh()を押しておくと何らかのパラメータが変更される度に自動更新されます。(ファイルサイズが大きいときには動作が重くなるのでご注意を)

ファイルの保存

パラメータの調整が終わったら、BACKEND TYPESから出力形式を選んだ後にSave As..をクリックして下さい。

ファイル保存ダイアログが表示されますので、任意の場所を選んで保存して下さい。

各項目の説明

ほとんどの場合、変更すべきパラメーターは-k, –bkacklevelの値を変更するだけだと思いますが、以下にパラメータの説明を記載します。

-z, –turnpolicy

ビットマップ画像をどのようにパスに変換するかのルールを設定します。デフォルト設定値はminorityです。

.

-t, –turdsize

 

指定した値以下の曲線を除去します。曲線部の認識方法は、turnpolicyの設定に依存します。0以上の値が設定可能で、デフォルト設定値は2です。

.

-a, –alphamax

 

検出されたコーナーをどの程度滑らかに繋げるかを設定します。0.0が曲線無し、1.3334が全て曲線となります。デフォルト設定値は1.0です。

.

-n, –longcurve

なるべく少ない分割数でカーブを割り当てるようにします。

.

-O, –opttolerance

 

正確さを犠牲にする代わりに制御点の数を減らす事で単純化を図ります。0以上の値が設定可能で、デフォルト設定値は0.2です。

.

-u, –unit

 

出力時の1ピクセル当たりの内部分割サイズを設定します。値を大きくする事でより細かい精度で出力されます。1以上の値が設定可能で、デフォルト設定値は10です。

.

-k, –blacklevel

 

グレイスケール画像を与えた場合、黒と認識する閾値を指定します。指定範囲は0.0〜1.0で、1.0に近づくほど黒とみなされる領域が増えます。デフォルト設定値は0.5です。

.

-i, –invert

白黒を反転します。

.

-P, –pagesize

出力画像サイズを指定します。

–tight

有効にすると周囲の余白(線画認識されなかった領域)が削除されます。

Download

PotraceGUI for WIn32

potraceGUI.zip

.

(ウイルスチェックはVirusBarrierを使用しています)

Splinterによるブラウザ制御(2)

Windows版でSplinter + firefoxを使用すると、CERTIFICATE_VERIFY_FAILEDが出てしまう問題に無理矢理対応。

SSLでの接続時に以下の場所でエラーになっているため、確認処理を無視するように変更。

こんな感じに…

エラーは出なくなるけど危険です。

splinterによるブラウザ制御(1)

ウェブアプリケーションの開発をする際に、実際のブラウザで動作確認を行う、といった場面があるかと思います。

単純なHTTPの通信テストであればスクリプトでもなんとかなる場合もありますが、javascriptを使用している場合、javascriptの動作結果や挙動についても検証する必要があります。

こういったテストを行う場合、大抵は外部からブラウザを制御して行います。

有名どころとしてはSeleniumだと思いますが、今回はあえてsplinterを使用してみました。

インストールは pip から。

ちなみに標準ではfirefoxを使用しますので、 firefoxのインストールをしておく必要があります。

簡単な使用方法

こんな感じに記述します。

上の例では、firefoxを開き http://mizuvm01.cloudapp.net/wp を開きます。

ページ遷移後はhtmlやタグやIDの検索をする事が出来ます。

単純な表示だけでは面白くないので、うちのサイトから画像を取得するプログラムなんぞを作ってみます。

やることは以下の三つです。

  • 水凪工房のウェブサイトを開く。
  • 「魔法少女リリカルなのは」を検索する。
  • 表示されている画像をダウンロードする。

画像のダウンロードについてはsplinterで処理するのは困難なため、requestsモジュールを追加します。

インストール出来たところで、早速こんな感じのコードを書きます。

かなりいい加減なコードですが、こんな感じとなります。

 

Twitter API とか

Twitter Streaming API を使う上でのサンプルをメモ。

Streaming API は Search API 同様 OAuth 認証を使用していますので、Search API のサンプルとまとめてみました。

プログラムは、ふゆみけさんのウェブに記載されているものを参考にしました。

http://d.hatena.ne.jp/fuyumi3/20111205/1323087002

上記のコードを実行するには、利用するPython環境にoauth2がインストールされている必要があります。

また、Twitter API を利用可能にしておく必要があります。

watershedによる領域分割

少し前の記事でGmicのcolorizeが便利そうでしたので、Gmic内のスクリプトを読みながらopencvで似たようなことをやってみました。

Gmicはsourceに含まれているgmic_def.gmicに処理手順が書かれているため、同じことができるんじゃないか…と思ったのですが、なかなか難しいかも。

pyopencv2を使ってwatershedを中途半端に実装してみた例

gmic_def.gmic内のスクリプトによると、__x_colorize内でpotential mapというのを生成し、それを領域分割時に参照しているようなので、まずはここの処理と同等のものを作ってみることにしました。

ラインアート処理部なので、

  1. [Layer1] blur 0.05%
  2. [Layer1] normalize 0.0 〜 1.0
  3. [Layer1] Layer1に対して blur 0.5% したものを[Layer2]に出力
  4. [Layer1] pow(べき乗計算) 10
  5. [Layer1] normalize 0.0 〜 1.0
  6. [Layer2] normalize 0.3 〜 1.0
  7. [Layer1] と [Layer2] を min 合成

といった処理をこんな感じに読みかえ。

ガウシアンフィルタのパラメータを理解していないため、数値は適当です。

 plotしてみる。

 watershed…だめかも。

 potential map

 

塗り分け処理を行っている部分も移植しないとあんまり意味がなかったり。

OpenCVを直接使用するのは初めてだったけど、Python用のライブラリも含まれているのでありがたかった。

MacOSX用のMakefileの生成にはCMakeが必要なのですが、以下のオプションのチェックを外しておきました。

  • BUILD_SHARED_LIBS
  • BUILD_TESTS
  • WITH_1394
  • WITH_FFMPEG

参考:http://blogs.wcode.org/2014/10/howto-install-build-and-use-opencv-macosx-10-10/

Render color map, Manage replace color mode, Render base image, Render viewの部分が理解できないと絶望的かも。

potrace を GUI 化(2)

だいぶ形になってきたので、サンプル画像らしきものを掲載してみます。

元々コマンドラインで使用していたので、作っておきながら使うときはあまりないような気がしますけど、Qtのアプリケーションをどの様に作っていけば良いのかの練習にはなりました。

 アリサちゃん

GUI のアプリケーション部分は気の利いた処理も何もなく、potrace 用のコマンドライン引数名そのままですので、判りづらいです。

 名称はコマンドライン引数名そのまま

同じ様な GUI フレームワークとしては wxWidgets があるのですけど、そちらよりも GUI 部分が組みやすい感じがしました。

問題になりそうな部分としては Qt のライセンス形式かもしれません。(特に、Python で作成する場合は、 Python + Qt + PyQt が必要になるため)

 

potrace を GUI 化(1)

Qt を使用して GUI アプリケーションを作成

せっかく Qt を導入したので、 Qt を使用したアプリケーションを作成してみました。

potrace に指定可能なパラメータ全てをそのまま貼り付けてあるため、 potrace を知らないと何を言っているのかわからない設定項目になってしまっていますけど…

potrace の出力を QGraphicsView に出力しているだけなのですが、適当に作った割にはそれっぽい動作をしてくれている感じです。

実行には Python3 と PyQt5, potrace が必要になるのですが、作成中のソースコードを Github にアップロードしておきました。

https://github.com/MizunagiKB/potrace_gui

 

Windows Azure の モバイルサービス

モバイル サービスについて

Windows Azure で利用できるサービスの一つに モバイル サービス というのがあります。

モバイルサービスと書かれてしまうとなんなのか判りづらいのですが、

  • REST 経由で使用可能なデータベース(20MBytes の場合は無料)
  • 認証機能
  • モバイルへのプッシュ通知
  • スケジュール

といったサービスをセットで提供してくれるものとなります。

ちなみにウェブサービスを提供するものなので、ウェブサイト用のスペースは提供されません。(ウェブサイトが必要な場合は、別途 web sites や virtual machines の契約が必要です)

モバイルサービスを開始すると、以下の様な画面が表示されてサンプルコードや組み込み例を提供してくれます。

azure_mobileservice

提供してくれるのはありがたいのですが、 Python 用のサンプルコードがありませんでした。

というわけでメモがてら記述しておきます。

REST insert / select / update / delete

 ■

どうという事のないコードですが、適当に記述するとこのような感じです。

Azure モバイル サービスの REST API リファレンス

http://msdn.microsoft.com/library/jj710108.aspx

上に記載したコードには select に関して単純なフィルターしか指定していませんが、色々な条件を指定する事が出来ます。

$filter の指定方法は、OData の URL Conventions に記載されています。

 

PyQt5 で GUI アプリケーション

Python には昔から Tk という GUI ライブラリが付属しているのですが、あまりかっこよくありません…

勿論、目的が達成出来れば問題ないのですが、やっぱり見た目がかっこいい方が開発していて楽しいかも?ということで、 MacOSX 上に PyQt5 の環境を構築してみることにしました。

インストール作業

Qt のインストール

http://qt-project.org

PyQt5 は Qt をラッピングしたモジュールなので、まず Qt を用意しなければいけません。

Qt には Online Installer が用意してありますので、それを使用してインストールします。

そのうち指定しなくても良くなるかと思いますが、MacOSX 10.9 上で build をしている場合は、環境変数にあらかじめ 10.8 という値を設定しておきます。

Python 3.4 のインストール

https://www.python.org

標準の MacOSX には Python3 がありませんので、 Python3[1. この記事を書いている時点では 3.4 が最新バージョンでした。]をインストールする必要があります。

…の前に Marvericks 環境に必要なツールをインストールしておきます。

インストールが終わったら、

インストール先を好きな場所にしたい場合は、 ./configure オプションの –prefix を使用する事でインストール先を任意の場所に変更することが出来ます。

sip のインストール

sip は C/C++ 用のモジュール(dll や so)を Python から呼び出せるようにするためのモジュールです。 PyQt5 は Qt を呼び出すために sip を使用するので、事前にインストールしておく必要があります。

PyQt5 のインストール

ここまで完了したらやっと PyQt5 のインストールを始める事が出来ます。

PyQt5 の build には Qt 用の make ツールである qmake と、事前にインストールした sip が必要となります。

インストール場所を以下の様に指定します。

PyQt5 のビルドにはかなりの時間がかかります。

ビルド後の確認方法は、 PyQt5 に添付している example を実行することで試せます。

とすることで、各種デモを呼び出せるメニューアプリケーションが起動出来ます。

メニューアプリケーション自体が PyQt5 製になっています。

pyqt_demo こんな感じ。

おまけ

cx_freeze を導入しておくと、アプリケーションの配布に便利です。

http://cx-freeze.sourceforge.net

bottle.py の egg 化

bottle.py の stable(0.12.7) は、 setup.py 内の指定が

となっているため、

といった感じで egg ファイルを生成する事が出来ません。(もっとも、 bottle.py は1ファイルだけで構成されているため、 egg 化するまでもないのですが…)

egg 化したくてしょうがない場合は、前述の場所を以下の様に書き換える事で egg ファイルを生成する事が出来ます。

 

Twisted を使用した proxy

Twisted を使用した Proxy のサンプルについての記録。

オリジナルは GitHub Gist で公開されている tcp-proxy.py となります。

Proxy を実現するには、 squid や Delegate 、 HAProxy といったものがありますが、 tcp-proxy.py は Twisted を使用した Python スクリプトとなります。

設定ファイルやコマンドライン引数などはなく、待ち受けと転送先を変更するにはそれぞれ 57 行目と 75 行目を書き換えるだけです。

Twisted の特徴は、イベント駆動と Defferred オブジェクトである事でしょうか。この二つを使用する事でポーリング処理が不要になるのと、処理を時系列に記述する事が出来るという利点があります。

自分は Deffered を理解するのに結構時間がかかってしまいました。

スペースハリアー風味の床描画(3)

スペースハリアー風味の床描画プログラムを手直ししてみました。

あんまり見た目は変わってないですが、影描画の処理の追加を行っています。

game_ss03 ありがちなポスト処理とか入れてみたり。

描画オブジェクトを Z ソートしていないため、前後関係があやしいですけど…

単純な半透明影を落としてしまうと同じ場所に落ちた影同士が段々と暗くなっていくため、影だけを描画するレンダーターゲットを用意して、最後に合成しています。(影の解像度が低く見えるのは、レンダーターゲットの解像度が低いからです。)

システム自体は Nebula Device 2 を使用している為、影の描画部分以外はシステム内蔵のシェーダーをそのまま使用しています。