doridoridoriand’s diary

主に技術的なことを書いていく予定(たぶん)

CloudFormation忘備録2


前回はただ単体のセキュリティグループを作っただけなので、今回は複数のセキュリティグループを連携させてみる。

例えば図のような経路に対するセキュリティグループを作りたくなったとする。

img-1.png

このときに、それぞれのコンポーネントに対してセキュリティグループを充てる必要が出てくる。 今回の場合ではリクエストを一番最初に受け付けるロードバランサと、そのロードバランサから来たリクエストを処理するAPサーバーの2つとなる。 ロードバランサはSSL終端をしているためHTTPS(443)のみ。APサーバー達はロードバランサからのリクエストしか受け付けないようにする。 (SSH出来ないよとかはとりあえず無視で。それは別のセキュリティグループを作って充てましょう)

前回書いたセキュリティグループのYAMLファイルを流用する。
以下のようにディレクティブを加えた。

---
AWSTemplateFormatVersion: "2010-09-09"
Description: >
  Here is the area of description of this CloudFormation template.
Resources:
  WebAPServersSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroup of webservers
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3000'
          ToPort: '3000'
          SourceSecurityGroupId: !Ref ApplicationLoadbalancerSecurityGroup
      Tags:
        - Key: Name
          Value: dev-web-ap-sg
      VpcId: vpc-XXXXXXXX
  ApplicationLoadbalancerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroup of Application Load Balancer
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '443'
          ToPort: '443'
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: dev-alb-sg
      VpcId: vpc-XXXXXXXX

別段変わったところは無く、ALB用のセキュリティグループが増えた形となる。ただしAPサーバー達に充てるセキュリティグループ dev-web-ap-sg には変更が入っている。

SecurityGroupIngressのアクセス元を表す表記が CidrIp から SourceSecurityGroupId へ変更となっている。 このように設定することによって、 dev-alb-sg を充てたロードバランサからのみのリクエスト受け付けるように出来る。 ちなみに今回は参照先・参照元共に一緒に生成しているため !Ref を利用して未知のセキュリティグループIDに対応出来るようにしているが、 既存のセキュリティグループを参照したい場合は sg-xxxxxxxx を書いてあげればおk。

前回のCloudFormationのスタックを利用してupdate-stackを実行。

無事にできていた。

img-2.png

CloudFormation忘備録

前のエントリーから非常に時間が開いてしまった。。
前のエントリーの投稿日60日前とか死ぬしかない。

本当に意識的に書いていかないと全然続かないな。 忙しかったんだけど、まあ酒飲んでる時間とかちょっと削れば1エントリーくらい書けるわけで。 まあ良い訳ですね。


業務で積極的にCloudFormationを使うようにしており、セキュリティグループやらロードバランサもCloudFormationで作っている。 以外とこの辺をCloudFormationで作っている人が居ないようなので、忘備録がてらブログに記しておく。

AWSのドキュメント読めば正直解決するのであるが、デバッグしずらいところでもあるので、このエントリーが誰かの役に立てばと。

いきなりソースコードから。 (not ステーキ)

---
AWSTemplateFormatVersion: "2010-09-09"
Description: >
  There is the area of description of this CloudFormation template.
Resources:
  WebAPServersSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroup of webservers
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: dev-web-ap-sg
      VpcId: vpc-XXXXXXX

最小構成のセキュリティグループのCloudFormationテンプレートを書いた。

おおまかな構成としては

AWSテンプレートフォーマットのバージョン
このテンプレートの説明
テンプレートで定義しているリソース

となっている。意外と構成要素少ない。なので、リソース配下にどのようなリソースをおけばよいかを書けば基本的には完成する。

一つずつ説明。

WebAPServersSecurityGroup

ここは正直なんと書いても問題ない。これ自体が変数みたいなもの。 今回は例として、WebAPサーバーにアタッチするセキュリティグループとしたので、このように書いているだけ。

Type: AWS::EC2::SecurityGroup

これはどのようなリソースをこのディレクティブ内部で使用するかを定義するもの。これはAWSのドキュメントを調べないとわからないので各自で。

Properties:

この下にネストさせて、色々構成物を定義していく。

GroupDescription: SecurityGroup of webservers
SecurityGroupIngress:
  - IpProtocol: tcp
    FromPort: '80'
    ToPort: '80'
    CidrIp: 0.0.0.0/0

