コンテンツにスキップするには Enter キーを押してください

Python 3.7 x OpenCV 4.0 で ONNX のモデルを実行する

本記事は、Fusic Advent Calendar 2018の16日目の記事になります。
昨日は、 @urata による、@ionic/vue + Capacitorでクロスプラットフォームの未来を覗いてみる でした。
Ionic + Vue + Capacitor の組み合わせで、クロスプラットフォームアプリを作成する なんて、いい未来ですね!ワクワクしてきます! (分かってない)

さて、2018年11月20日に、 OpenCV 4.0 がリリースされました。
https://opencv.org/opencv-4-0-0.html

Release highlights:
OpenCV is now C++11 library and requires C++11-compliant compiler. Minimum required CMake version has been raised to 3.5.1.
A lot of C API from OpenCV 1.x has been removed.
Persistence (storing and loading structured data to/from XML, YAML or JSON) in the core module has been completely reimplemented in C++ and lost the C API as well.
New module G-API has been added, it acts as an engine for very efficient graph-based image procesing pipelines.
dnn module was updated with Deep Learning Deployment Toolkit from the OpenVINO™ toolkit R4. See the guide how to build and use OpenCV with DLDT support.
dnn module now includes experimental Vulkan backend and supports networks in ONNX format.
The popular Kinect Fusion algorithm has been implemented and optimized for CPU and GPU (OpenCL)
QR code detector and decoder have been added to the objdetect module
Very efficient and yet high-quality DIS dense optical flow algorithm has been moved from opencv_contrib to the video module.
More details can be found in previous announces: 4.0-alpha, 4.0-beta, 4.0-rc and in the changelog
Branch 3.4 will be switched to maintanence mode: only bugfixes and light features will be accepted. BTW, release 3.4.4 is ready too!

For those who have not took part in the OpenCV 2018 survey yet, feel free to share your thoughts.

適当に抜粋して意訳すると、

  • OpenCV1.x の頃からずっと使われてきた C API を刷新し、C++ で書き直したよ
    — これにより、XML, YAML, JSON などを取り扱う部分のコードも変更されたよ
  • 新たに G-API と呼ばれるモジュールが追加され、グラフベースの画像解析をする際に強力に機能するよ
  • Kinect Fusion アルゴリズム が実装され、CPU/GPU での実行が最適化されたよ
  • objdetect モジュールに QRコードを発見し解析する機能を追加したよ
  • OpenCV 3.4 は、メンテナンスと軽い機能の追加のみ対応するよ。ところで、3.4.4 は今日から使えるよ

という感じでした。

  • もっと詳細を知りたかったら、 4.0-alpha, 4.0-beta, 4.0-rc, changelog を見てね

と書いてあったので、少し追加で見てみます。

4.0-alpha (2018/9/20) の抜粋&意訳 (*1)

  • OpenCV の DNN モジュールに ONNX パーサーを追加したよ
    — AlexNet, Inception v2, Resnet, VGG etc. The tiny YOLO v2 などが部分的にサポートされているよ。
  • Mask RCNN をサポートし、example を追加したよ
  • OpenVINOを利用することによってより早い物体検出ができるようになったよ。
  • QR コードがより早く読めるようになったよ (Core i5, 640x480px の画像で 80FPS ぐらい)

らしいです。

