PyFes 2012.07 に参加した

https://github.com/pyspa/pyfes/blob/develop/201207.rst

f:id:inoshirou:20120729174852j:plain

参加メモ

  • ステッカー
    • カンパしたので、PyFesステッカー2種類とPySpaステッカーを貰った。とても良いものだ
    • 独自言語パイソン ステッカーも貰った
  • ハッカソン
    • テストのハンズオンが気になるも、もくもくすることに
      • PyQt4を触ってみた
    • 使った教材は @ransui さんの「PyQtではじめるGUIプログラミング」
    • スライドを読みながら一通り写経してみた
    • 余った時間で作りたいアプリのスケッチをしてみるなど
  • ランチ
    • 主催者グループにくっついて蟹料理の店「蟹漁師」へ
    • 蟹とトマトのクリームスパゲッティ、うまし
    • #hython と #kabepy の交流があったり
  • プレゼン
    • だいたい置いてきぼり
    • Webクロールはうまく対象を選べば面白そう
    • HBaseについての為になる話は面白かった
    • VagrantとChef便利そう
    • ぁっぉ
>>> import ぁっぉ
>>> ぁっぉ.ぃぅ()
['ぅゎ', 'っょぃ', 'ヵιュヵ', 'ゅぃぃっ', '']

ボルダリングに興味がある方はこちらにどうぞ(宣伝)

LTなどで少し触れられていたので宣伝してみる。

ボルダリングをお勧めするのは筋トレとかダイエットの為ではなく、ただただ楽しいからですよ!

OpenCVで画像学習したときのメモ

コマンドのオプションすぐ忘れそうなので、自分用のメモ。

参考ページ
http://gihyo.jp/dev/feature/01/opencv/0004

サンプルを作成する

  • ubuntuの場合は、opencv_createsamplesのように、コマンドの頭にopencvが付く
  • コマンドに渡す画像領域の情報は、ググって見つけたWebのツールを使った
  • createsamplesコマンドの実行
    • -info
      • ファイルから情報を読ませる場合に使う
    • -vec
      • 出力ファイル名。適当に付ける
    • -num
      • サンプル画像の数。今回はサイト通り4000で
    • -bgcolor
      • 背景色を指定する。
      • 今回で言えば壁の色を指定する必要があるってことかな?
    • -w, -h
      • 作成するサンプル画像のサイズを指定するらしい
      • これはどう決定するのが最適なのかな?

作ったサンプルを学習させる

  • haartrainingコマンドの実行
    • -data
      • 学習結果の名前をつける、任意でよい
    • -vec
      • サンプルvecファイル名を指定
    • -bg
      • 非オブジェクト画像のリストを指定
      • 要はNG画像だよね?
    • -npos, -nneg
      • number of positive
      • number of negative
      • の略でいいのかな?正解画像数と不正解画像数
    • -w, -h
      • 画像サイズ。vec作成時のサイズに準ずる
    • -mode
      • 使用するオブジェクト検出特徴の種類を指定するらしい

その他

  • 思ったよりも学習速度早かった
  • ステージが0~13の計14ステージだったのかな
  • dataに指定した名前のxmlファイルとディレクトリが作成された
    • ディレクトリには数字のディレクトリが出来てた
    • 各ステージの途中経過は保存されるとか書いてあったので、これがそうだと思われる

Python mini Hack-a-thon で OpenCVを触ってみた

(第20回)Python mini Hack-a-thon

http://connpass.com/event/545/

参加してきました。3回目。

OpenCVを触ろうと思ってみたのは前日で、なんとなく画像認識をやってみたいというただの思いつき。

自分はボルダリングをやっているのですが、壁の画像からホールドやらを認識させることでなんかおもしろい事ができないかなーというのがきっかけ。

Pythonと画像認識で検索したらOpenCVが出てきたので使ってみることにしました。

インストール

インストールはここを参考に。Ubuntuなのでaptitudeでさくっとできるようです。
http://opencv.jp/opencv2-x-tips/install-linuxubuntu