GroupDescription

セキュリティグループの説明文。事業部では英語で書くことが決まりとなっているが、別に日本語でもエラーにはならないと思う。

SecurityGroupIngress

インバウンドのルールのこと。ちなみにアウトバウンド(EC2 => ネット)の方は SecurityGroupEgress。だた、EC2にアタッチするセキュリティグループでアウトバウンドを制限する要件はそれほど高くないと思われるので、今回は割愛。
複数定義したいときは次のように書くことも出来て、

 - IpProtocol: tcp
   FromPort: '80'
   ToPort: '80'
   CidrIp: 0.0.0.0/0
 - IpProtocol: tcp
   FromPort: '443'
   ToPort: '443'
   CidrIp: 0.0.0.0/0

ちなみに更に一気に範囲を指定してあげたいときは

- IpProtocol: tcp
  FromPort: '2000'
  ToPort: '4000'
  CidrIp: 0.0.0.0/0

とすることで 2000~4000番ポートを一気に開けることが出来る。 完成したCloudFormationテンプレートを実際に使用したい時は以下のコマンドを使用する。
(AWS CLIの基本的な使い方はマスターしている前提で話しています。そもそもAWS CLIってなんぞやって方はこちらを参照ください)

$ aws cloudformation create-stack --stack-name=dev-web-application-security-group --template-body=file://dev-web-ap-sg.yml

YAMLファイルを dev-web-ap-sg.yml として保存して、この構成名を dev-web-application-security-group として作成する感じ。

実行すると以下の結果が返ってくる。

/Users/dorian/sandbox aws cloudformation create-stack \
                      --stack-name=dev-web-application-security-group \
                      --template-body=file://dev-web-ap-sg.yml | jq -r
{
  "StackId": "arn:aws:cloudformation:ap-northeast-1:0123456789:stack/dev-web-application-security-group/8d7bf440-c6e9-11e7-931f-500c44f24c1e"
}

マネコンを開いてみると

ててーん。あっという間に完成。実際にセキュリティグループを見てみると

確かにできている。ちなみにCloudFormationの画面を確認してみるとこんな感じで出ていた。

最初に頑張って書いてしまえば、インフラ構成をgitでバージョン管理出来たりするので変更履歴置いやすいし、インフラエンジニアじゃなくてもどのような構成になっているのかを分かってもらえるので変なコミュニケーションが発生せず快適だったりする。

inode を枯渇させてみる

毎週書くとか言っておきながら、すごく日が開いてしまった。。よくない。。

とか言っておきながら、今回も小ネタ的なものですみません。 inode を枯渇させてみる。

業務中にルートボリュームがおかしくなったサーバーがあり、調査の過程でinodeも調べたので、興味本位がてらやってみた。 (結局そのサーバーは別の原因でルートボリュームがおかしくなっていたのだけれども)

そもそもinodeってなんぞや、全く聞いたことが無いで、という方は以下を読んでおけばなんとなくわかるかと思います。
inode番号とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

数に上限があるので、細かいファイルをガンガン保存していたりすると普通に枯渇する。そんなに無いとは思うけれどJSONをファイルとして 大量に保存していたりすると大変そう。

枯渇させるのは簡単で、ファイルをひたすらtouchしてあげればおk。 計測がてら、以下のようなスクリプトを組んでみた。

。。。と実行してみたことろ、SSH越しでコマンドを実行していため、生成速度が遅い。
1時間程度回してみたが、0.3%くらいしか使用率が上がらなかったorz
inode枯渇のタイミングで挙動がスクリプトの挙動がおかしくなって、正確な測定にならないだろなとか考えてSSH越しで別サーバーを立てて叩くようにしたが、そもそも測定が終わらなさそうなので、考えを改めて、普通にローカルで回せるように変更。
本当は別のドライブアタッチしてあげれば、そんな心配もしなくて良いのだけれども、まあ面倒なので
最終的に以下スクリプトを利用。

これを回すと以下のログが出力されるようになっている。

