Python + OpenCV

とある朝、FreeBSDでpkg upgradeしたら、巨大なpkg(LLVM39,size=244M)が対象になっていた。落ちるまでに 20分はかかりますって言ってきた。まあ、海の向こうからやって来るんでしょうがない。

転送スピードが報告されるんだけど、最初は300k/s ... 200k/s ... 100k/s と、段々 落ちて、最後はストップ。

ネットワークの不調の前兆はあり、隣の7機で国内のサイトをアクセスしても、超が付くほど 遅い。ありゃ、無線送信機が壊れたか?

階下のipadをみたら、電波を受信してない。あーあ、決定的だな。パソコン使うの暫く休止 しよう。そして、その間に無線機を電源断して休ませよう。復興の確認はipadで手軽に 出来るからね。

で、儀式を執り行っても、一向ににipadは電波を受信せず。えーと、こうなったら、光終端装置 も休ませるか。大停電させて再起動してもだめ。

そのうちに女房が起きてきた。ipadおかしくなかった? って、聞くと、昨夜使ってたら、 ネットワークがどうのとか言ってきたので、使うの止めたとか。

もう一度、パソコンに向かったら、ネットワークは復してた。ipad死んでる。4年で昇天か。

で、真面目観察したら、よそのSSIDはちゃんと受信してるぞ。そうなると、今までの接続 情報を忘れてしまってるな。再設定したら、生き返った。これで、2度目ですよ。ぼけの 始まりは、ご主人様に似るのか。

この騒動の後遺症が一つ出てきた。終端装置がDHCPを兼ねてるんだけど、IPの払い出しを MACと紐づけしなくなってしまった。振られるIPがふらふらしてる。

しょうがないので、IPを手早く確認するbatを書いたぞ。

~ $ cat ip.bat
@echo off
ipconfig | find "172"

grepの代わりにfindを使うのはいいんだけど、検索文字列を常に囲んでくれってのは、 腐った仕様だな。

で、こんなWindows機に振られたIPアドレスを気にするか? VMWareとかから、Windows側に 建てたX serverにアクセスするのに、IPが必要だから。IPアドレスが変わるって言っても、 なんらかの規則性が有るに違いない。

これはもう、実験計画法の世界だな。計画を立てて検証してみよう。Windows10機は、起動が 速いので、常にcoldStartさせてる。7機は、遅いので、サスペンド/レジュームをしてる。

7機が起き上がった時、前に使ってたIPを使おうとしてDHCPに要求する。10機の方は、IPに こだわりが無いので、DHCPサーバーの言うがままになってる。こういう仮定で実験計画を 立案すれば良いかな。なお、ipadは、休んでいても、IPをずっとキープするように、適当な 時間間隔でDHCPサーバーと通信し、IPアドレスを独り占めしてる。(ですよね、あぷるさん)

こんな推測で、どうでっしゃろ?

OpenCV

先月買って積読になってた、日経ソフトウェアを見てる。タイトルにあるpythonとopencv とかいうのを組み合わせて、画像から人の顔を認識させましょなんてのが出てた。 面白そうなので試してみるかな。

普通に記事をなぞるだけじゃつまらないので、ちょいと下調べ。OpenCVってのをよく知らない ので、まずは本山参拝。

OpenCV

有名な所みたいで、案内が出てたぞ。

OpenCV-Pythonチュートリアル

OpenCVとは? 最新3.0の新機能概要とモジュール構成

アドベンドカレンダーにも登録されてるぐらいだから、注目されてるのね。

OpenCV Advent Calendar 2016

OpenCV Advent Calendar 2015

ならば、自前でコンパイルしてみるかな。ソースを取ってきて configureじゃなくてcmakeで やるようだ。

[debian opencv-3.2.0]$ mkdir build
[debian opencv-3.2.0]$ cd build
[debian build]$ cmake ../
-- Detected version of GNU GCC: 49 (409)
-- FP16: Feature disabled
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found suitable version "1.2.8", minimum required is "1.2.3")
-- Could NOT find TIFF (missing:  TIFF_LIBRARY TIFF_INCLUDE_DIR)
    :
--   Install path:                  /usr/local
--
--   cvconfig.h is in:              /tmp/opencv-3.2.0/build
-- -----------------------------------------------------------------
--
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/opencv-3.2.0/build

ソースのTopに置いてある、CMakeLists.txtっていうのが、cmakeの種になるみたい。 cmake中に、必須のモジュールを自動取得してたぞ。後は、makeするだけです。

[debian build]$ time make -j2
  :
[ 34%] Generating test_precomp.hpp
[ 34%] Generating test_precomp.hpp.gch/opencv_test_objdetect_Release.gch
In file included from /tmp/opencv-3.2.0/build/modules/objdetect/perf_precomp.hpp:14:0:
/tmp/opencv-3.2.0/modules/highgui/include/opencv2/highgui.hpp:784:1: fatal error: can’t write PCH file: デバイスに空き領域がありません
 } // cv

real    1m22.351s
user    2m30.492s
sys     0m8.080s

なんと、2GのRAMDISKを1分半にも満たない時間で消費しつくしてしまってる。この分だと 6G以上のエリアが必要になりそうだな。自前で作るのは止めて、anacondaに任せましょ。

[debian ~]$ conda install -c menpo opencv3=3.1.0

面白そうなので、Windows7機のDebianにも入れておこうとしたら、そんなパッケージは 無いと言われたよ。

アプルが提供するiOSも新しいやつは、64Bit版しか対応しないって言うし、32BitCPUは、 どんどんと見捨てられる運命なのね。家にあるやつもボケ始めたので、良い潮時かも。

ちなみに、どんな版が有るかは、下記のように確認出来る。最初、menpo って何か 分からなかったけど、こうしてみるとレポジトリィーのサイト名なんですなあ。conda用語 では、チャンネルって言うらしいけどね。

[debian ~]$ conda search -c menpo opencv3
Fetching package metadata ...........
opencv3                      3.1.0                    py27_0  menpo
                             3.1.0                    py35_0  menpo
                          *  3.1.0                    py36_0  menpo
                             3.1.0                    py34_0  menpo
                             3.2.0               np111py34_0  menpo
                             3.2.0               np111py35_0  menpo
                             3.2.0               np111py27_0  menpo

面白いの見つけた。

島の海岸線の長さを推定してみる

輪郭線の長さや、囲まれたエリアの面積を求められるとな。20日のマッサージで小顔実現とか やってて、befor、afterの写真がよく出てるけど、化粧とかでごまかしていないかい。 そういう悪だくみは、OpenCVを使えば、一発だな。

sample

ソースを取ってきて嬉しいのが、各種サンプルが付属してる事。pythonっていうdirの中に 各種の例が収められている。しかもそれが、demo.pyから簡単に呼び出せる事。

例えば、histなんてのが有る。起動すると、

running: hist.py
usage : python hist.py <image_file>
 Histogram plotting

    Keymap :

    a - show histogram for color image in curve mode

    b - show histogram in bin mode

    c - show equalized histogram (always in bin mode)

    d - show histogram for color image in curve mode

    e - show histogram for a normalized image in curve mode

    Esc - exit

こんな操作板と共に、有名な帽子を被った女性の写真が出てくる。(レナって名前らしい。)

画像の上でどれかキーを選ぶと、相応のグラフが出て来るんだけど、横軸は何だろう? こういう所から調べていって、知力を段々と付けていくんだな。

def hist_lines(im):
    h = np.zeros((300,256,3))
    if len(im.shape)!=2:
        print("hist_lines applicable only for grayscale images")
        #print("so converting image to grayscale for representation"
        im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    hist_item = cv2.calcHist([im],[0],None,[256],[0,256])
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX)
    hist=np.int32(np.around(hist_item))
    for x,y in enumerate(hist):
        cv2.line(h,(x,0),(x,y),(255,255,255))
    y = np.flipud(h)
    return y
     :
        elif k == ord('b'):
            print('b')
            lines = hist_lines(im)
            cv2.imshow('histogram',lines)
            cv2.imshow('image',gray)

RGBをグレーに変換して、それをライングラフに変換、それとグレーになったイメージを 表示だな。calcHistあたりを調べるかな。

[debian python]$ pydoc3 cv2.calcHist
Help on built-in function calcHist in cv2:

cv2.calcHist = calcHist(...)
    calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) -> hist

ぐぐったら、日本語が出てきた。ラッキー。サンキューさーですよ。 cv::calcHist

OpenCVとVisual C++による画像処理と認識(5)

ヒストグラム その1: 計算して,プロットして,解析する !!!

折角のチュートリアルを無視してたのがバレバレだな。

これ、どうもCフラフラ語みたいだけど、Python語に変換はどうしてるんだろ?

OpenCV-Pythonの紐づけ(Bindings)がどのように動作するのか?

もう一つ例題。houghcircles.py。何をやるかと言うと、プリント基板に載っている、丸っぽい 部品を認識して、それを赤丸で囲んでくれるやつ。

