2017よーめー日記2017年10月24日火曜日QRコードをデコードする世の中にはあらゆるソースコードがあふれているんですが、ありえないことにQRコードをデコードできるフリーのライブラリっていまだにあんまりないのね。libdecoderqrというライブラリが一番有名なんですが、OpenCVガンガンに使っているからでかいし使いづらい。これではラズパイとかで使えないじゃないか。いうわけで、以前作った最小のOpenCVを元に、外部のライブラリに依存しない単独で動くlibdecoderqrを作ってみました。ライブラリのソースもかなり古いので、最新のg++やclangでもコンパイルできるようにして完成。GitHubにでもコミットして世の中に貢献しなくては。*.cppでコンパイルできます。MacOSXのg++とVisualStudio2013でコンパイルできたので、多分Linuxでも動くと思います。サイズが小さいので組み込みやスマホアプリの開発にも使えると思います。これで以前このブログで紹介したlibwebcamと組み合わせて、USBカメラとラズパイでQRコードを使ったプログラムを動かすことができます。USBカメラでとった画像をいろいろごにゅごにょするのって意外と面白いですね。オープンソースだけで短期間にいろいろな面白いシステムを組むことができます。視差マップを作るおじさんの画像処理勉強シリーズも毎日こつこつひとつづつやってると、勉強することがだんだんなくなってきますね。今日はアイサイトで使われている。視差マップに挑戦です。二つのカメラで撮影した画像から物体の距離を求めることができます。ほんとうはLiDARとかのレーダーレーダーを使って障害物を検出したいのですが、個人的にやるのは無理なので、簡単な複数のカメラを使った障害物検出にしました。実際にアイサイトは特徴点にたいする視差マップを使っていますが、視差マップ自体は特徴点がなくても作ることができます。いうことでいつものように勉強http://ishidate.my.coocan.jp/opencv_20/opencv_20.htmなるほど。StereoSGBM(ステレオセミグローバルブロックマッチング)ということをすればよいのね。いつものようにコピペ流でコードを書きます。いってもコアの処理の部分はたったの四行なので誰でも作れます。オリジナルはRGBで処理していますが、移植をしやすいようにRGBAの32ビットで処理するように変更しました。0;}-----------------------------というわけでこのふたつの画像の視差マップを作ってみました。equalizeHist関数はGPUがないと動かないので、使わないように変更。近い部分が赤色になるようです。なんか正しくできたっぽい。道路の白線認識をする。最近、自動運転って検索するとおじさんのブログが出てきます。おじさん、自動運転の仕事なんてやってないんだけどなぁ・・・。おじさん、お盆休みにレンタカーを借りました。最新のレンタカーってすごいんです。車が道路の白い線からはみ出ると、ぴーっと音が鳴るんです。最近の車は白線がどこがわかるんですね。おじさん、これ作ってみたい。いうわけで、本日は白線認識というものをやってみます。やるか調べてみると、なんかHough(ハフ)変換というものを使うと、直線とか曲線とかがわかるらしい。https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%95%E5%A4%89%E6%8F%9BOpenCVにも関数あるし。http://opencv.jp/opencv-2svn/cpp/feature_detection.htmlというわけで以前のブログで作った最小のOpenCVでHough(ハフ)変換のコードを作成。その辺のWebに落ちている写真で白線認識してみました。0;}--------------------------------------ほんとうに数行コードを書くだけでできちゃうんですね。自動運転って意外と簡単?この画像から白線を検出するとこのようになるらしいです。前回ブログで紹介した射影変換と組み合わせれば道路内で自分の走っている位置とかもわかっちゃいます。いうことで、本日は白線認識についてでした。射影変換してみたスマホのカメラなどでとった写真で斜めになっているものを、正面からみたように変換する射影変換というものがあります。日産の車の360度アラウンドビューモニターとかで使われているあれですね。個人でアラウンドビューモニター作ってやろうじゃないの。いうことでいつものように、C++で射影変換書いてみました。http://wildpie.hatenablog.com/entry/20141112/1415802846理論とかはこのページに書いてあります。ベクトルって難しいなぁ。理論をよく読んでC++で実装します。いっても関数はOpenCVにあるしね。このように写真にある四か所の点の座標を与えると勝手に正面から見た画像に変換してくれます。0;}--------------------------------たしかに正しくできた感じ。共有2017年7月10日月曜日OpticalFlowをしてみた動画の中で物がどれだけ動いているかを数値化するOpticalFlowというものがあります。これを使うと、人や物がどんだけ動いているか画像からわかるらしいです。これを使って自動運転車とかが歩行者検出とかしているのね。いうことで、よしいつものようにC++でOpticalFlowの実験。いつものように、OpticalFlowを実装したC++のライブラリを探すのですが、どうもちゃんと使えるOpticalFlowはまだOpenCVでしか実装されていないようです。OpenCVでかいから使いたくないんだよね。今回はOpenCVからOpticalFlowの関連部分だけを抜き出して使うことに挑戦します。OpenCVって全ビルドすると何百メガもあるんですが、必要なところだけを抜き出して使うと数メガバイトで済むのです。OpenCV2.4.13.2をとってきて、core部分のビルドをします。coreというのはMatクラスの部分です。ベクトル演算をするところです。modules/core/srcとmodules/core/includeにある*.cppと*.hのファイルをどこかのディレクトリに入れます。次に、*.hと*.cppファイルからincludeしているファイルのパスの部分だけを消します。"types_c.h"こんな感じでcoreの部分のファイルを全部持ってきてコンパイルすると、Matクラスが使えるようになります。これでOpenCVのベクトル演算部分だけ完成。これと同じことをimgprocにもすると、OpenCVの画像処理変換処理とベクトル演算部分だけを使うことができます。世の中の大部分の人は、OpenCVの画像処理とベクトル演算部分しか使ってないと思うんですよね。coreとimgprocの50個くらいファイルを取ってきてコンパイルすれば、コンパクトなOpenCVを作ることができます。画像の読み書きの部分は入っていませんが、この二つのモジュールだけもかなりの処理ができ、画像の変換、リサイズ、をすることだってできます。最後にOpticalFlowやTemplateMachingの部分のソースのoptiflowgf.cppやtemplmatch.cppを持ってきます。これでOpticalFlowをするための最小のOpenCVが完成。0;}--------------------------この二つの画像から動いている部分を検出します。画像の動いている部分が1になるようにしてみました。共有2017年7月6日木曜日libwebcamとUSBカメラで遊ぶ最近のディープラーニングブームで、USBカメラを使って画像処理をする機会が増えています。みんなどうやってUSBカメラから画像を取ってきているのかと調べてみると、多くの人がOpenCVやffmpegで動画を取ってきているようです。OpenCVでかいし、コンパイルめんどくさくない?バージョンどんどん上がって互換性なくてコンパイルが通らないし。いうことで、今回は手軽にUSBカメラで画像をキャプチャーすることができるライブラリlibwebcamを使って画像処理をしてみたいと思います。このlibwebcamすごいです。WindowsでもLinuxでも同じようにUSBカメラから画像をキャプチャーできるのです。WindowsはDirectShow経由で、LinuxはV4L2経由で画像を取ってくるので、RasberyPiや試してませんがやAndroid等でも動くはずです。いつものようにlibwebcamのサイトからソースコードをとってきます。http://rojarand.github.io/libwebcam/Linuxのほうは簡単にビルドができるのですが、いつものおじさんのWindowsしかもVirtualBox上のVisualStudio12ではビルドができない。いうかファイル足りないし。ソースを見ながらどうすればVisualStudio2012や最新のVisualStudio2017でビルドできるか考えます。Windows版をビルドするには、どうやらWindows7SDKにはいっているDirectShowのSampleが必要なようです。Windows7SDKにあるDirectShowのサンプルのbaseclassesのソースコードを一式を持ってきます。これWindows8SDKにはないってないんです。してもWindows7SDKを入れないといけない。このソースも一緒にコンパイルすると、次はCLSID_hogehogeが解決しませんとかいうたくさんのリンクエラー。うーんこれはどうやって解決するか書くとめんどくさいので、とりあえず以下のファイルを作ってみました。このファイルも一緒にコンパイルするとリンクエラーがなくなります。<uuids.h>#endif--------------------これで、ビルドができ、ビットマップファイルを作るサンプルが動きます。ここでまた問題が、このサンプルはLinuxでは動きませんと書いてある・・・。調べてみるとどうやら、USBカメラというものはUSBのバス上をMotionJPEGというJPEGファイルでデータが来るらしい。WindowsはDirectShowがフォーマット変換をするのでRGB形式など違うフォーマットで各フレームのデータが受け取れるけれど、LinuxのV4L2はフォーマット変換をしないのでJPEGでしかフレームデータを受け取れないみたいです。いうことで、サンプルを以下のようにJPEGファイルを書き出すサンプルに書き直してみました。0;}--------------------わかりづらいなぁ、はじめからこのサンプルにしとけよ。これで、WindsowsでもLinuxでもラズパイでもAndroidでもカメラからキャプチャーをしてJPEG形式ですがフレームデータを受け取ることができます。最後にこのJPEGをどうやってRGB形式に変換するのか、また、このたくさんのJPEGのフレームデータからどうやって動画ファイルを作るのか。これは以前このブログで紹介したSTBという画像処理ライブラリ、とJO_MPEGというMPEG書き出しライブラリで行います。STBhttps://github.com/nothings/stbJO_MPEGhttp://www.jonolick.com/home/mpeg-video-writerこんな感じに書けばUSBカメラの画像をMPEGファイルに書き出せます。0;}-------------------これで、ラズパイでOpenCVを使わず顔認識とかするロボットが作れる。すると車の自動運転も夢じゃないな。今日はOpenCVを使わないで手軽にUSBカメラで画像認識をする方法でした。昨日書いた、便利なtiny-dnnとstbライブラリ。stbの動画版の簡単に動画ファイルを出力できるjo_mpeg。これらのライブラリと強化学習と組み合わせれば、CaffeとかKerasとかを使わないでDQN(深層Qネットワーク)とかできんでない?と思ったのですが、おじさん仕事が忙しくて、実装や学習させる根性がないので、今日はまずC++で普通の強化学習をやるところまで。強化学習ってなんなのかというと、ここに理論とソースコードが書いてあります。http://kivantium.hateblo.jp/entry/2015/09/29/181954すごいねー。おじさんが大学生だった時代はこんな便利なWebページなかったのね。深くない普通の強化学習はとってもわかりやすいですね。おじさんのような浅い知識でも大丈夫。いつものようにここのソースをそのままとってきて、ちょっと改良。stbで途中経過と結果の画像を作ります。おじさん意地でもC++でやるんです。なんか同じ結果になったぞ。これに深層学習とかDNNとかを組み合わせるとDQNになるらしい。いうことで、次はC++でtiny-DQNとかやりたいんだけどなー。そんなに暇ないしなー。誰かライブラリ作ってくれないかなぁ。共有2017年6月27日火曜日C++ヘッダーだけで動くライブラリstbってなに?前回tiny-dnnのライブラリはヘッダーだけで他のライブラリはインストールしないで動くと書きました。今回はその原理というか中身についてちょろっとみてみたので、説明しようと思います。tiny-dnnのなかでも使われているのですが、世の中にはすごい人がいまして、C++のヘッダーだけで動くいろんなフォーマットの画像を読み込める画像ライブラリstbがあります。https://github.com/nothings/stbこれを使えば簡単にC++言語で画像の読み書きができます。ちょー簡単に画像ファイルの読み書きとリサイズ、さらにいろんな変換ができます。あの重いOpenCV使わないでいいんです。これ大学の実験とかにもつかえるじゃん。PNGとかzlib使っているはずなのでzlibとかもどうしているのかと調べるとさらにびっくり。世の中にはもっとすごい集団というのがありまして、C++のヘッダーだけで動くライブラリをたくさん作っている方々もいます。https://github.com/nothings/single_file_libsこのグループの哲学がすばらしいですね。一つ、ライブラリはCまたはC++で動かないといけない一つ、ライブラリはデスクトップやモバイルなどの複数のあらゆるプラットフォームで動かないといけない一つ、ライブラリは32ビット環境でもでも64ビット環境でも動かないといけない一つ、ライブラリは最大で二つのファイルでないといけない。した理由があるのならば例外も許す。C++のヘッダーだけで動くmpegエンコーダーとかC++のヘッダーだけで動くオーディオミキサーとかもうなんでもあるのですね。これらを使うと、簡単にC++で音声や画像を読み込んで結果を動画で出力できます。機械学習の結果やテストの結果など数値の羅列になりがちなプログラムを簡単にビジュアル化。ラズパイのような非力な組み込みの環境でも簡単に音声や画像の処理ができてすごいことができてしまいます。いうわけで、C++でライブラリを作るときはヘッダーだけで動くように作るといろんな人が使ってくれるらしいです。共有tiny-dnnでディープラーニングしてみた。おじさんWindowsとC++言語大好きなのですが、なかなかWindowsのC++言語で動くディープラーニングのライブラリってないんですよね。ディープラーニングは無理かなと思っていたのですが、C++で簡単に使えるtiny-dnnという深層ニューラルネットワークのライブラリがあることがわかったので、遊んでみました。最近のC++のライブラリの流れとして、ヘッダーファイルだけ取ってくればインストールなしで使えるものが多いですね。Pythonと競争しているのか、Pythonを使う上でめんどくさいライブラリーをインストールする作業をしないで使えるというのはよいですね。ライブラリをインストールすると起きるバージョン問題とか起きないし。いうことでtiny-dnnをGitHubから取ってきます。https://github.com/tiny-dnn/tiny-dnnこのライブラリの作者は日本人のようで、日本人でこんなの作れるなんてすごいですね。最初tiny-dnnのマスターの最新を取ってきたのですが、これだと、なぜかMacやVisualStudio2013でビルドできません。いうとこでv1.0.0.a3のタグのものを取ってきます。なにかデモでも動かしてみようと。tiny-dnnのソースを展開するとexamplesディレクトリにおなじみの文字認識mnistがあるので、それを動かしてみます。Test.cppのように簡単にコンパイルして実行できます。tanh_layer();こんな風に「<<」演算子で連結すると深層ニューラルネットワークが組めるのも面白いですね。Test.cppをコンパイルして実行してみてわかったのですが、学習したデータがないよ。作者のホームページ上で公開している学習済みデータは違うものだし。いうことでTrain.cppを同じようにコンパイルして学習プログラム動かします。../../dataこれで学習するようです。最適化をしないで普通にコンパイルをかけて実行したら、1エポック実行するのに2時間くらいかかるようです。明日までかかるじゃないか。コンパイル時の最適化をマックスにしてもう一度再コンパイルして実行。一回実行するのに2分くらいになりました。これならエポック値30で1時間。ファンがマックスで回りますが一時間くらいするとLeNet-modelというファイルができます。おじさんせっかちなんだよね。なんで機械学習ってそんなに時間かかるんだ。これで、文字認識をすることができる。hati.pngと指定して「8」の文字を認識させてみました。3,41.52178,40.31522,23.789なんと、「3」という結果に。おじさん字を書くの汚いし、確かに「3」と「8」にてるからなぁ。一時間くらいの学習では文字は認識できないらしいです。共有2017年3月21日火曜日プログラムの勉強2020年度から小学校でもプログラムを教えるようになるそうです。どんなプログラム言語で勉強するんでしょうね。個人的にはPythonとかBasicよりはJavaScriptのほうがいいと思っています。その方がきれいにキャラクターがアニメーションしたり、学習意欲がわきそうに思うんですよね。僕が小学生のときは算数の計算がめんどくさくて電卓で計算していたのすが、いまやブラウザに計算式をいれると計算してくれる時代。小学生もおうちのスマホでプログラムとかもできるといいですよね。キャラクターは動きませんがとりあえず小学生でもスマホやPCでJavaScriptのプログラムを作って遊べるサイトを作ってみました。http://2nd.agolamusic.com/trial/jslearning/jslearning.htmlでもこれスマホだとセミコロンとか入力しづらい・・・。考えたら、varとかセミコロンとかなくても文法上大丈夫だね。スマホだけで計算できるじゃん。JavaScriptを実行するサイトは簡単に作れるのですが、世の中にはJavaScriptで書かれたPythonとかBasicもあるので、これらのライブラリを使えば、Pythonプログラムページとかも作れる?おじさんのような悪い大人になると、このサイトにお花とかワニとか電車の絵をつけると高く売れそうな気がしてしまいます。誰かこのサイト買ってくれないかなあ。利権がありますが、JavaScriptのほうがこういうサイトもすぐ作れるし、教材楽に作れそうな気がします。僕の毎日利用している山手線には転職したいと思っている人が多いらしく、かならず扉のところにはいつも転職サービスへの広告があります。仕事に疲れて電車を降りるときふと見上げると転職サービスの広告が・・・・。そんなに転職ビジネスって儲かるんだと思っていたら、転職電車が登場していました。電車の扉はビズリーチ、中刷りもビズリーチ、車内の動画広告もビズリーチ、電車の先頭から最後までもう全部ビズリーチ。毎日たくさん走っている。明電舎、テイジン、楽天、ソニー、募集はいわゆつIT系のソフトウェアエンジニア系の会社ばかり。あらー、日本という国はこんなに理系のエンジニア不足してるんだね。そりゃー、給料が安い旧態依然の自動車メーカーや電気メーカーから人いなくなるわ。会社にいくときもビズリーリ。外に打ち合わせにいくときもビズリーチ。会社にもどるときもビズリーチ。家に帰る時もビズリーチ。家族で出かけるときもビズリーチ。こんな電車に毎日乗るとほんとうに転職したくなっちゃうじゃないか。あらー、うちの会社のおっさんが真剣に見てるよ。共有Android用のPythonをビルドしてみた忙しくてブログが更新できていなかったのですが、大作を作ったので今日は更新。Android端末で動くPythonがない。ラズパイ版のPythonもあるのになんでAndroid版だけないんだ。いうことで、PythonのAndroid版をビルドしてみました。Android)というGoogleの方が移植したAndroid用のPythonのソースをgithubからとってきます。上で、スクリプト言語によるコーディングや、スクリプトおよび対話式インタプリタの実行を可能とするソフトウェアです。等で、今後さらに追加される予定です。呼び出すといった使い方も可能です。--------------------このレポジトリにビルドしたPythonインタープリタのバイナリーも含まれているのですが、出力されたコードがPIEではないため比較的新しいAndroidではこのバイナリーが実行できないのです。仕方がないので自分でビルドします。GoogleにはWindowsはないようで僕のAndroid-NDKがはいっているWindowsマシンではデフォルトのビルドが通らない・・・・・・。いうことで、いくつか修正してビルドします。ソースのコピーsl4a-master/python/srcをsl4a-master/python-build/python-srcにコピーします。sl4a-master/python-build/pythonndk-build途中の3つくらいのファイルでビルドエラーが出ますが、まぁその部分たいしたことないのでコメントアウトすればビルド完了sl4a-master/python-build/python/libs/armeabiこのフォルダにpythonの実行形式のバイナリーとsoファイルが出来上がります。上でできたバイナリーをAndroid端末にもっていって、環境変数LD_LIBRARY_PATHをsoのあるフォルダに設定してあげればpythonを実行することができます。osなどのimport文が通りません。Pythonのライブラリを持ってきます。PYTHONPATHの設定sl4a-master/python/src/Libにあるファイル一式をAndroid端末にもってきて、そのパスを環境変数PYTHONPATHに設定します。これでAndroid端末用のPythonが出来上がります。コンソールのままAndroid端末の開発ように使うもよし、apkにいれてアプリとして使うもよし。今回、SL4Aに含まれているPytyhon2.6をビルドしましたが、Android用のパッチを当てなくてもなんとなくビルドは通るんですね。いうことはPython2.7もビルドできるかも。Android用のPythonのバイナリーだけほしい方はこちら:https://drive.google.com/file/d/0B5M9qMMg3tfQbkNTaUdkUnBHV1k/view?usp=sharingAndroid用のPythonのソース一式がほしい方はこちら:https://drive.google.com/file/d/0B5M9qMMg3tfQeTZ5LXRRcG5INDg/view?usp=sharingPythonって結構簡単にしかも高速にビルドできるのね。Pythonの動作原理を勉強するのにもちょうどいいですね。いうことで今日はAndroid版のPythonのビルド方法の解説でした。地図を表示してみた最近、スマホアプリで近くのお店を探すアプリが増えてきました。自分のいる場所とかで違うアイテムがもらえるゲームの位置ゲーとかもあるし。技術的にどうやってんだろうと思って調べてみました。最近はブラウザでGPSの位置情報が取得できて、その位置情報をもとにJavaScriptでいろいろ処理したり、地図とかを表示しているようです。いうことで位置情報の取得はAPIを呼びだけなので、地図を表示するWebサイトのHTMLをつくってみました。10分くらいごにょごにょJavaScriptを書けば位置情報とか地図ってすぐできんじゃん。(2)視差マップを作る道路の白線認識をする。(3)強化学習してみた。C++ヘッダーだけで動くライブラリstbってなに?tiny-dnnでディープラーニングしてみた。