I, [2017-09-10T12:41:28.910920 #20048]  INFO -- : Used: 86386  Remain: 3753614  Percentage: 97.750
I, [2017-09-10T12:41:28.946672 #20048]  INFO -- : Used: 86396  Remain: 3753604  Percentage: 97.750
I, [2017-09-10T12:41:28.981453 #20048]  INFO -- : Used: 86406  Remain: 3753594  Percentage: 97.749
I, [2017-09-10T12:41:29.016357 #20048]  INFO -- : Used: 86416  Remain: 3753584  Percentage: 97.749
I, [2017-09-10T12:41:29.050865 #20048]  INFO -- : Used: 86426  Remain: 3753574  Percentage: 97.749
I, [2017-09-10T12:41:29.085021 #20048]  INFO -- : Used: 86436  Remain: 3753564  Percentage: 97.749
I, [2017-09-10T12:41:29.119606 #20048]  INFO -- : Used: 86446  Remain: 3753554  Percentage: 97.748
I, [2017-09-10T12:41:29.155900 #20048]  INFO -- : Used: 86456  Remain: 3753544  Percentage: 97.748
I, [2017-09-10T12:41:29.190215 #20048]  INFO -- : Used: 86466  Remain: 3753534  Percentage: 97.748

出力されるものは現在のinodeの使用率、残り、残りの%表記となっている。
最終的に15時間ほど掛かって完全に枯渇した。
枯渇すると以下のログが吐き出される。

ubuntu@ip-172-31-3-220:~$ ruby run_local.rb
/usr/lib/ruby/2.3.0/fileutils.rb:1157:in `initialize': No space left on device @ rb_sysopen - ./inode/1/e28c7144-aff1-4ddf-97cd-f93abaee09f7 (Errno::ENOSPC)
        from /usr/lib/ruby/2.3.0/fileutils.rb:1157:in `open'
        from /usr/lib/ruby/2.3.0/fileutils.rb:1157:in `rescue in block in touch'
        from /usr/lib/ruby/2.3.0/fileutils.rb:1153:in `block in touch'
        from /usr/lib/ruby/2.3.0/fileutils.rb:1151:in `each'
        from /usr/lib/ruby/2.3.0/fileutils.rb:1151:in `touch'
        from run_local.rb:18:in `block (2 levels) in <main>'
        from run_local.rb:15:in `times'
        from run_local.rb:15:in `block in <main>'
        from run_local.rb:12:in `times'
        from run_local.rb:12:in `<main>'
ubuntu@ip-172-31-3-220:~$

容量的には余裕。

ubuntu@ip-172-31-3-220:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            488M     0  488M   0% /dev
tmpfs           100M  6.8M   93M   7% /run
/dev/xvda1       30G  1.5G   28G   5% /
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/1000

しかしinodeは確かに枯渇している。

ubuntu@ip-172-31-3-220:~$ df -i
Filesystem      Inodes   IUsed  IFree IUse% Mounted on
udev            124865     381 124484    1% /dev
tmpfs           126832     469 126363    1% /run
/dev/xvda1     3840000 3840000      0  100% /
tmpfs           126832       1 126831    1% /dev/shm
tmpfs           126832       3 126829    1% /run/lock
tmpfs           126832      16 126816    1% /sys/fs/cgroup
tmpfs           126832       4 126828    1% /run/user/1000

この状態ではボリュームに対する、書き込みが発生するいかなる処理も実行不可能となる。 もちろんファイルの新規作成は無理であるし、

ubuntu@ip-172-31-3-220:~$ touch test.txt
touch: cannot touch 'test.txt': No space left on device

入力補完といった、一見ファイル作成とは無関係のコマンドも、以下のように使用することが出来ない。

ubuntu@ip-172-31-3-220:~$ less -s re-bash: cannot create temp file for here-document: No space left on device
-bash: cannot create temp file for here-document: No space left on device

これらに対処する一番簡単は方法は、不要ファイルを削除すること。 以下のように、ちょっとでもinodeに余裕ができれば、

ubuntu@ip-172-31-3-220:~/inode$ df -i
Filesystem      Inodes   IUsed  IFree IUse% Mounted on
udev            124865     381 124484    1% /dev
tmpfs           126832     469 126363    1% /run
/dev/xvda1     3840000 3830454   9546  100% /
tmpfs           126832       1 126831    1% /dev/shm
tmpfs           126832       3 126829    1% /run/lock
tmpfs           126832      16 126816    1% /sys/fs/cgroup
tmpfs           126832       4 126828    1% /run/user/1000

ファイルの新規作成も可能。

ubuntu@ip-172-31-3-220:~$ touch test.txt
ubuntu@ip-172-31-3-220:~$ ls
test.txt

入力補完も問題なく効く。

CentOS7でXFSフォーマットされたルートボリュームを拡張する

会社で使用しているサーバーの1台でルートボリュームを拡張する必要が出てきたので、実施した。 CentOS7での拡張は経験がなかったので、忘備録としてブログに記載。

サーバーはAWS上に存在。今年の2月にEBSのサイズが自由に変更出来るようになった。 https://aws.amazon.com/jp/blogs/news/amazon-ebs-update-new-elastic-volumes-change-everything/

検証に利用していたサーバーのルートボリュームは20GBだったのだが、ログのサイズが予想よりも大幅に大きかったため、99%まで逼迫していた。

今回は私物のAWSアカウントにサーバーを立てて会社で行った操作を記録。 何も考えずにウィザードに則ってインスタンス立てたりすると8GBのルートボリュームになっちゃったりする。 以下のようにすぐに逼迫してしまう。

[centos@dorian ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       8.0G  7.6G  499M   94% /
devtmpfs         477M     0  477M    0% /dev
tmpfs            496M     0  496M    0% /dev/shm
tmpfs            496M   13M  483M    3% /run
tmpfs            496M     0  496M    0% /sys/fs/cgroup
tmpfs            100M     0  100M    0% /run/user/0
tmpfs            100M     0  100M    0% /run/user/1000

これでは生きていけないので、EBSを変更する。 マネコンからは以下のように変更できる。

対象のインスタンスを選択し、ルートデバイスのところをクリック。

sc-1

するとブロックデバイスのポップアップが表示されるので、EBS IDの部分をクリックして、ボリュームのページに移動する。

sc-2

対象のボリュームが選択された状態になっているので、上部にあるアクションボタンからボリュームの変更を選択。

sc-3

sc-4

必要としているサイズに変更する。今回は100GBととしてみた。

sc-5

実行をするとボリュームの状態がin-use - modifyingとなり、サイズの変更が行われれていることがわかる。

sc-6

この作業には数分掛かるので、待つ。変更中でもボリュームはオンラインであるので、以下のように読み書きは可能(性能劣化はしていると思うけれども)

[centos@dorian ~]$ mkdir works
[centos@dorian ~]$ cd works/
[centos@dorian works]$ ll
合計 0
[centos@dorian works]$ touch file
[centos@dorian works]$ ll
合計 0
-rw-rw-r--. 1 centos centos 0  8月 19 08:40 file
[centos@dorian works]$

変更が完了すると、 in-use - completed(100%)と表示される。

sc-7

サーバーに戻ってパーティーション変更の作業を行う。 もちろん拡張したことは認識されていない。

[centos@dorian works]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       8.0G  7.6G  499M   94% /
devtmpfs         477M     0  477M    0% /dev
tmpfs            496M     0  496M    0% /dev/shm
tmpfs            496M   13M  483M    3% /run
tmpfs            496M     0  496M    0% /sys/fs/cgroup
tmpfs            100M     0  100M    0% /run/user/0
tmpfs            100M     0  100M    0% /run/user/1000

ただしディスク自体が100GBになっていることは再起動なしで反映されていた。

[centos@dorian works]$ lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  100G  0 disk
└─xvda1 202:1    0    8G  0 part /

よってパーティーションの変更をすればおk まずはボリュームとパーティーションの現状確認をするため、 fdisk コマンドを利用して情報を引き出す。

[centos@dorian works]$ sudo fdisk -l /dev/xvda1

Disk /dev/xvda1: 8588 MB, 8588886016 bytes, 16775168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト

[centos@dorian works]$ sudo fdisk -l /dev/xvda

Disk /dev/xvda: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x000b2270

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/xvda1   *        2048    16777215     8387584   83  Linux

次にfdiks使用して、現在のパーティーションの削除と再作成を行う。 この作業の途中でインスタンス障害などでリブートが掛かると多分二度と起動しなくなるので要注意。

[centos@dorian works]$ sudo fdisk /dev/xvda
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/xvda: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x000b2270

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/xvda1   *        2048    16777215     8387584   83  Linux

コマンド (m でヘルプ): d
Selected partition 1
Partition 1 is deleted

コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
パーティション番号 (1-4, default 1): 1
最初 sector (2048-209715199, 初期値 2048): 2048
Last sector, +sectors or +size{K,M,G} (2048-209715199, 初期値 209715199): 209715199
Partition 1 of type Linux and of size 100 GiB is set

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。

WARNING: Re-reading the partition table failed with error 16: デバイスもしくはリソースがビジー状態です.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
ディスクを同期しています。

緊張の一瞬。最後にWARNING出るのが普通にビビる。OSがまだ古い情報保持したままだよってことなのでことなので問題ないはず。

一旦再起動。

[centos@dorian works]$ sudo shutdown -r now
packet_write_wait: Connection to 52.38.77.75 port 22: Broken pipe
/Users/dorian/AWS_keys ssh centos@example.com
Last login: Sat Aug 19 08:36:55 2017 from nttkyo888131.tkyo.nt.ngn.ppp.infoweb.ne.jp
[centos@ip-172-31-26-162 ~]$

無事に再起動した。ボリュームを確認してみる。

[centos@ip-172-31-26-162 ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       100G  7.6G   93G    8% /
devtmpfs         477M     0  477M    0% /dev
tmpfs            496M     0  496M    0% /dev/shm
tmpfs            496M   13M  483M    3% /run
tmpfs            496M     0  496M    0% /sys/fs/cgroup
tmpfs            100M     0  100M    0% /run/user/1000

無事に増えている。元の8GBを超えて追加出来るか試してみる。

[centos@ip-172-31-26-162 ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       100G   12G   88G   12% /
devtmpfs         477M     0  477M    0% /dev
tmpfs            496M     0  496M    0% /dev/shm
tmpfs            496M   13M  483M    3% /run
tmpfs            496M     0  496M    0% /sys/fs/cgroup
tmpfs            100M     0  100M    0% /run/user/1000

無事に出来た模様。

今回はサーバーに搭載しているアプリケーションの関係でルートボリュームを拡張したが、ログのボリュームを別途用意し、LVMを組むなどの工夫をするほうが本来取るべき作業内容だとは思う。

つか緊張するのでもうやりたくないですね(^ν^)

動画を分析してみよう with Tensorflow

どちらかと言うとTensorflowを使ってみたかった側面が大きい。 同様のことを行いたいのならば、音声を使ったり、画像の色彩の変化を利用したりともっと別の方法があるはず。

TensorFlow結構前から話題になっていたのにほとんど関わりが無かったので触る機会を作ってみた。 ニューラルネットワークの構築を容易にするライブラリなので、多方面に応用が効く(だからこれだけ広く使われているっていうのも理由の1つだと思うけれども)

基本的にGPU Optimizedなので、GPUを利用出来る環境で使用すべきであるが気軽に触ってみたかっただけなので、一旦Mac上のUbuntuにインストールして使用。

Tensorflowはチュートリアルが充実しており、サンプルコードも満載。以下リポジトリがとても参考になる。 https://github.com/tensorflow/models

今回はこの内のImage Recognitionを利用して動画の中に何が写っているかを結果として出力させ、その結果から場面転換点等を検知出来るようにする。 考えた処理フローは以下の通り。

  1. OpenCVを利用して動画をフレームごとに分割&保存
  2. TensofrowのInceptionV3を利用して、物体認識。結果をフレームごとに保存
  3. 結果の差異から転換点と思われるところを出力

実際に実証用のコードを書いてみた。コードは以下リポジトリに存在している。 https://github.com/doridoridoriand/train-movie-data

/bin 配下にコードを格納それぞれの役割は次の通り。

  1. divide.py
    OpenCVを利用して動画をフレーム単位に分割&保存

  2. classify_image.py
    Tensorflowを用いて画像ごとに写っている物体の名前一覧をjsonで出力。出力名はフレーム番号と同様。

  3. parse_json.py
    2で作成したJSONから変化を大きいフレームを検出

  4. 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-buildanaconda-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経由でインストールされたOpenCVpython用バイナリを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なら一発じゃね?って飛んできたので、試したら本当に楽に入ってしまった。。開発用途ならこれで十分かも。