私は主にPHPをメイン言語としてきており、Pythonは一度も書いたことがありません。
と言うか勉強したこともないので記述方法すら全く知りません。
ですが今回何万枚もある画像の更新作業(倍以上のサイズの画像へ更新)をしなければならなくなり、かつ確実に同じ画像で更新しなければいけない制約があります。
画像ディレクトリ事更新すればと思うかも知れませんが、画像ファイル名が同じであっても、画像自体が違っている可能性があるため、目視などの確認作業が必要になってきます。
そこで少しでも目視の負担を下げるために、プログラムで画像の類似度を判別し類似度が異なる画像のみを目視で確認できるようなシステムを構築する事になりました。
そこで画像の類似度を判別できるライブラリなどを探した結果OpenCVにたどり着いた流れになります。
OpenCVについて
概要[編集] 画像処理・画像解析および機械学習等の機能を持つC/C++、Java、Python、MATLAB用ライブラリ[3]。プラットフォームとしてmacOSやFreeBSD等全てのPOSIXに準拠したUnix系OS、Linux、Windows、Android、iOS等をサポートしている。
引用:Wikiペディア
上記にも書かれているようにいくつかの言語で利用できるようですが、CもJavaもかじった程度な上に、環境構築、学習コストが高そうだったためPythonで実装することを選びました。
という事でここから本題のPythonにてOpenCVを利用できる環境構築をVirtualBox上のCentOS7に準備していきたいと思います。
記事内説明
ホストOSはMacになります。
今回はVirtualBox、Vagrantの初期化や操作方法などの説明は省いています。
両方でそんな凝った事は行っていませんので。
また簡単な説明はちょくちょく挟んではいますので不明な点や誤ちなどありましたらご連絡頂ければと思います。
今回はCentOS7を利用していますが、CentOSの6、他のディストリビューションで環境構築したい方は Vagrantbox.es から好みのものを探してくるといいと思います。
システム全体構成
細かいものは省いていますが、大体のファイル構成は下記になります。
Python-OpenCVプロジェクト - Vagrant - Vagrantfile - include_recipe.rb - package_recipe.rb - command_recipe
Vagrant+ItamaeにてVirtualBoxにCentOS7を準備する
では最初にVagrantfileを使って、VirtualBox上にCentOS7を入れます。
synced_folder
はホストOSとゲストOS間でフォルダを同期したい場合に設定するものになり、今回はapp
以下を設定しています。
Vagrant.configure(2) do |config| config.vm.box = "base" config.vm.box = "CentOS7.0-x64" config.vm.hostname = "python-opencv.com" config.vm.network :private_network, ip: "192.168.10.50" config.vm.network :forwarded_port, guest: 22, host: 2223, id: "ssh" config.vm.box_url = "https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.1.0/centos-7.0-x86_64.box" config.vm.synced_folder "../app", "/home/vagrant/app", create: true, owner: "vagrant", group: "vagrant" config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--memory", "2048"] end end
ホストOSでVagrantfileでCentOS7をインストール
# Vagrantfileのディレクトリに移動 cd Python-OpenCV/Vagrant # vagrant実行 vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'CentOS7.0-x64'... ==> default: Matching MAC address for NAT networking... ==> default: Setting the name of the VM: Vagrant_default_1502775655599_87835 ==> default: Clearing any previously set forwarded ports... ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: hostonly ==> default: Forwarding ports... default: 22 (guest) => 2223 (host) (adapter 1) ==> default: Running 'pre-boot' VM customizations... ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2223 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Remote connection disconnect. Retrying... default: Warning: Remote connection disconnect. Retrying... default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: default: Inserting generated public key within guest... default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 4.3.28 default: VirtualBox Version: 5.0 ==> default: Setting hostname... ==> default: Configuring and enabling network interfaces... ==> default: Mounting shared folders... default: /vagrant => /Users/ユーザー名/間のディレクトリ/Python-OpenCV/Vagrant default: /home/vagrant/app => /Users/ユーザー名/間のディレクトリ/Python-OpenCV/ap
取り敢えず上記のようになれば成功だと思います。
Itamaeで最低限の処理を実行
後からVirualBoxにログインしPythonやOpenCVをインストールするのですが、なるべく自動化してる部分はその機能を使ってやる方が便利なのでItamaeにて行います。
- yumの更新
- timezoneをJapanに変更
- 文字コードの変更
- 自分の使いやすい
.vimrc
の転送 - ファイヤーウォールの解除
- vim, gitのインストール
yumの更新があるのでかなり時間が掛かってしまいます。
bundle exec itamae ssh --vagrant include_recipe.rb
VirtualBoxにログインしてPython3とOpenCV3をインストール
本当はこれらも全てItamaeで自動化しておいた方がいいのですが、何せ初めてなこともあるので、それはまたの機会に記事にできればと思います。
# VirtualBoxにログイン vagrant ssh Last login: Tue Aug 15 14:56:23 2017 from 10.0.2.2 Welcome to your Vagrant-built virtual machine. [vagrant@python-opencv ~]$ # pythonのバージョン確認 [vagrant@python-opencv ~]$ python -V Python 2.7.5
pyenvを使ってPython3をインストール
私もそれほど詳しくはないのですが、PythonはLinuxのコア機能としても利用されているようなので、大本のPython自体のバージョンを上げたりするのは何かあった際に危険なので、今回はpyenv
というツールを利用してPythonの環境を構築します。
pyenv
を簡単に説明すると、Python専用の仮想環境構築用ツールになり、コアシステムのPythonと切り離した状態で新たにPython環境を構築できるものになります。
今回はログインしているvagrant
ユーザーのまま作業を行います。
git clone https://github.com/yyuu/pyenv.git ~/.pyenv # pyenvまでのパスを設定 vim ~/.bashrc # 下記を追記 -------- export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" -------- # .bashrcを反映 source ~/.bashrc # 依存関係にあるものをインストール sudo yum install gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel bzip2 sqlite zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel # インストール可能なバージョンを確認 pyenv install -l # python3.6.1をインストール pyenv install 3.6.1 # pythonを3.6.1に切り替え pyenv global 3.6.1 # pythonのバージョン確認 [vagrant@python-opencv ~]$ python -V Python 3.6.1 # pipのバージョンを確認 [vagrant@python-opencv ~]$ pip -V pip 9.0.1 from /home/vagrant/.pyenv/versions/3.6.1/lib/python3.6/site-packages (python 3.6)
無事`vagrant`ユーザー環境にてPython3にバージョンアップが完了しました。
因みに`root`ユーザーに切り替えてPythonのバージョンを確認してみましょう。
vagrantで`root`ユーザーの初期パスワードは vagrant になります。
# rootユーザーに切り替え [vagrant@python-opencv ~]$ su - Passwort: Letzte fehlgeschlagene Anmeldung: Dienstag, den 15. August 2017, 15:43:50 JST auf pts/0 Es gab 3 fehlgeschlagene Versuche seit der letzten erfolgreichen Anmeldung. # pythonのバージョン確認 [root@python-opencv ~]# python -V Python 2.7.5
ちゃんと元の2.7.5のままですね。
OpenCV3をインストール
OpenCVのインストール方法もたくさんあり、やりたい内容によって依存関係にあるソフトも変わってくるため大変なのですが、今回の目的は始めに書いた通り「画像の類似度を計測する」ことになりますので、OpenCV単体で問題ありません。
# pipを使ってOpenCVのインストール pip install opencv-python # OpenCVのバージョン確認 [vagrant@python-opencv ~]$ python Python 3.6.1 (default, Aug 15 2017, 15:29:44) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.3.0' >>> exit()
ちゃんとOpenCV3系がインストールされているのが確認できました。
Python+OpenCVを使った画像解析のコードはたくさんネット上に公開されているので、それらを参考に目的を果たせるプログラムを作りたいと思います。