OpenCV 3.1.0 C++ Macに環境構築
事前準備
CMakeを使用しますので事前にインストールします。
brew install cmake
ソースからのインストール手順はこちらを参考に以下のコマンドを順次実行します。
OpenCV: Using OpenCV with gcc and CMake
mkdir /tmp/opencv/ cd /tmp/opencv/ git clone https://github.com/Itseez/opencv.git git clone https://github.com/Itseez/opencv_contrib.git cd opencv mkdir release cd release cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. make -j7 sudo make install
CLion
IDEにはJetBrainsのCLionを使用します。
www.jetbrains.com
動作確認
実際にCMakeで動かしてみます。
OpenCV: Using OpenCV with gcc and CMake
New Projectを選択しプロジェクト名を入力。「opencv-sample」にしました。

CMakeLists.txtの末尾に以下を追加します。「opencv_sample」の部分はプロジェクト名に置き換えます。
... find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) target_link_libraries(opencv_sample ${OpenCV_LIBS})
次にmain.cppを編集してopencvの動作確認をします。
ローカルにある画像を表示するサンプルです。画像ファイルへのパスは絶対パスを入力します。
#include <stdio.h> #include <opencv2/opencv.hpp> using namespace cv; int main(int argc, char** argv ) { Mat image; image = imread("<画像ファイルのパス>", 1 ); if ( !image.data ) { printf("No image data \n"); return -1; } namedWindow("Display Image", WINDOW_AUTOSIZE ); imshow("Display Image", image); waitKey(0); return 0; }
実行
Control+Rで実行できます。Targetをプロジェクトに変更して実行。

