AndroidでTesseractを使ってみた
http://code.google.com/p/tesseract-android-tools/ を使うとAndroidからでも簡単にOCRれるみたいなので、夏休み中で時間もあることだし試してみようかと。
ビルドの仕方はREADMEに書いてある通りに以下のようにすればOK
cd <project-directory> wget http://tesseract-ocr.googlecode.com/files/tesseract-3.01.tar.gz wget http://leptonica.googlecode.com/files/leptonica-1.68.tar.gz tar -zxvf tesseract-3.01.tar.gz tar -zxvf leptonica-1.68.tar.gz rm -f tesseract-3.01.tar.gz rm -f leptonica-1.68.tar.gz mv tesseract-3.01 jni/com_googlecode_tesseract_android/src mv leptonica-1.68 jni/com_googlecode_leptonica_android/src ndk-build android update project --path . ant release
でハマりやすいのが、学習データ的なものがないので http://code.google.com/p/tesseract-ocr/ の /tessdata から適切なディレクトリに配置しておく必要がある点。これを忘れるとSEGVしまくります。
一応、ギャラリー、カメラから読み込むサンプルを作ってgithubにあげておいた。
https://github.com/komamitsu/Android-OCRSample
肝心の精度は、ちょっとこのまま使うにはナイーブだな〜という感じ。
OCatraをいろいろ直したり、ベンチマークとってみたり
komamitsu/OCatra · GitHub のkeepaliveまわりのバグとかを直したり、モジュール名を変更したりしました。
Eventモジュールを使ってすっきり書いた方が良さげだなぁとか思っているのですが、現状そんなにややこしい制御をしていないので、まぁいいかと。
あとついでに、thin上でSinatraを動かしたやつと、abでrpsを比べてみました (-c 200 -n 4000)。
1st | 2nd | 3rd | 4th | Ave. | σ | |
---|---|---|---|---|---|---|
OCatra (byte) | 3089 | 3197 | 1761 | 3415 | 2865 | 748 |
OCatra (opt) | 4288 | 1809 | 6120 | 3920 | 4036 | 1768 |
Sinatra + thin | 1561 | 1613 | 1595 | 1557 | 1581 | 27 |
bytecode版とnative版でともにSinatra + thinよりも速いのですが、測定値にばらつきがありました。99%のリクエストは一瞬なんですが、1%未満でレスポンスが遅くなるみたい。ちょっと気になるな〜
OCatraを短くかけるように修正
SinatraっぽいOCatraを書いてみた - komamitsu.log で作ったOCatraですが、もうちょっとすっきり書けるように修正。
open Ocatra open HttpCommon open HttpCommon.HttpContent let _ = get "/" (fun r -> say (TextPlain "Hello, World (GET)") ()); post "/" (fun r -> say (TextPlain "Hello, World (POST)") ()); get "/givemeyournameandage" (fun r -> say ( TextHtml ( "<html><head><title>hello " ^ r ++> "name" ^ "</title></head>" ^ "<body><h3>you are " ^ r ++> "age" ^ " years old.</h3></body></html>") ) () ); run ()
SinatraっぽいOCatraを書いてみた
先日、やっつけのWebサーバーを書く際にRubyのSinatraで書いてみたのですが、「簡単に書けて良いな〜」と思ったので、OCamlでもそれっぽいものを適当に作ってみました。
現状はこんな感じでかけます:
open Ocatra open HttpCommon open HttpRequest open HttpResponse let _ = get "/" (fun req -> create_response (Some (HttpContent.TextPlain "Hello, World (GET)")) () ); post "/" (fun req -> create_response (Some (HttpContent.TextPlain "Hello, World (POST)")) () ); get "/givemeyournameandage" (fun req -> let name = HttpParam.find req.param "name" in let age = HttpParam.find req.param "age" in create_response (Some ( HttpContent.TextHtml ( "<html><head><title>hello " ^ name ^ "</title></head>" ^ "<body><h3>you are " ^ age ^ " years old.</h3></body></html>") )) () ); run ()
「それっぽい感じで書けそうかな?」というのを確認した段階なので、肝心の「短くかけるか?」というのはあまり追求してない... 後で暇になったら頑張ろうかなと。
あと、ソースコードの配置とかMakefileとかSignature切ってないとかが、やっつけ感溢れるというか適当なので、これも暇になったら頑張りたい。
あと、OCamlのライブラリ依存を何とかするのが面倒で苦手なので、品質よりも簡単に使えること(できるだけ標準で用意されている環境で使いたい)優先で、HTTPサーバー的なところは自前で実装しています。この辺も結構適当にやってるので暇になったら頑張りたい。
テトリスっぽいやつに自動保存機能つけた
テトリスっぽいゲーム作った - komamitsu.log で書いた Not Found なんですが、アプリを終了させると(というか画面を閉じるだけで)、次はまた最初からになってしまうのが嫌だったので自動的に保存する機能を付けました。で、アプリスタート時に続行可能に。
テトリスっぽいゲーム作った
https://play.google.com/store/apps/details?id=com.komamitsu.ketris
以前、ちょっと時間が空いていた頃、SurfaceViewの練習がてら適当にブロックを書いて動かしてたらテトリスになったので、ちょこちょこと手を加えてそれっぽくしてリリースしました。
途中で幾つか革新的なあいであが浮かんで来たのですが、実装してみてチューニングしてみて結局使い勝手が良くないなぁということで没になり、最終的にごく普通のテトリスになってます。というかそもそもテトリス良く知らないので間違ってるかも...
基本的に、いざというときの自分の暇つぶしに使えるようにしたいなぁと。で、そういう状況は大体がAndroidの電波が届かない地下鉄に乗っているときで、自分的にはそういうとき片手で操作できると嬉しいので、その辺の操作感まわりはちょっと気にしました。
あと、好奇心半分お小遣い目当て半分で、広告を入れてみています。でもゲーム画面が小さくなってちょっと嫌だなぁとか、それだけのためにuse-permission増やす(INTERNETとか)のも嫌だなぁという感じがしているのでどうにかしたいですねぇ。
error: gnutls_handshake() failed: A TLS packet with unexpected length was received
とあるgit repositoryからgit cloneしようとしたら以下のエラーが出てしまいました。
error: gnutls_handshake() failed: A TLS packet with unexpected length was received
で、どうしようか、というメモ。
まず、どうやらgnutlsがエラーを出しているみたいなので、念のため確認と絞り込み。やはりエラーとなる。
$ gnutls-cli -p 443 hogehoge.com Resolving 'hogehoge.com'... Connecting to '123.231.213.123:443'... *** Fatal error: A TLS packet with unexpected length was received. *** Handshake has failed GnuTLS error: A TLS packet with unexpected length was received.
じゃあサーバー側の致命的な問題なのか?ということでopensslを使ってみる。こちらはエラーにならない。
$ openssl s_client -port 443 -host hogehoge.com : (エラーじゃないっぽい内容)
git cloneしたときにどういった経路でgnutlsが使われているのか知りたいので、GIT_TRACE=1で。
$ GIT_TRACE=1 /usr/bin/git clone https://hogehoge.com/git/foobar.git trace: built-in: git 'clone' 'https://hogehoge.com/git/foobar.git' Cloning into foobar... trace: run_command: 'git-remote-https' 'origin' 'https://hogehoge.com/git/foobar.git' :
あと、ltraceを使ってみたときに、/usr/lib/git-coreを触っていたのを見てたので、/usr/lib/git-core/git-remote-httpsを使っているのでは?と何となく思うので、確認
$ ldd /usr/lib/git-core/git-remote-https : libcurl-gnutls.so.4 => /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 (0x00007f32ee49c000) : libgnutls.so.26 => /usr/lib/x86_64-linux-gnu/libgnutls.so.26 (0x00007f32ecee4000) :
ということで、git cloneからgnutlsのエラーまでが繋がった。
で、gitの最新版のソースコードを https://github.com/git/git.git から落としてきて、configure -hすると、--with-openssl と --with-curl があったので付けてみた。その時、libcurl-devっぽのが無さそうで怒られたので、libcurl-openssl-devを入れた。
$ git clone https://github.com/git/git.git $ cd git $ autoconf $ sudo aptitude install libcurl4-openssl-dev $ ./configure --with-openssl --with-curl $ make $ sudo make install
で、こっちを使ったらうまく行った。