4.0-beta(2018/10/16) の抜粋&意訳(*2)

  • ONNX パーサーでもっと多くのトポロジーを認識できるようにしたよ
  • 物体検出のコードを改良して使いやすくしたよ
  • 超効率的な画像処理パイプラインエンジンがopencv_gapiモジュールとして統合されたよ
  • QUirc (https://github.com/dlbeer/quirc) ライブラリを活用して、QRコードを読み取って解析できるようになったよ

あと、 OpenVINO toolkit の話も出ていました。
OpenVINO toolkit は、Intel 製のDeep Learning モデル推論時に使うライブラリらしく、Intel 製のチップを用いた推論速度が早くなるそうです。

4.0-rc (2018/11/12) の抜粋&意訳(*3)

  • Vulkan をバックエンドとしたDNN のモジュールが追加されたよ
  • より正確にカメラのキャリブレーションを行えるメソッドが追加されたよ
  • Graph API がより良くなったよ
  • QuickTime, QTKit, Unicap, Video for Windows, libv4l, DC1394_V1, Carbon などの時代遅れのビデオバックエンドを削除したよ
  • 3.4 のブランチに最近入ったコード(脆弱性対策など)をマスターにマージしたよ

changelog の抜粋&意訳

割愛。

読んだ感想

QR コードと DNN を超推してるなという印象です。

中国では数年前からQR コード決済がずっと流行っていますし、
日本でも、PayPay によるQR コード決済が大きな話題を呼びました。
確実に需要が高まってきているのでしょう。
QR コードの読み取りと解析がすばやくできるのは大きな価値になるのだろうなと感じます。

DNNは相変わらず画像の分野で猛威を奮っています。
OpenCVも画像を扱うライブラリである以上、無視できなくなった形でしょうか。
ちなみに、開発自体はかなり前から行われていたそうです(*4)。

ただ、新たにONNXに対応するなど、幅を広げている印象です。
今回、G-API (Graph-API) というものが追加されており、興味深いのですが、
まだPython 版はリリースされていない(*5)ようなので、もう少し待ってから使ってみようと思います。

環境構築

Python から OpenCV を操作できる環境を構築していきましょう。
Python を使っている人はお世話になっている方が多いと思いますが、
OpenCV 3.4.x 系は、 pip install opencv-python でインストールできます(*6)。

ところが、こちらの issue にあるとおり、
まだ2018/12/16 の段階では OpenCV の 4系には対応していません。
困った。。。

ということで、いろいろと探しました。そして、見つけました。
こんな素晴らしいレポジトリを!
https://github.com/janza/docker-python3-opencv

ということで、使ってみました。
が、残念ながら python -c "import cv2; print(cv2.__version__)" を実行してもうまくいきませんでした。

なので、改良版を作成しました。
こちらのコマンドで docker pull していただけます(1.3GB)。

docker pull gorogoroyasu/docker-python3-opencv

入手後、 docker run -it --rm gorogoroyasu/docker-python3-opencv python -c "import cv2; print(cv2.__version__)" としていただけると、無事 4.0.0 という結果が帰ってくるのではないかと思います。

変更点を見たらわかることなのですが、本家との違いは、シンボリックリンクの設定を追加したことです。

// 2018/12/24 編集
一応本家にもPRを出してますが、マージされるかどうかはわかりませんし、あまり自信もありません。
もしマージされたら、本家の方を使ってください。

マージされましたので、 https://github.com/janza/docker-python3-opencv をお使いください。
// 2018/12/24 編集 ここまで

なお、以下のONNX を使ってみるサンプルコードは、全てこの環境で動かしています。

ONNXを動かしてみる。

  1. Python を実行する。
docker run -it --rm gorogoroyasu/docker-python3-opencv python
  1. Mnist のモデルを準備する
    https://github.com/onnx/models/tree/master/mnist より、データをダウンロードする。
    そして、解凍する。
wget https://onnxzoo.blob.core.windows.net/models/opset_8/mnist/mnist.tar.gz
tar -zxvf mnist.tar.gz
  1. 推論する

最初に、

pip install matplotlib sklearn

を実行する必要があります。

その後、

import numpy as np
import matplotlib.pyplot as plt
import cv2
import sklearn

from sklearn import datasets, model_selection, svm, metrics
mnist = datasets.fetch_mldata('MNIST original', data_home='data/src/download/')

lendata = np.arange(len(mnist['data']))
choosen = np.random.choice(lendata, 5, replace=False);
for c in choosen:
    img = mnist['data'].reshape((28, 28))
    img = img / 255.
    img = img.reshape((-1, 1, 28, 28))
    net=cv2.dnn.readNetFromONNX('./mnist/model.onnx')
    net.setInput(img)
    detections = net.forward()
    print('prediction: ', np.argmax(detections), 'answer: ', int(mnist['target']))

を実行すると、

prediction:  3 answer:  3

のように、NN によって予想された結果と、正解が出力されます。

ということで、無事推論できました。

今回は OpenCV 4.0 を使って ONNX が実行できることを確認したかったので、
適当に学習済みのモデルを取ってきて推論を回しましたが、
実際はちゃんと train/validation データに分類する必要があります。

参考文献等

*1 https://opencv.org/opencv-4-0-0-alpha.html
*2 https://opencv.org/opencv-4-0-0-beta.html
*3 https://opencv.org/opencv-4-0-0-rc.html
*4 https://rest-term.com/archives/3269/
*5 https://docs.opencv.org/4.0.0/df/d7e/tutorial_table_of_content_gapi.html
*6 https://github.com/skvark/opencv-python

  • https://rest-term.com/archives/3491/
  • https://stackoverflow.com/questions/53224685/trouble-using-opencv-to-load-a-net-from-onnx-python-pytorch
  • https://docs.opencv.org/4.0.0/d0/d1e/gapi.html
  • http://asukiaaa.blogspot.com/2018/03/opencvdnnpythonmobilenet.html
  • https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/
    など。

明日の担当は、@kawano-fusic です。楽しみですね!

I’m a software engineer in Fukuoka, Japan. Recently, I am developing machine learning models using TensorFlow, and also developing Web services by using PHP.

コメントする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です