画像が表示されれば成功です。
"15926 Insufficient free space for journals"
最近Dockerを使用してEC2上に並列テスト環境構築みたいなことをしていて、EC2(t2.small)上にMongoDBを3台ほど立てようとした時に15926 Insufficient free space for journalsというエラーが発生しました。
起動時にJournaling用に確保しているディスク容量が足りないということ。
EC2はデフォルトで8GBしかディスクがないので立ち上げの時に容量を確保できなかったために発生しているようでした。
対策
対策はEBSのサイズを大きくしても良いですが、上のStackoverflowにも書いてあるようにsmallFilesをtrueに設定すること。これでJournalのサイズを抑えることができるそうです。
設定
設定方法は立ち上げ方によって違います。
普通にMongoDBをインストールして起動している場合は/etc/mongo.confを編集する。
smallFiles: true
Configuration File Options — MongoDB Manual 3.0
--
Dockerで起動している場合は起動コマンドにオプションをつける。
docker run -d -p 27017:27017 --name my-mongo mongo mongod --smallfiles
--
docker-composeを使用している場合はdocker-compose.ymlにて起動コマンドを上書きする。
mongo: image: mongo command: mongod --smallfiles
Flask on Heroku でセッションを使う際の設定
EC2上では動作したのにHeroku上へ移した時に以下のエラーが出るようになった。
Traceback (most recent call last):
File "/app/blueprint/pages.py", line 51, in valid_login
session['username'] = user['username']
File "/app/.heroku/python/lib/python2.7/site-packages/werkzeug/local.py", line 341, in __setitem__
self._get_current_object()[key] = value
File "/app/.heroku/python/lib/python2.7/site-packages/flask/sessions.py", line 126, in _fail
raise RuntimeError('the session is unavailable because no secret '
RuntimeError: the session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
調べたところFlask-Sessionという拡張モジュールを利用するそう。
pip install Flask-Session
今回はMongoLabアドオンを使用していたためSESSIN_TYPEを変えるとファイルやDBに保存できるっぽい。
以下のようにfilesystemを指定した場合はflask_sessionディレクトリが作成されてそこに保存される。
SESSION_TYPE = 'filesystem' app.config.from_object(__name__) Session(app)
今回はMongoLabを使用していたためmongodbに設定したかったけれどHeroku上で以下のエラーが発生。
SESSION_TYPE = 'mongodb'
SESSION_PERMANENT = True
MONGOLAB_URI = os.environ.get('MONGOLAB_URI', None)
if MONGOLAB_URI:
SESSION_MONGODB = MONGOLAB_URI.split('/')[2]
SESSION_MONGODB_DB = MONGOLAB_URI.split('/')[3]
SESSION_MONGODB_COLLECT = 'sessions'
Traceback (most recent call last):
File "/app/.heroku/python/bin/gunicorn", line 11, in <module>
sys.exit(run())
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/base.py", line 189, in run
super(Application, self).run()
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
Arbiter(self).run()
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 201, in run
self.halt(reason=inst.reason, exit_status=inst.exit_status)
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 297, in halt
self.stop()
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 342, in stop
time.sleep(0.1)
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 214, in handle_chld
self.reap_workers()
raise HaltServer(reason, self.WORKER_BOOT_ERROR)
gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/arbiter.py", line 459, in reap_workers
ローカルだと動くんだけど原因がわからん。。。 気が向いたら調べます。
Jubatusハッカソンに参加してきました
作ったもの
何をしたか(だいたいの時系列で)
13:30-Hackathon開始-14:00チームビルディング。機械学習初心者で特に目的もないので1人で触ってみることに-16:00用意された記事データとJubatus/言語解析系の資料を読む-23:00Web上から使えそうなデータ取得を試みる(結局使わず)。-24:00全くJubatusに触っていないことに気づいてとりあえずサーバを立てる-01:00試しにチュートリアル通り記事データを放り込むと簡単なレコメンドが完成-09:00色々調べつつAPIサーバとChrome拡張を作る-16:00発表資料を作成して寝る。-18:00発表&解散
思ったこと
- チュートリアルだけでも手軽に動かせて十分に面白い
- 機械学習に疎くてもそれっぽいものを作れて簡単に組み込むことができた
- Jubatus本体はあまりハックできなかったので何ができるかもっと試してみたい
- Flask便利。MeCab初めて使ったけど面白い
- 何をしたいか考えたりデータを用意したりするところが結構時間かかると思った
- 参加者に詳しい人が多かったので発表を聞いてとても参考になった
- 次は時系列の数値データとか使って予測とかを作ってみたい
- 一人だと気楽だけど寂しいので次はチームで何か作ってみたい
www.slideshare.net
軽い気持ちで来たらガチな人が多くて不安でしたが発表まで出来たので満足。
使い方がわかったところで、もう少し深掘りしてみたいと思います。
皆様お疲れ様でした。
DynamoDBのお手軽バックアップ
アプリの状態だけ保持しているようなあまり大きくないDynamoDBのテーブルを
バックアップするのにDataPipeline使うのもどうかと思うのでツール作ろうかと考えていたら
既にあった。
使ってみたら結構便利だったので使い方をまとめます。
AmazonLinuxへインストール
このツールはAWSのpython向けSDKであるbotoを利用しますが、
AmazonLinuxにはpython + botoが初めから入っています。
dynamodumpをgitからチェックアウトするだけで使う準備は完了です。
$ yum -y install git $ git clone https://github.com/bchew/dynamodump.git $ cd dynamodump
バックアップ
バックアップ対象のDynamoDBテーブルへの読み込み権限があれば、
以下の3つのオプションのみでバックアップが取得できます。
| パラメータ名 | 値 |
|---|---|
| -m (Mode) | backup |
| -r (Region) | ap-northeast-1 |
| -s (SrcTable) | 対象のテーブル名 |
$ python dynamodump.py -m backup -r ap-northeast-1 -s my-table INFO:root:Starting backup for my-table.. INFO:root:Dumping table schema for my-table INFO:root:Dumping table items for my-table INFO:root:Backup for my-table table completed. Time taken: 0:00:00 $ tree . |-- LICENSE |-- README.md |-- dump | `-- my-table | |-- data | | `-- 0001.json | `-- schema.json |-- dynamodump.py `-- requirements.txt
リストア
リストアはバックアップ時と同じパラメータでも実行可能です。
しかしそのまま実行すると前処理でテーブルを削除してしまうので、
データだけを戻したい場合は--dataOnlyオプションを指定します。
| パラメータ名 | 値 |
|---|---|
| -m (Mode) | restore |
| -r (Region) | ap-northeast-1 |
| -s (SrcTable) | 対象のテーブル名 |
| --dataOnly | スキーマの作成/削除を行わない |
$ python dynamodump.py -m restore -r ap-northeast-1 -s my-table INFO:root:my-table table is being deleted.. INFO:root:my-table table deleted! INFO:root:Starting restore for my-table to my-table.. INFO:root:Creating my-table table with temp write capacity of 25 INFO:root:Waiting for my-table table to be created.. [CREATING] INFO:root:my-table created. INFO:root:Restoring data for my-table table.. INFO:root:Processing 0001.json of my-table INFO:root:Updating my-table table read capacity to: 1, write capacity to: 1 INFO:root:Restore for my-table to my-table table completed. Time taken: 0:00:21
$ python dynamodump.py -m restore -r ap-northeast-1 -s my-table --dataOnly INFO:root:Starting restore for my-table to my-table.. INFO:root:Restoring data for my-table table.. INFO:root:Processing 0001.json of my-table INFO:root:Restore for my-table to my-table table completed. Time taken: 0:00:01
S3へ定期バックアップするように設定する
cronでも良いと思いますが今回はJenkinsを使用してジョブを定義しました。
Git:RepositoryURLにhttps://github.com/bchew/dynamodump.gitを指定して、
シェルの実行で以下のように定義するのがオススメです。
対象のバケット名やテーブルはお好みで変更してください。
BUCKET_NAME=yustam-dynamo-backup ARCHIVE_NAME=dump_`date +%Y%m%d%H%M`.tgz python dynamodump.py -m backup -r ap-northeast-1 -s my-table tar czf $ARCHIVE_NAME ./dump rm -rf ./dump aws s3 cp $ARCHIVE_NAME s3://$BUCKET_NAME/dynamo/$ARCHIVE_NAME rm -f $ARCHIVE_NAME exit 0;
ビルドトリガを定期的に実行にして好きな時間に動かしたらいいと思います。
AWS CLIを使用してEC2のバックアップを定期的に取得する
AWS CLIとjqを使用した実装です。
設定した世代数分保持して古いバックアップから消していきます。
| 設定値 | 説明 |
|---|---|
| MAX_IMAGE_NUM | バックアップのイメージを保持する世代数 |
| INSTANCE_ID | バックアップを取得する対象のEC2インスタンスID |
| AMI_NAME | 取得するAMIの名前。実行毎に重複しないようにする |
| DESCRIPTION | バックアップの種類を識別するために使用します |
cronやJenkinsのジョブに設定して定期的に実行します。
再起動を許容する場合は--no-rebootオプションを外します。
EBS付きのインスタンスは追加のオプションが必要なので注意。
#!/bin/sh MAX_IMAGE_NUM=2 REGION=ap-northeast-1 INSTANCE_ID=i-00000000 AMI_NAME=ec2-backup-$(date +%m%d%H%M) DESCRIPTION="daily_backup" IMAGES=$(aws ec2 describe-images\ --region ap-northeast-1\ --owners self\ --filters Name=description,Values=$DESCRIPTION\ | jq .Images) # Delete oldest image if [[ $(echo $IMAGES | jq length) -ge $MAX_IMAGE_NUM ]]; then OLDEST_IMAGE_ID=$(echo $IMAGES | jq 'min_by(.CreationDate)' | jq -r .ImageId) echo "Delete: $OLDEST_IMAGE_ID" aws ec2 deregister-image\ --region $REGION\ --image-id $OLDEST_IMAGE_ID fi # Create image echo "Create: $AMI_NAME" aws ec2 create-image\ --region ap-northeast-1\ --instance-id $INSTANCE_ID\ --name $AMI_NAME\ --no-reboot\ --description $DESCRIPTION exit 0
Packer + Jenkins(on EC2)で自動AMI作成
Packerを使用してAMIの作成を自動化が出来たのでJenkinsでCIしてみようと思います。
Packerの使い方やJenkinsの使い方は割愛して簡単にポイントのみまとめます。
Jenkinsの設定
Gitリポジトリを指定
こちらのようなリポジトリを作成します。
template.jsonがPackerのテンプレートファイルです。
ジョブの設定
シェルの実行で以下のようにシェルを設定します。
packerをインストールしてしまえば毎回ダウンロードする必要はありません。
mkdir packer cd packer wget -o - https://dl.bintray.com/mitchellh/packer/packer_0.8.0_linux_amd64.zip unzip packer_0.8.0_linux_amd64.zip cd ../ ./packer/packer build template.json rm -rf ./packer exit 0;
設定は以上です。あとは好きなタイミングでジョブが動くように設定します。
注意する点
Jenkinsからpackerを使用してsshするとsudoが使用できない
packerを使用するとEC2にsshで接続してコマンドを実行しようとしますが、
スクリプト内でsudoを使用するとエラーが出て失敗してしまいます。
sudo: sorry, you must have a tty to run sudo
解決法
そのため、ここではEC2のUserDataにて/etc/sudoersを編集するようにしました。
packerではAMI作成用のEC2にUserDataを指定できるため、そこでsudoの設定を変更します。
#!/bin/bash -ex sed -i 's/Defaults requiretty/Defaults !requiretty/g' /etc/sudoers
その他、sudoで実行したいコマンドがあればここで実行しておくと良いです。
ビルダーのuser_data_fileにファイル名を指定すると起動時にUserDataへ設定されます。
{
"builders": [{
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami": "ami-cbf90ecb",
"instance_type": "t2.micro",
"ssh_username": "ec2-user",
"ami_name": "packer-ami-{{timestamp}}",
"user_data_file": "files/user-data.txt"
}],
"provisioners": [{
"type": "shell",
"scripts": [
"scripts/create-user-dirs.sh",
"scripts/install-packages.sh"
]
}]
}