(実際はsearchして適当にそれっぽいパッケージをインストールしたところ、ここに記載してあるうちのパッケージがいくつか抜けてました)

触ってみる

ちなみにOpenCVについてはこれっぽっちも知識がなかったので、まずは簡単な使い方から試していこうと思い

OpenCVで学ぶ画像認識
http://gihyo.jp/dev/feature/01/opencv

これが比較的易しい感じがしたので、これに沿って進めて行きました。ちなみにOpenCVはC++で書かれたもので、上記の連載の中でもサンプルコードはC++です。
OpenCVは公式にPython APIを用意しているため、一部を除いてほぼ同じ記述で問題なく動作しました。

連載では

  • 画像を読み込んで表示するだけ
  • 画像にエッジ抽出処理をかける
  • 画像を回転させる
  • 画像の中の顔を認識する

という流れでコードを示しながら使い方を説明しています。ハッカソンではこれらのコードをPythonで書き直してました。
https://gist.github.com/2982758

画像からオブジェクトを検出する

連載を読み進めることで、画像からなにか特定のものを認識させたい場合は、まずその対象の特徴を学習させる必要があることを学びました。
顔の認識については既に学習済みの検出器がOpenCVに付属しているのでそれを使うだけでしたが、それ以外についてはまず自分でサンプル画像を用意し、それを以って学習させる(検出器を作る)ことが必要です。

ちなみに、「学習に用いる上で効率的なサンプル数は,正解画像7000枚,非正解画像3000枚」らしいです。

OpenCVには一つの画像から大量のサンプル画像を生成するツールも付属しているので、これを活用して手間を省くのが定石なのかな?

ハッカソンでは、このツールを使おうとしたが見つからず(libcv-devパッケージをインストールしてなかった)、うだうだしている間に時間切れとなりました。

今後の目標

とりあえずはボルダリングのホールド(手や足をかける石)を検出するところまでやってみたいですね。
とはいうものの、ホールドの形は一つ一つ違う上に数も多いので、かなり大変な気がしてます。なんとか手間が省けないものかな。

あと、最終的にこんなのできるといいよね、というアイデアもまわりの人から貰ってきました。
どれも最初に書いたボルダリングの壁画像認識に絡めたものです。

  • 課題の難易度を自動判定する
  • 最適なムーブ(手や足の運び方)をサジェストする
  • 新しい課題を生成する

などなど。まあ、どれもハードル高すぎて無理なんじゃないかと思いつつ、本当にできたら楽しそうなので考えてはみようかと思います。

7つの言語 7つの世界 Erlangセルフスタディ 1〜2日目

以前から気になっていたのと、id:Voluntas 氏のお勧めもあって買ってみた。
Erlangだけならさくっと読めそうな感じなので、飛行機本はこっち終わらせたら再開する。

7つの言語 7つの世界

7つの言語 7つの世界

2日目を終えて、ボーナス問題以外のコードを書いてみたので載せておく。

コード

  • 1日目
    • 再帰で文字列の中の単語をカウント&再帰で10まで数える(day01_count.erl)
    • 引数から"success"か"error: Message"を出力(day01_errormsg.erl)
  • 2日目
    • リストからキーワードに対応する値を返す(day02_listutil.erl)
    • 要素毎の合計額を計算するリスト内包表記(day02_comrehension.erl)


ErlangのEshellで遊んでみた - 第2章の続き

先日のエントリはプログラミングErlang(飛行機本って言えばいいのかな?)の第2章の途中まで試してみたので、続きをやる。
まずはタプル。

タプル
2> P = {point, 12, 23}.
{point,12,23}
3> P.
{point,12,23}
4> Person = {person,
4>   {name, joe},
4>   {height, 1.82},
4>   {footsize, 42},
4>   {eyecolour, brown}
4> }.
{person,{name,joe},
        {height,1.82},
        {footsize,42},
        {eyecolour,brown}}
5> Person.
{person,{name,joe},
        {height,1.82},
        {footsize,42},
        {eyecolour,brown}}
6> {_,{_,_},{_,_},{_,_},{_,Eyecolour}} = Person.
{person,{name,joe},
        {height,1.82},
        {footsize,42},
        {eyecolour,brown}}
7> Eyecolour.
brown
8>

Pythonにもタプルはあるが、Erlangのタプルは中括弧で囲む。また、そのタプルが保持している値は何なのかをタプルの1要素目にアトムで表現するのが推奨されているらしい。
上記の例だと、3番目で座標を表す二つの数値を含むタプルを作っているが、先頭の要素に point というアトムを入れている。
6番目ではパターンマッチを用いてタプルの中身を取り出している。このやり方はPythonのシーケンスのアンパックとな似た感じなのですんなり理解できた。使わない値をアンダースコアに突っ込むというコードもどこかで見たことあったような。

リスト

続いてリスト

8> MyCats = [{chibi, 10},{kanta,8},{mikan,7}].
[{chibi,10},{kanta,8},{mikan,7}]
9> MyAllCats = [{hachi, 3},{sora, 2},{umi, 2}|MyCats]
9> .
[{hachi,3},{sora,2},{umi,2},{chibi,10},{kanta,8},{mikan,7}]
10> [Cat1|CatList1] = MyAllCats.
[{hachi,3},{sora,2},{umi,2},{chibi,10},{kanta,8},{mikan,7}]
11> Cat1.
{hachi,3}
12> CatList1.
[{sora,2},{umi,2},{chibi,10},{kanta,8},{mikan,7}]
13> [Cat2, Cat3|CatList2] = CatList1.
[{sora,2},{umi,2},{chibi,10},{kanta,8},{mikan,7}]
14> Cat2.
{sora,2}
15> Cat3.
{umi,2}
16> CatList2.
[{chibi,10},{kanta,8},{mikan,7}]
17> 

他の言語に明るくないので正しくないかもしれないけど、ヘッドとテールという概念を言語機能として持つのは独特だなあという印象。
飛行機本にはLISPプログラマに対してCARだのCDRだのCONSだのといった用語で説明する注釈があったので、関数型の言語では一般的な概念なのかな?
ちなみに、タプルに入れてある値はうちのネコ達から。

文字列
24> Hoge = "Fuga".
"Fuga"
25> [1,2,3].
[1,2,3]
26> [83,117,112,114,105,115,101].
"Suprise"
27> [1,83,117,112,114,105,115,101].
[1,83,117,112,114,105,115,101]
28> "あーらん!".
[12354,12540,12425,12435,65281]
29> [12354,12540,12425,12435,65281].
[12354,12540,12425,12435,65281]
30> 

文字列はダブルクォートで囲む。シングルクォートで囲むとアトムになってしまう。文字列の実態は整数のリストで、リストのすべての要素が文字列として評価できる数値の場合、そのリストを評価すると文字列として扱われるようだ。26番目はすべての要素が表示可能な文字に該当する数値なので評価すると文字列になっているが、27番目は先頭の1が文字に該当しない。
日本語を評価したらエラーになるかなと思ったけど、予想外なことに数値のリストになった。どういうことだろう?返ってきたリストを評価しても文字列にはならなかった。これは入力した"あーらん!"はLatin-1以外のエンコードUTF-8かな?)で入力されて、エンコーディングで扱う範囲を超えているので文字列としては扱えないってことだろうけど。
逆に扱えないのに何で数値には変換出来るのだろう?

パターンマッチ
31> [H|T] = "hogefuga".
"hogefuga"
32> H.
104
33> T.
"ogefuga"
34> 

文字列もリストだしヘッドとテールに分解できるよね。という確認。

疑問点

第2章をざっと流して疑問に思ったことをいくつか。

  • リスト同士を単純に結合するには?
  • リストの末尾に要素を加えたい場合は?
  • リストの要素を始点と終点を指定して別のリストに切り出す方法は?
  • Latin-1以外の文字コードを扱うには?

リストの操作について、スライスで柔軟に値を取り出せるPythonは便利なんだな、というのを再認識。