丸っぽい部品って何だ? 電解コンデンサーが筆頭に上がるだろう。他には、CANタイプの トランジスターとかICが有るな。更に電子回路に詳しい人なら、フェライトコアなんてのを 上げるかも知れない。そういう人はcoreな人と呼ばれている。

実例では、コンデンサとCANタイプのトランジスターしか載っていない、極普通のボード。 残念ながら、今が旬のラズベリーじゃないけどね。

検出した丸部品に、プリント板の表裏を貫通するランドパターンが含まれているのは、ご愛敬。

    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 10, np.array([]), 100, 30, 1, 30)

この関数が核っぽいけど、例によって意味不。で、解説を読む。

ハフ変換による直線検出

Hough変換を用いて、円を検出する

Hough変換を用いて、直線を検出する

もっと一般化すると、こうなるのか。

Canny法によるエッジ検出

そして、真打のメッシ様のご登場とな。って、事は、これ大事、切り札ですよって言いたいんだな。納得しました。

いずれにしろ、資料が豊富に揃っていて、2次元をやるにはうってつけですよ。

あれ? 3次元はどうよ? そんなのまだ技術が成熟してないんで無理。変なメガネをかけて 御覧下さいとか、立体ホログラムは手軽じゃないからねぇ。

ちゃうで。ビデオはどうよ。あれは3次元だぞ。えっ、奥行き無いじゃん。だから、奥行きは 諦めて、その代わりの次元に時間を取り入れたのさ。りっぱな3次元じゃん。

どんな応用有る? そうさな、頭ぼさぼさの脳学者が得意としてる、AHA体験。じわーと、画面の 一部が変わってくのを、見つけてくれってやつ。

あんなの、時間で微分すれば一発じゃん。OpenCVに果たして、そんなのの用意が有るか、探してみれ。

MobaXterm

を使って、Windows側へXを飛ばしてる。それには、Windows側のIPが必要って訳。今まで 何の疑いも持たずに、Netの情報を盲信し、設定してきた。

でも、loginした時に、下記のようなメッセージが出てる事に気がついた。(下記はFreeBSDの例)

 ┌────────────────────────────────────────────────────────────────────┐
 │                        • MobaXterm 9.4  •                          │
 │            (SSH client, X-server and networking tools)             │
 │                                                                    │
 │ ➤ SSH session to sakae@172.123.146.11                              │
 │   • SSH compression : ✔                                            │
 │   • SSH-browser     : ✔                                            │
 │   • X11-forwarding  : ✘  (disabled or not supported by server)     │
 │   • DISPLAY         : 172.123.123.4:0.0                             │
 │                                                                     │
 │ ➤ For more info, ctrl+click on help or visit our website           │
 └────────────────────────────────────────────────────────────────────┘

X11-forwardigに罰印が付いてるのが気になる。素直に解釈すればforadingが禁止になってるか、そんな機能はサポート外。

でも、DISPLAY変数をちゃんと設定すればXがWindows側に飛んでいくよ。このからくりはいかに?MobaXtermのHelpメニューに起動ログの項目が有ったので、眺めてみた。

LaunchTabContent(ssh "172.123.146.129" -l PleaseAskMe -p 22 -Y -o ForwardX11Trusted=yes -o ForwardX11=yes  -C -o Compression=yes  -Z , FreeBSD)

こういう要求が出されてましたよ。OpenSSH 日本語マニュアルページなんてのが有ったので、勉強させてもらいましょ。 なお、Windows側に建ったXserverは、使用の許可をxhostコマンドで与えるとな。

で、ふとLinuxとか、OpenBSDではどうか調べてみた。

 │   • X11-forwarding  : ✔  (remote display is forwarded through SSH) │
 │   • DISPLAY         : ✔  (automatically set on remote server)      │

こんな風に表示されてて、DISPLAY変数を指定せずとも、Xが使えたよ。そうなると、なぜ FreeBSDだけが、動かないか気になる。気分転換で、Windows7機の方も確認してみた。

ウブとOpenBSDがダメだった。FreeBSDは普通に動いていたぞ。試しにOpenBSDのsshd_configを 眺めたら、X11Forwardingがnoになってた。これをyesにしたら、OpenBSDも動き出した。

[ob: ~]$ echo $DISPLAY
localhost:10.0

こんな設定が、自動的に行われるのね。知らんかったぞ。 まあ、Xのアプリは頻繁に使う訳でもないので、これぐらいにしておくかな。

etc

Bash のプロセス置換が便利な件

これ、前回やったPIPE屋さんの強力な道具になりそう。但しBash連合に加盟してる必要が ある。Bashと言ってもFreeBSDで提供されてるportsでは、エラーになって動かなかった。 何かスイッチでも有るのだろうか?