動画を分析してみよう with Tensorflow
どちらかと言うとTensorflowを使ってみたかった側面が大きい。 同様のことを行いたいのならば、音声を使ったり、画像の色彩の変化を利用したりともっと別の方法があるはず。
TensorFlow結構前から話題になっていたのにほとんど関わりが無かったので触る機会を作ってみた。 ニューラルネットワークの構築を容易にするライブラリなので、多方面に応用が効く(だからこれだけ広く使われているっていうのも理由の1つだと思うけれども)
基本的にGPU Optimizedなので、GPUを利用出来る環境で使用すべきであるが気軽に触ってみたかっただけなので、一旦Mac上のUbuntuにインストールして使用。
Tensorflowはチュートリアルが充実しており、サンプルコードも満載。以下リポジトリがとても参考になる。 https://github.com/tensorflow/models
今回はこの内のImage Recognitionを利用して動画の中に何が写っているかを結果として出力させ、その結果から場面転換点等を検知出来るようにする。 考えた処理フローは以下の通り。
- OpenCVを利用して動画をフレームごとに分割&保存
- TensofrowのInceptionV3を利用して、物体認識。結果をフレームごとに保存
- 結果の差異から転換点と思われるところを出力
実際に実証用のコードを書いてみた。コードは以下リポジトリに存在している。 https://github.com/doridoridoriand/train-movie-data
/bin
配下にコードを格納それぞれの役割は次の通り。
divide.py
OpenCVを利用して動画をフレーム単位に分割&保存classify_image.py
Tensorflowを用いて画像ごとに写っている物体の名前一覧をjsonで出力。出力名はフレーム番号と同様。parse_json.py
2で作成したJSONから変化を大きいフレームを検出convert_frame_to_second.py
3で抽出下したフレームを時間に変換する突貫コード()
使用した映像はUltra Japan2016のアフタームービー。理由は行きたかったけど行けなかったから。 真面目にやるのであれば、モデルデーターの関係から自然や動物が写っているデーターのほうが良いのだけれども。。
実際に検出できた場面転換点は以下のとおり。
https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=100s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=101s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=102s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=104s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=105s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=106s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=107s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=109s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=111s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=112s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=117s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=118s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=121s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=122s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=123s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=126s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=128s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=129s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=130s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=133s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=139s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=140s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=141s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=143s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=145s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=150s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=152s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=156s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=159s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=163s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=167s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=170s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=172s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=175s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=176s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=178s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=184s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=186s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=188s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=189s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=192s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=193s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=195s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=196s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=197s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=198s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=199s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=201s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=203s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=204s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=205s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=207s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=208s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=209s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=210s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=212s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=213s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=215s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=217s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=219s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=220s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=221s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=222s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=223s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=225s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=226s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=227s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=228s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=231s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=232s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=233s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=234s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=236s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=237s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=238s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=239s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=240s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=241s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=242s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=243s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=244s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=245s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=247s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=248s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=250s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=251s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=252s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=253s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=255s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=258s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=260s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=261s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=265s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=266s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=267s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=268s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=269s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=270s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=276s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=278s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=281s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=282s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=287s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=288s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=291s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=293s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=294s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=296s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=298s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=299s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=300s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=301s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=303s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=305s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=306s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=308s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=311s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=312s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=313s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=316s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=319s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=320s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=323s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=325s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=326s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=328s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=32s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=330s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=331s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=332s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=333s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=334s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=335s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=337s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=338s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=339s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=340s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=341s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=342s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=344s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=345s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=347s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=348s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=349s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=34s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=351s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=352s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=359s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=360s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=361s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=362s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=363s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=364s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=365s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=366s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=367s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=368s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=370s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=372s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=373s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=374s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=375s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=379s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=381s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=382s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=383s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=385s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=389s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=392s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=396s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=397s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=398s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=399s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=400s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=402s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=403s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=405s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=412s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=413s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=416s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=428s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=431s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=438s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=43s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=443s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=446s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=447s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=452s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=455s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=456s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=458s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=462s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=469s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=46s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=470s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=473s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=483s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=484s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=485s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=486s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=488s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=489s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=490s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=496s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=497s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=498s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=499s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=500s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=503s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=504s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=507s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=511s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=512s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=513s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=515s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=516s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=518s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=519s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=522s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=525s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=53s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=54s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=57s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=58s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=62s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=66s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=68s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=69s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=71s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=75s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=77s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=79s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=82s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=83s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=87s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=90s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=91s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=96s https://www.youtube.com/watch?v=fYB1Ovpd0nc&t=99s
。。。多いわww
Youtubeの仕様で1秒以下の指定ができなかったので重複とみなされてしまうところはカットした。 ちょっと敏感に反応している感も否めないが、結構精度良く抽出出来ているのではないかと思う。
問題は映像を分割する際の時間とファイルサイズだと思われる。 今回画像に分割する際にPNGを選んでしまったことも有り、9分の動画を画像に分割しただけで10GBにもなってしまった。 またTensorflowの処理時間も2時間程度掛かった。
GPUを利用すればもっと高速化出来ると思われるので、改善の余地は沢山ありそう。 ひとまずチュートリアルをアレンジしても結構遊べることが分かった。
Ubuntu上に最新のSwiftをソースからコンパイルして使えるようにする
Ubuntu上で行うことを想定。 ひとまず公式サイト https://swift.org/ に何か載っていないか見てみる。
公式サイトで案内されているgithubのリポジトリ参照してみると普通にやり方書いてあった。 https://github.com/apple/swift
とりあえず公式が案内している方法に従ってみる。
$ sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-dev tzdata
$ mkdir swift-source $ cd swift-source
$ git clone git@github.com:apple/swift.git $ ./swift/utils/update-checkout --clone-with-ssh
$ sudo apt-get install cmake
$ git clone git@github.com:ninja-build/ninja.git && cd ninja $ git checkout release $ cat README
$ cd $ ./swift-source/swift/utils/build-script -r -t
エラーが出た。
CMake Error at CMakeLists.txt:613 (message): Python 2.7 or newer is required
Pythonが古いとのこと。しかし、現在インストールしているPythonは3.6.0。おかしい。 もしかして2系じゃないといけないのかと思い、pyenvで2.7.13をインストールしてみる。
どうやらビンゴ。コンパイルが進み始めた。結構掛かりそう。
。。エラーがまた出た。
[6/29] Building HTML documentation FAILED: cd /home/dorian/swift-source/swift/docs && /home/dorian/.pyenv/shims/sphinx-build -W -D latex_elements.papersize=letter -d /home/dorian/swift-source/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/doctrees -b html . /home/dorian/swift-source/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/docs/html pyenv: sphinx-build: command not found The `sphinx-build' command exists in these Python versions: anaconda-2.4.0 [6/29] Compiling /home/dorian/swift-source/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/stdlib/private/SwiftPrivateLibcExtras/linux/x86_64/SwiftPrivateLibcExtras.o ninja: build stopped: subcommand failed. ./swift-source/swift/utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting
どうやらpython周りが結構面倒くさそう。私の環境がデフォルトと違うっていうのが大きそうだけれども。
エラー文言を読んでみると sphinx-build
が anaconda-2.4.0
にしかないとのこと。
対処療法的だけれども、anaconda-2.4.0に切り替えて、再度ビルドを実行。
進み始めた。
Testing Time: 396.22s Expected Passes : 2891 Expected Failures : 88 Unsupported Tests : 837 -- check-swift-linux-x86_64 finished -- --- Finished tests for swift ---
インストールが終わった模様。 最後にパスを通す必要がある。
export PATH=/home/自分のユーザー名/swift-source/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/bin:"${PATH}"
REPLを実行してみる。
$ swift *** You are running Swift's integrated REPL, *** *** intended for compiler and stdlib *** *** development and testing purposes only. *** *** The full REPL is built as part of LLDB. *** *** Type ':help' for assistance. *** (swift)
(swift) let greeting = "Hello!" // greeting : String = "Hello!" (swift) print(greeting) Hello! (swift)
問題なく動いていそう。
インストール時にpythonとの依存関係がちょっと面倒だったけれども、その後は割とすんなりいった印象。 最新を使いたいとかでなけれは実はDockerHubにDockerfileがあったりする。
https://hub.docker.com/_/swift/
いい時代だ。 次回はまたPythonに戻る予定。
pyenvで管理しているPythonからOpenCVを使えるようにする
MacはHomebrew経由でインストールできる模様。以下コマンドを実行してみる。
$ brew install opencv
以下のエラーが出力された。
$ brew install opencv Error: No available formula with the name "opencv" It was migrated from homebrew/core to homebrew/science. You can access it again by running: brew tap homebrew/science
メッセージに従って brew tap homebrew/science
を実行。
再度 brew install opencv
を実行したところ、無事にインストールできた。
ここでpythonからOpenCVを呼び出せるか、試しにREPLを起動してみる。
$ python Python 3.5.1 (default, Apr 16 2017, 13:35:06) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import cv Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'cv' >>> import opencv Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'opencv' >>> exit()
どうやらモジュールが発見できていない模様。調べてみるとこのインストール方法はどうやら古い気がする。 python3系から呼び出すためには、別のopencvをインストールする必要がありそう。 先ほどインストールしたものを削除する。
$ brew uninstall opencv Uninstalling /usr/local/Cellar/opencv/2.4.13.2... (278 files, 35.6MB)
インストールオプションを調べる。
$ brew info opencv3 homebrew/science/opencv3: stable 3.2.0 (bottled), HEAD [keg-only] Open source computer vision library, version 3 http://opencv.org/ Not installed From: https://github.com/Homebrew/homebrew-science/blob/master/opencv3.rb ==> Dependencies Build: cmake ✘, pkg-config ✔ Recommended: eigen ✔, jpeg ✔, libpng ✔, libtiff ✔, openexr ✔, numpy ✔ Optional: ffmpeg ✘, gphoto2 ✘, gstreamer ✘, jasper ✘, jpeg-turbo ✘, libdc1394 ✘, openni ✘, openni2 ✘, qt ✘, tbb ✘, vtk ✘ ==> Requirements Optional: cuda ✘, java ✔, python3 ✔ ==> Options
次のコマンドを実行。
$ brew install opencv3 --with-python3
(オプション入れたせいか、すごい時間がかかる。。) (make走るのでかなり時間が掛かる。。) (一時間位かかりそう。。)
なんかまたエラーが出た。
Already downloaded: /Users/dorian/Library/Caches/Homebrew/numpy--nose-1.3.7.tar.gz ==> python3 -c import setuptools... --no-user-cfg install --prefix=/usr/local/Cellar/numpy/1.13.1/libexec/nose --single-version-externally-managed --record=installed.txt ==> python3 setup.py build --fcompiler=gnu95 --parallel=8 install --prefix=/usr/local/Cellar/numpy/1.13.1 --single-version-externally-managed --record=installed.txt ==> Caveats If you use system python (that comes - depending on the OS X version - with older versions of numpy, scipy and matplotlib), you may need to ensure that the brewed packages come earlier in Python's sys.path with: mkdir -p /Users/dorian/.local/lib/python3.5/site-packages echo 'import sys; sys.path.insert(1, "/usr/local/lib/python2.7/site-packages")' >> /Users/dorian/.local/lib/python3.5/site-packages/homebrew.pth Python modules have been installed and Homebrew's site-packages is not in your Python sys.path, so you will not be able to import the modules this formula installed. If you plan to develop with these modules, please run: mkdir -p /Users/dorian/.local/lib/python3.5/site-packages echo 'import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")' >> /Users/dorian/.local/lib/python3.5/site-packages/homebrew.pth ==> Summary 🍺 /usr/local/Cellar/numpy/1.13.1: 1,375 files, 29.1MB, built in 2 minutes 14 seconds ==> Installing homebrew/science/opencv3 --with-python3 ==> Downloading https://github.com/opencv/opencv/archive/3.2.0.tar.gz ==> Downloading from https://codeload.github.com/opencv/opencv/tar.gz/3.2.0 ######################################################################## 100.0% Error: opencv3: Does not support building both Python 2 and 3 wrappers
Error: opencv3: Does not support building both Python 2 and 3 wrappers
え。そうなの? 確かにオプション一覧に無かった。。
ひとまず埒が明かないので、もう一回オプション無しでインストールする。
$ brew install opencv3
問題なくインストール完了。
ではこれを pyenv
でインストールしたpythonから呼び出せるか試してみる。
python用のバイナリファイルは以下パスに入っているみたい。
/usr/local/Cellar/opencv3/3.2.0/lib/python2.7/site-packages
個人的にはpython3系に一本化したいので、しばらくpython3でうまく出来ないか(python3系用のsoファイルがインストールされないか)格闘していたが、一筋縄では行かないと判明したので、さっと諦めて pyenv
で2.7.11にバージョンを変更。
pyenv
でインストールしたpythonは以下ディレクトリに格納されている。
~/.pyenv/versions
brew経由でインストールされたOpenCVのpython用バイナリをpyenv経由でインストールしたpythonから参照出来るようにするために、シンボリックリンクを貼ってあげれば良い。そのためには以下コマンドを実行する。
ln -s /usr/local/Cellar/opencv3/3.2.0/lib/python2.7/site-package/cv2.so ~/.pyenv/versions/2.7.11/lib/python2.7/site-packages
実際にpythonから呼び出せるか確かめてみる。
/Users/dorian/.pyenv/versions/2.7.11/lib/python2.7/site-packages python Python 2.7.11 (default, Aug 6 2016, 11:14:26) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.2.0' >>>
問題なく呼び出せた模様。 環境作るのに時間かかってしまった。。
おまけ
シンボリックリンクの張り替えで、opencvとopencv3を切り替えられた。
$ python Python 2.7.11 (default, Aug 6 2016, 11:14:26) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.2.0' >>> exit() $ rm .pyenv/versions/2.7.11/lib/python2.7/site-packages/cv2.so $ ln -s /usr/local/Cellar/opencv/2.4.13.2/lib/python2.7/site-packages/cv2.so ~/.pyenv/versions/2.7.11/lib/python2.7/site-packages /Users/dorian python Python 2.7.11 (default, Aug 6 2016, 11:14:26) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '2.4.13.2'
補足
Twitterでつぶやいたら、anacondaなら一発じゃね?って飛んできたので、試したら本当に楽に入ってしまった。。開発用途ならこれで十分かも。
pyenv 使ってるならbrewじゃなくてanaconda で入れたら一発な気がする。。
— Yuto Suzuki (@moc_yuto) 2017年7月22日
ブログを移行しました
気がつけば社会人2年目も半ばになっているっていう。 後輪矢のごとしとはまさにこのことですね。
HUGO+レンサバから、はてなブログ+S3(アセット)に移行しました。 理由としては
などがあります。学生時代には予想もしなかったインフラエンジニアになっている、ほぼ毎日酒を飲んでいるなど、中々めまぐるしく変化している社会人生活ですが、 技術的なことを主軸にこのブログを更新していこうと思います。
インフラエンジニアになっても何故か仕事レベルで書ける言語は増える一方なので、インフラという枠(あるレベル以下は既にその境界線が無いようなものですが)に囚われずに書いていきます。
AWSをVagrantから使ってみる
卒研とか引っ越しとかで忙しくてねえ。。(言い訳)
AWS便利すぎて値段が割高というデメリットが完全に霞んでいる感ありますね。個人的にはもう少しGoogleCloudPlatform使いたいんですけど。 でも結局GCPあんま使ってないっていう
・・・
vagrant-aws
というプラグインを利用することによって、AWSをあたかもVagrantでVirtualboxなりVMWareなりのVMを立ち上げているかのように使えるということで、試しに使ってみました。
作者のページを見れば当たり前ですが詳しく書かれているのでどうぞ
まあまずプラグインをインストールしないことには始まりませんので、インストールします。(あ。VagrantやAWSを普段そこそこ使用している方向けの記事ですので、Vagrantって何ぞやって方はまず普通にVagrantを使ってみてください)
$ vagrant plugin install vagrant-aws
次にvagrantが利用するboxをインポートします。そもそもVagrantはローカルにVMを立てて使うものなので、どうしてもVMのイメージが必要となります。
$ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
次にAWSに接続するために必要な情報を集めます。今回はAWSに接続するためにアクセスキーIDとシークレットアクセスキーが必要となります。しかし、ルート権限を持った状態でのこの2つの発行は出来ないことになっているのでIAMユーザーを作成し、 そのユーザーのアクセスキーIDとシークレットアクセスキーを用いて接続することにします。
まずAWSのコンソールにログインし、上のメニューバーを[サービス] -> [IAM]の順にクリックしていきます。
するとこのような画面が現れます。
ここでVagrantから操作する専用のIAMユーザーを作成しましょう。 [個々のIAMユーザーの作成] -> [ユーザーの管理] -> [新規ユーザーの作成] とクリックしていきます。ユーザー名は任意で大丈夫です。ここで重要なのは、画面下に設置してある[ユーザーごとにアクセスキーを生成]のチェックボックスにちゃんとチェックが入っているかどうかです。 これにチェックしていないとちゃんとアクセスキーが発行されませんので注意してください。
これで無事作成すると、[これは、これらのユーザーセキュリティ認証情報をダウンロードできる最後の機会です。]などという文言と共にアクセスキーIDとシークレットアクセスキーが表示されると思います。 これをどっかにメモっておきましょう。
これでAWS側の準備は整いました。ではVagrantfileを作成してゆきましょう。
任意のフォルダでvagrant init
を実行します。
最初に書かれているサンプルをさくっと削除して、次の内容を書き込みます。
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "dummy" config.vm.provider :aws do |aws, override| aws.access_key_id = "さっき取得したアクセスキーID" aws.secret_access_key = "さっき取得したシークレットアクセスキー" aws.keypair_name = "いつも使用しているリージョンの公開鍵の名前" aws.tags = {'Name' => 'Vagrant'} # AWSのEC2に名前を付けられる。とりあえずVagrantにした aws.ami = "ami-a21529cc" # Ubuntu14.04LTS HVMのイメージ aws.instance_type = "t2.micro" #インスタンスのサイズはご自由に # セキュリティグループの設定がうまくいかない #aws.security_groups = {'groupId' => 'セキュリティグループID'} aws.region = "ap-northeast-1" override.ssh.username = "ubuntu" override.ssh.private_key_path = "公開鍵の絶対パス" end end
以上の状態でvagrant up
を実行します。するとこのようにAWS上にVagrantを立てることが出来ました。
Vagrant全ての機能を使えるわけではありませんが、気軽に実際にサーバーを立てて検証するには良いと思いました。個人的にはMulti-VMモードで複数起動出来るか試してみようと思います。
C#のyieldに関して
まあなんか書くことなかったんだけど笑 C#のyieldを目にする機会が多かったので、ちょっと調べてみました。Microsoftのドキュメントを読んでみると
ステートメントで yield キーワードを使用した場合、メソッド、演算子、または get アクセサーが反復子であることを示します。 yield を使用して反復子を定義すると、カスタム コレクション型の IEnumerable および IEnumerator パターンを実装するときに明示的な余分なクラス (列挙の状態を保持するクラス。たとえば IEnumerator
を参照) が不要になります。
フーン
まあコード書いてこのyieldの利益をえてみましょう。まずyieldを使っていない書き方から
class YieldTest { static void Main(String[] args) { foreach (var item in GenDataset()) { Console.WriteLine(item); } } static List<String> GenDataset() { List<String> dataset = new List<String>(); for (int i = 0; i < 100; i++) { dataset.Add(i.ToString()); } return dataset; } }
まあ単純に0から99までの数字を配列に入れているだけです。次にyieldを使った書き方に変更してみます
class YieldTest { static void Main(String[] args) { var dataSet = GenDataset(); foreach (var item in dataSet) { Console.WriteLine(item); } } static IEnumerable<String> GenDataset() { for (int i = 0; i < 100; i++) { yield return i.ToString(); } } }
ListからIEnumerableというインターフェースに変更して、かつ内部のListの変数宣言などが不要になっています
正直この例だと簡単過ぎてメリットを感じないのですが笑
ここでメソッドから帰ってきた配列の型を確認してみましょう。普通に書いた方は
System.Collections.Generic.List
1[System.String]`
ですが、yieldで書いた方は
YieldTest+<GenDataset>c__Iterator0
という形で返ってきています。イテレータとなっていることから、List型ではなく、反復子として処理されたことがわかります。なので、内容はList型のような参照を行うことが出来ません(配列要素をカウントするCountなどをメソッドチェインすることは不能です)
。。結論として何を言いたいんだって感じになってしまいましたが、まあRubyにもYieldあったなあって思って色々試しただけですw
久しぶりにまとまらない話になりましたorz