Cocoa Advent Calendar 2016 23日目openCVをiOS Swift3.0.1で活用する。

こんにちは、iosフリーランスエンジニアの永田大祐と申します。
機械学習の技術を高めて、iosのモバイルに、機械学習を繋げるエンジニアになります。
よろしくお願いします。

今回は、Swift3.0.1Xcode8.2の環境で実施する。
openCVライブラリーを紹介したいと思います。
Qitaの画像もopenCVを使用しております。

openCVは、機械学習を学ぶうえで、取り組み始めたライブラリーです。

#opeCVとは
コンピュータービジョンライブラリーで、Linux,Windows,MacOSX上で動きます。

多くは、監視、認識するようなアプリケーションで活用されています。

opeCVの特徴は、基本データ型です。Cの観点からは、基本的ではないようです。
データ型には全てコンストラクタメソッドがあります。
「コンストラクタ」は引数のリストを取り、適切な値の集合体の構造体を返す。インライン関数です。


#openCV、GitHubの詳細ページ
https://github.com/opencv/opencv

#openCVダウンロードサイトがあります。
http://opencv.org/downloads.html
この中にある、各OS専用のリンクページを開くと自動的にダウンロードできます。

#参考文献

現在はopenCVも３系ですが、リンク先は2.4とバージョンが古いですが、c++でコーディングが大量にあり、Swiftで書き換えるのに参考になります。中身は完全c++なので、呼び方など、アレンジしないと全く使えないので、superクラスの型から把握すると、Swiftから呼べるようになるかもしれません。
http://opencv.jp/cookbook/

BLE通信とともに参考にさせていただきました。パクってはいません。
http://www.slideshare.net/t26v0748/opencv-30-on-ios

こちらも参考にさせていただきました。パクってもコピーしてもコンパイル通りません。iosのSwiftで実施したので、、、。
http://qiita.com/icoxfog417/items/53e61496ad980c41a08e



本は、、、
どこぞの方が読みやすい、分かりやすいと好評されていたので、いざ覗いてみたら、約600ページあります。めちゃ難しい本です。　鉄の意志とか思いました。
https://www.amazon.co.jp/詳解-OpenCV-_コンピュータビジョンライブラリを使った画像処理・認識-Gary-Bradski/dp/4873114136/ref=sr_1_1?ie=UTF8&qid=1482059865&sr=8-1&keywords=opencv+amazon
でも毎日しっかり読めば、僕も面白い本と、思いました。


#今回取り組んだこと
####リアルタイムで検知して、グラフィックを実施すること。

顔認識をしたら、Bluetooth通信している端末に情報を飛ばし、音声通知をするというものです。


![openCV.gif](https://qiita-image-store.s3.amazonaws.com/0/131469/4976f720-7058-ea5a-2624-008f0c9962ed.gif)


####BLE通信を実施する目的で、ライブラリーを作りました。
https://github.com/daisukenagata/BLEView

opeCVの認識結果を、BLE通信するために使用しました。
で必要な手順は
##[Swift愛好会 Advent Calendar 2016 23日目　Swift3 Bluetoothライブラリーの紹介](http://qiita.com/daisukenagata/items/1e5784dbff8d0428f993)      こちらにBLEの詳細がありますので、合わせてお読み願います。


podファイルには↓と記載して、pod install

     pod "BLEView"　
     pod 'OpenCV'

クラスには↓と記載。
   
     class ViewController: BLEView 

ライブラリーで文字列が呼ばれるように設定してますので、textSamに適当に文字列の値を渡せば、通信が走ります。BLE通信の呼び出し方法としては↓と記載。

     self.setVoice(ddd:self.textSam.text!)

BackGroundでも通信を走らせたい場合は、

<img width="736" alt="スクリーンショット 2016-12-18 午後7.48.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/f279c8d1-bb47-63af-9af1-9605280d8be8.png">



info.plistの設定、

    カメラ機能に必要なkey
    Privacy - Camera Usage Description
    アルバム保存に必要なKey
    Privacy - Photo Library Usage Description
    音声に必要なkey
    Privacy - Speech Recognition Usage Description
    BLE通信に必要なKey
    Privacy - Bluetooth Peripheral Usage Description


#iosでのopenCVを活用する手順
1 拡張子ファイル.mmファイルを作成
<img width="729" alt="スクリーンショット 2016-12-18 午後8.37.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/558af0da-d695-56bf-9590-3f1c0817bfb0.png">
通常は、mファイルが作成されますが、c++を呼び出す場合は拡張子をmmに変える必要があります。ここでクラスメソッドを作ります。

2 headerファイル作成
自動で作成されますので、mmファイルで作成したメソッドを宣言します。

3 カスケードファイルを取り込む
こちらは顔認識と目の認識ファイルです。
ディレクトリ構成は、指定はございません。
<img width="258" alt="スクリーンショット 2016-12-19 午前2.58.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/35962fe5-a03d-5ba5-9c0d-0d652458d585.png">

こちらのリンク先から取得できます。
https://github.com/opencv/opencv/tree/master/data/haarcascades


4 Swiftファイルで呼び出し
適当に好きな箇所でコーディングしてください。

詳しい詳細コードは、今年Swift愛好会の合宿で記念に公開しました。

Swift愛好会　会長の記事
http://qiita.com/jollyjoester/items/13035eebe8b3ea275526

詳細コードは、世にはあまり出ていない情報です。
http://www.slideshare.net/DaisukeNagata1

#業務レベルで必要になりそうなポイント

    // 処理時間短縮のために画像を縮小
    cv::resize(gray, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cv::equalizeHist( smallImg, smallImg);
このメソッドで処理スピードを上げることにより、リアルタイムでの解析結果の遅延が少なくなると思います。UIを良く見せる目的で、グラフィックを上げる場合などは用途が異なるので、ios側で解像度をコントロールする必要があります。

#openCVで苦労した点
文字解析はOCRを現在活用して、こちらもopenCVと合わせ技で開発していましたが、初めは、openCVの文字認識を実装しようとしていました。しかし、エラーは出なくとも、コンパイルを通そうとすると、どうしてもエラーが出てしまいました。

対応は、GithubよりopenCVの文字解析ファイルを、iosのプロジェクトに組み込んで読み込ませていました。

openCVのライブラリーのsuperクラスからコードを確認してもエラーになる箇所が見つけられず、GitHubのissueに質問を投げました。
https://github.com/opencv/opencv/issues/7543#event-836233681
<img width="765" alt="スクリーンショット 2016-12-22 午後2.15.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/3aa3fc20-892a-443f-869a-747fcb18faa0.png">

結果はiosモバイルアプリケーションには対応していないようでした。
*今はXcode8.2にバージョンアップしています。

これは、これで、答えがわかり、かなりスッキリしました。

読み込ませることができず、何十時間も苦しんだ挙句、気づいた点がありました。
要するに、人工知能ファイルを自分で生成する必要がある。
人間に限らず、文字認識なども、動くもの、湾曲、などには対応しきれないからです。






#今後の目標
１週間で、今年も終わりです。今年中に今回作ったopenCV,Bluetooth機能を作りこみ、年明けには現在リリースしているアプリをアップデートしようと思います。
https://itunes.apple.com/jp/app/soundchat/id1159413780?mt=8

openCVが用意した人口知能のカスケードファイルというものを使用する状態でしたが、オリジナルの人口知能ファイルを独自に生成したいと思います。
#人口知能ファイル生成を可能にするには:robot: