2012年1月5日木曜日

仕事始めの前日

あっという間に正月休みが終わってしまった.
今日から2012年の仕事が始まる.
だるく感じる気持ちと,引き締まる気持ちは短時間に,くるくると心の主導権を奪っている.

今年も正月休みを殆ど自宅で過ごしたのだが,
最終日の昨日は,気持ちを切り替えるために日帰り温泉へ出かけてきた.

はじめ近くにあるお山の湯へ行くつもりだったのだが,
いわゆる休みボケを拭い去るつもりで,少し遠いところを目指すことにした.
盛岡から西に片道60キロ程度の乳頭温泉である.

雪深い山奥にある乳頭温泉の露天風呂は,確かに期待を裏切らなかった.

霞むほど遠くまで続くブナの雑木林に深々と粉雪の舞い散る姿を眺めながら,
東屋の下,硫黄の香る露天風呂に浸かるのは,最高の贅沢であった.

3歳と6歳の子供たちは,露天風呂の脇に積もった雪をたらいにいれたお湯に溶かすのが
気に入ったのか,何度もそれを繰り返していた.
なかなか上がると言わず,1時間30分程度 温泉に浸かった.

私は硫黄の匂いが好きだから,硫黄をタップリと含んだ空気を吸い込んでいるだけで,リラックスしているような気持ちになるのだが,実際に体にはどのような影響があるんだろうか興味のあるところだ.
硫化水素は,強力な毒性を持つらしいが毒と薬が表裏一体であることをふまえれば,心地よく感じる温泉の硫黄臭によい効果を期待してもいいのではないだろうか.

硫黄という物質に先人たちは,地獄だとか悪魔と結びつけて考えたのはなんでだろう.
溶岩だとか火山とか火口とか,生物の住めない殺伐とした景色に多く存在するからだろうか.

次々と浮かんでくる疑問を温泉の中では調べることも出来ないから,ただ雪の降りしきる雑木林を眺めているうちに,すべてがどうでも良くなって,心は空っぽになった.

何もできない空間に意図して身を置くことは,心の奥に隠れていた「諦め」という掃除屋を蘇らせて,日常に曇った心をきれいにするということなのかも知れないと私は思った.
人は心を支配しているようで支配をしていないから,自動的なその働きを予測して行動することも,心を維持するためには必要なのだろうか.

2012年1月4日水曜日

Frogpadの分解そして悲鳴

順調にFrogPadの習熟度も上がって,いい気になってきました.
片手で日本語入力できるのは予想以上にスグレモノです.
いい気になって楽しんでいたら,電源が切れなくなっていることに気づきました.
スイッチをスライドしてもOFFされないのです.
常にON状態となっていて,これでは電池が直ぐに無くなってしまいそうです.
オートパワーオフ機能があるので,そのままでもいいのですが,やっぱり気持ち的にOFFしたくなります.
きっとスイッチの爪が外れたんだろうと思い,分解して見ることにしました.
まずこれが,電源のスライドスイッチです.
こいつを動かすと電源ON OFFさせられるんですが,動かしてもぴくりといいません.


分解するには,背面のネジを外すだけのようです.


下の方に爪があり,折れないように木を使いながら開けます.
変な小細工もなく簡単に空きました.


これがバッテリーなんでしょう.パッケージ形状から言ってLipoと思います.


この部分が電源のスライドスイッチです.


ここまで確認したところで,スイッチが外れたとかいう問題ではなく,爪が折れた事が判明しました.
なんと小さいツメでしょう.モールドの部品にスライドスイッチの黒いツメがくっついています.
本来ならこれがスイッチ側にくっついているハズです.
ツメの大きさは1ミリ以下です.
そういえば,お子様がぶつかってきたときに派手に床へおっことした記憶がよみがえってきました.
瞬間接着剤でくっつく代物では無い様な....




...せっかく片手入力の練習を積み上げてきたというのに.
おんなじスライドスイッチ どこかに無いかなあ....
でも型番もわからないし・・・

「キャー」静かに 心のなかで悲鳴をあげて泣いているところです

勾配方向画像のHSV表示スクリプト

画像の勾配方向をHSVに変換するPythonスクリプトです.
OpenCV2.3.1で動作します.2.2系では動かないと思います. 

使い方は,
-i オプションで勾配方向画像を得たい画像ファイルを与え
-o オプションで変換後の画像ファイルを指定します.
-s オプションをつけると変換後に表示してくれます.

 使用例)
 python gradient_direction_hsv.py -i source.jpg -o result.jpg -s

 変換例)


ダウンロード

2012年1月3日火曜日

ロマネスコのピクルス漬けを作ってみた

昨日,茹でたロマネスコが少し余ってしまいました.
フラクタルな模様は子供たちには不評で,悪魔の野菜だとかいって逃げまわる始末です.
捨てるのはもったいないのでツイッターでピクルス漬けにしたという話を思い出して早速作ってみました.
一般的なピクルスの作り方を参考に,ありあわせの材料をジップロックに放り込んだだけなのですが,ニンニクの香りがするだけで美味しそうな気がしてきます.

材料)
穀物酢
100ml
50ml
砂糖
30g
ニンニク
ひとかけ
唐辛子
1本
塩コショウ
適量
ローズマリー
適量

今はジップロックに入れて保存しているところです.
肝心の味のほうですが,フツーにピクルスでした.
まあ,買ったものよりは,おいしいように思います.
ロマネスコのピクルス漬けなんて売ってないからそれだけでも作ってみる価値はあったんじゃないでしょうか.

NIPALSとかPLSとか

昨今の認識アルゴリズムは,マシンパワーにものを言わせて判別に使う情報量をどんどんと増やしていく傾向にあると思うのです. 例えばHOGとかがいい例ではないでしょうか.私の5年前のノートPCでは遅すぎて使いもになりません.

そもそも自分が学習機ならとても覚えられないような情報量を無理やり食わせて,性能をだすことができるんでしょうか. もっとシンプルにやる方法が必ずあるに違いないと心の奥底で私は信じているのですが,今は具体案を提案できている状態ではないので私の主張には説得力はありません.

実際に人間の脳みそは,体重比率で大きなウエイトを占めているわけで,生物の知能が発達すると共に脳みそは大きくなってきたのを鑑みると,高度な情報を処理するためには複雑な仕組みが必要なのだと,暗に示唆されているようにも思えます.高度な知性を実現するには脳みそのような複雑なハードが必要なのだという証だといわれれば反論するのが難しいです.

だけれどもほんの一部でもいいから,シンプルな手法によって人間の知性を計算機の上で実行できないものだろうかと思うのです. 映像から人がどこを歩いているのかだけでも人並みに判別できれば,悲惨な交通事故をもっと減らすことのできる役立つ機械を作ることが出来るはずです.
もしシンプルに計算量の少ないアルゴリズムでそれが実現できれば,安いハードウエアで製品を構成することができるようになり,普及が期待されます.

そこで手っ取り早い方法として性能は保証されているけれど膨大な情報を収集する必要のあるアルゴリズムを使いつつ,その中からあまり重要ではない情報をふるいにかけて情報量を減らして,計算量を減らすアプローチを考えます.このようなことをやる代表的な手法として主成分分析(PCA)があります.PCA-SIFTなどが応用例としていい例でしょう.

でも実際にPCAを分類器に入力するデータの次元圧縮手段として使ってみると,期待したほど性能は良くないんじゃないかという印象を持っています. もちろんそれはケースバイケースなんだと思いますが,画像認識に使うようなデータでは判別結果に使うパラメータの線形独立性を期待できないことがほとんではないでしょうか.

そのようないい加減なデータでもパワフルに働いてくれる次元圧縮方法がないものかと探していたら,先日PLSという手法(Partial Least Square)を見つけました.化学分析分野でよく用いられる方法のようで,例えば,サンプルの各波長における吸光度から,どのような物質がどのような割合で含まれているかなどを分析するために開発された手法のようです.

日本語で書かれたフリーで読める文献がありました.こちらです「PLS 回帰におけるモデル選択」.でも日本語で読んでもなんだかよく分かんなかったです.ちょっと苦しいけれど英語の文献の方が丁寧に書かれていて,理解しやすかったりすることも多いです.これもいいかも知れません「A Beginner’s Guide to Partial Least Squares Analysis
実は自分が参考にした最もわかりやすかった文献のリンクが今探せないです.どこいっちゃったものだか.あとで見つけたら追記しておきます.

このPLSをお手軽にためすには,「R」のplsパッケージを使うのが良いみたいで,PLSの紹介論文などでは,Rに付属のgasolineという吸光度とオクタン価の関係を測定したデータが良く紹介さrています.Rはあんまり好きじゃないので,早速,ガソリンデータを使ってPLSアルゴを試すpythonコードを書いてみました.
def NIPALS_internal(X, Y, n, M, N, u, epsilon):
    u0 = u
    while True:
        w = X.T * u / (u.T * u)
        w = w / norm(w)
        t = X * w
        c_ = Y.T * t / (t.T * t)
        c = c_ / norm(c_)
        u = Y * c
        if norm(u0 - u) < epsilon: break
        u0 = u
    p = X.T * t / (t.T * t)
    q = Y.T * u / (u.T * u)
    Xnew = X - t * p.T
    Ynew = Y - t * c_.T
    return Xnew, Ynew, t, u, p, q, w

def NIPALS(X, Y, k = 1, epsilon = 1e-12):
    n, N = X.shape
    M = Y.shape[1]
    X_mean = X.mean(axis=0)
    X_std = X.std(axis=0)
    Y_mean = Y.mean(axis=0)
    Y_std = Y.std(axis=0)
    X_ = (X - X_mean) / X_std
    Y_ = (Y - Y_mean) / Y_std
    X__, Y__ = X_, Y_
    W = matrix(zeros( (N, k), float32))
    T = matrix(zeros( (n, k), float32))
    U = matrix(zeros( (n, k), float32))
    P = matrix(zeros( (N, k), float32))
    Q = matrix(zeros( (M, k), float32))
    for i in range(k):
        u = Y_[:,0]
        Xnew, Ynew, t, u, p, q, w = NIPALS_internal(X__, Y__, n, M, N, u, epsilon)
        X__, Y__ = Xnew, Ynew
        W[:,i], T[:,i], U[:,i], P[:,i],Q[:,i] = w,t,u,p,q
    B = X_.T * U * (T.T * X_ * X_.T * U).I * T.T * Y_
    return (B, X_mean, X_std, Y_mean, Y_std)
Rのplsに付属のガソリンデータの読み込みと,既述のNIPALS(), NIPALS_predict()の利用シーンは次のような感じです.
def load_gasoline():
    f = open("gasoline.txt")
    reader = csv.reader(f, delimiter=' ', quoting=csv.QUOTE_NONE)
    octane, NIR = [], []
    for i, row in enumerate(reader):
        if i > 0:
            octane.append(int(row[0].strip('\"')))
            NIR.append([float(j) for j in row[1:]])
    return matrix(octane).T, matrix(NIR)

if __name__ = '__main__':
    Y, X = load_gasoline()
    tt = []
    t_y0, t_y1 = [],[]
    for h in range(2,26):
        s = 0
        for i in range(60):
            p = NIPALS(X, Y, h)
            Y_ = NIPALS_predict(p, X[i,:])
            t_y0.append(Y[i,0])
            t_y1.append(Y_[0,0])
            s += abs(Y[i, 0] - Y_[0,0])
        tt.append(s/60)

    gp = Gnuplot.Gnuplot(debug = 1)
    gp.xlabel('X')
    gp.ylabel('Y')
    gp('set grid')
    s = Gnuplot.Data(range(len(tt)), tt, title='error',with_='points 3 3')
    s1 = Gnuplot.Data(range(len(t_y0)), t_y0, title='raw',with_='line')
    s2 = Gnuplot.Data(range(len(t_y1)), t_y1, title='predict',with_='line')
    gp.plot(s, s1, s2)
    raw_input()
これを足がかりにして認識アルゴリズムに応用して性能を試すようなことを正月休みにやってみたいと思っていたけど,子供たちの喧騒の中でブログに書くのが精一杯でした.

休みも残すところ今日の半日と明日1日になってしまいました. そろそろ家出ゴロゴロしているのがだるくなってきたので,これからどこかへ出かけてみたいと思っていますが,人ごみは嫌いであり,はて どこへ行こうか,子供たちは雪遊びできるところへ行けば喜ぶに違いありませんが,心の底から雪遊びを楽しむ心を忘れてしまった私は,寒いばかりなので他にいいところは無いものかと考えるのですが,人ごみも苦手だし,あてもなく困ったものです.

勾配方向画像のHSV表示

HOG特徴とかEOH特徴を使ったスライド資料を作る時など,エッジの勾配方向をかっこ良く色分けした画像を載せると見栄えが良くなりわかりやすい.
その画像だけを作る労力もバカにならないと思うのです.例えばこんな画像のこと

左側は原画で,右側はソベルフィルター処理後に勾配の方向を求め角度によって色分け表示してます.HOGの著者Dalalさんたちの論文に掲載されている画像をイメージして作りました
盛岡の月が丘のあたりで研究用に撮影した画像のなのだけれどストックを手に散歩したおじさんが写っていた.乾いた路面の上なのだがきっとストックがあると足への負担が軽減されるのだろうか

こういう画像のような色分けをするときHSV色空間を使うのだけど使うたびに計算式を調べたりしている.ちゃんと自分のライブラリとして管理するべきなんだけど毎日使うわけじゃないのでつくったコードの存在自体を忘れる始末.毎回ググってる状態なのでいっその事ウェブに掲載してしまえば未来の自分が再利用する確率が高いのかも知れない

という訳でRGBからHSVに変換するコードを載せちゃいます.
プレゼン資料を作るための画像処理は,私の場合はPythonでお手軽にすませるこが多いです.
def hsv2rgb(h, s, v):
    h = float(h)
    s = float(s)
    v = float(v)
    h60 = h / 60.0
    h60f = math.floor(h60)
    hi = int(h60f) % 6
    f = h60 - h60f
    p = v * (1 - s)
    q = v * (1 - f * s)
    t = v * (1 - (1 - f) * s)
    r, g, b = 0, 0, 0
    if hi == 0: r, g, b = v, t, p
    elif hi == 1: r, g, b = q, v, p
    elif hi == 2: r, g, b = p, v, t
    elif hi == 3: r, g, b = p, q, v
    elif hi == 4: r, g, b = t, p, v
    elif hi == 5: r, g, b = v, p, q
    r, g, b = int(r * 255), int(g * 255), int(b * 255)
    return (b, g, r)#cv2.cv.CV_RGB(r, g, b)
よくブログなどに備忘録として掲載しますなどと書いてあることがあって正直なところ意味不明だと思ってたんだけどやっとその思考が理解できたようなつもりになったのでした

追記)
入力画像のエッジ勾配方向をHSV表示するスクリプトを公開しておきました.こちらです

2012年1月2日月曜日

ロマネスコ伐採完了

フタクタルな葉っぱの部分は茹でてマヨネーズにて食べるつもり
茎の部分が大きかったので薄くスライスしてニンニクと軽く炒めてみるのだ.

ただいま.茎の部分を炒めたのを食べてるところ.モグモグ...

キャベツとジャガイモを足して2で割ったような食感と味であります.
次は,フラクタルな葉っぱが楽しみです.





ロマネスコ発見

近所のスーパーで初めて見つけた。ジュリア集合みたいな野菜。食べ方知らないけど買ってみるかな

Android ADK+秋月電子USBホストマイコンボードのその後

Xperia X10を買ってから約1年半.
何か面白い事をやってやろうと思っているうちに時間はドンドンながれて,新しい機種が次々と発表されて,持っている機種への満足度は,指数関数的に減退していくのでございます.
中でもAndroid2.3.4から導入されたAccsessory Development Kitは,ぜひとも使ってみたい機能であったのだけど,私の古ぼけたX10では,使うことができなくて諦めていた.
そこへADKをサポートしたと思われるXperia X10用のカスタムファームを見つけてしまった.これが去年の7月ころのこと.
そのカスタムファームを導入すれば,あとはUSBホスト機能のあるマイコンを使って,Androidの周辺機器を作って楽しめるのではないかと睨んだ私は,まず安く手に入るUSBホスト機能のあるマイコンボードを探してみた.
目に止まったのは「秋月電子 H8 3069/USBホストボードキット」 価格は3000円也.
USBホストドライバーは,SL811が乗っかってる.使ったことはない.
このボードは2004年に発売開始された歴史のあるもののようなので,きっと誰かが使いこなす雛形ソースなどを公開していると期待して調べてみたが,予想は裏切られ見つけることが出来なかった.
サンプルソースコードがついていると秋月のサイトに書いてあったので,それを期待して購入したのだが,残念ながらサンプルとしてしか成立しないレベルの程度のものしかついていなかった.
仕方ないのでADKのArudino用サンプルソースを参考にしながら,H8 3069/USBホストボードで動作するADKデバイス開発を目指し,空き時間に作り込んでみることにしたのだが,今にいたってもADKデバイスを動かすところまでできていない.
なぜかというと,私がX10に導入したカスタムファームは,AndroidのJAVA階層レベルでは,ADKのAPIをサポートしているもののLinuxカーネルがADKに必要な機能を持っていないようなのだ.具体的に言うとカーネルバージョン2.6.29ベースではNGで,2.6.34といったバージョンが必要らしい.
やっとファームの方に,ADKの認識プロトコルを実装し,ADKの門前をくぐることができると期待していた私は,門前払いを受けたことに大いにショック状態となった.
しょぼいファームだけど,それなりにめんどくさい作業をしたので,文字通りガックリ状態.
Xperia X10用の2.6.34系カーネルが公開されるか,あと半年まって新機種に乗り換えるかするまで塩漬けするしかない.

折角つくったファームなので,こっそり公開させて頂きます.AKI-ADKソースコード
HOS-V4を使わせて頂いております.素晴らしいRTOSを公開いただきありがとうございます.
メモリー配置は,GDBでデバッグする状態になっているのでROMに焼いて動作するようにするには,リンカスクリプトをちょっといじらねばなりません.

このファームは,リセット後,ひたすらにUSBスレーブデバイスを探し続け,見つけると接続したデバイスを列挙し,もしAndroidケータイがつながっているなら,ADK接続モードになるはず.
きっと本家Androidならアクセサリとして認識されるんじゃないかと期待しております.
お金があればGoogleから,開発デバイスを買うんだけれどなあ.

2012年1月1日日曜日

テスト

ケータイからポストできるのかをテストしてみる。

片手入力bluetoothキーボードに再チャレンジする

気がつけば2012年1月1日は,あと1時間ちょっとで終わろうとしている.
今年は何か目標を設定しようかと元旦ぐらいは,前向きになってみようと思うのだが,身の丈にあった現実的な目標は,なかなか思いつかないものだ.
いつまで続けられるか分かんないが,このブログを書き続けてみるのもいいかと思えば,早速明日,書かないことになるかもしれないと思えば気持ちはとたんに萎えてくる.

この休み中,棚を整理していたら4~5年前に買ったFrogPadという片手入力用に設計されたキーボードを見つけた.
寝ながらパソコンをやる時にノートパソコンを腹の上に載せ,キーボードを叩こうとすると,どうしてもぎこちなくなる.
そこで良いものはないかと探して見つけたのが,FrogPadであった.
右手用と左手用があり,私は右手にマウスを握り左手にキーボードを握りつつ,気持よく寝そべりながらパソコンをやることをイメージして,左手用を買った.
私のかったFrogPadは,リチウムイオン電池を内蔵していて,インターフェースはBlueToothワイヤレス接続である.
充電は,USBミニジャックを接続して,PCやACアダプタから行うようになっている.
4~5年前に買ったと書いたが,もっと前だったような気もする.
ちなみにFrogPadで検索したら,今もこの会社は存在するようで,もっと薄いタイプの製品がHPに掲載されており,iPadとの連携などを紹介していた.

FrogPadを買ってしばらく使っていたが,寝そべりながら気持よく使うには,かなりの鍛錬が必要だとわかり,私はガックリとした.
楽するために買ったのに寝ながら苦労するのは本末転倒であり,結局今まで放置することとなった.
このキーボードと戯れていたらカミサンに見つかって,「ああ あの片手でできるとかいって,すぐほうりなげてたやつね」と容赦なかった.

掃除して久しぶりに目にしたFrogPadは,なんとなく魅力的に思え,手にとって,それからホコリを払って,汚れを拭いた.
写真は,私のFrogPadを撮影したものである.
クリーム色の筐体は,表面が少し黄ばんでいるのだが,白熱電球の下で撮ったのでよく見えない.
背面のシールには,シリアル番号らしき数字が見え「312」とある.
案外,私は早い時期に飛びついたのかも知れない.

このキーボードは,左手用で片手のみでフルキーボードと同等の入力ができることになっている.
両手分の役割を片手でやるので,五本指で押せる範囲しかボタンが付いてない.
足りない分は,キーの同時押しの組み合わせパターンで補う仕組みになっている.




この忘れ去ってたFrogPadを棚から見つけたのが3日くらい前のことなのだけれど,それから暇さえあれば,ネットのキーボード練習サイトをつかって,FrogPadの練習をした.
なるほどタイピングというサイトは,インターフェースも見やすくて気に入っている.

ここのサイトの都道府県名を使った練習メニューを使い,私がフルキーボード入力した場合と,FrogPad左手用を使った場合の成績を比較してみた.次の通りである.


フルキーボード
FrogPad左手用
比率(full/FrogPad)
入力時間
112
206
1.84
タイプ数
476
476
-
エラー数
13
52
4

平均を取ったり,最も高い成績が出るまで繰り返すことなどはせず,風呂上りに一回づつ測定した結果である.まあ,練習中には,もっと良い成績がでていたような気もする.フルキーボードでは90前後.FrogPadでのベストは192秒ぐらいである.エラー数も高めに出ているかも.長風呂が影響したかも知れない.
とはいえ,普段意識せずキーボードを叩く能力レベルをみる指標としては十分だと思われる.
FrogPadでの入力時間は,フルキーボードの2倍よりは多少早いレベルである.
両手で入力しているのに対して,片手で入力するのだから妥当なところではないか.
エラー数が4倍も多いが,練習すれば減るだろうと見込んでいる.一方,入力速度は,これ以上の向上は見込めないんじゃないかと予想している.

正直に言えばFrogPad左手用の入力は,今はまだ,もどかしい感じがする.
フルキーボードを使うのと同じ姿勢で,勝負してはいけないのかも知れない.
事実,フルキーボードを使うには不便な姿勢では,こいつの方が気持ちよく使える.

買った当初は,諦めたが,今回は少し粘ってみようと思っている.
あと3日ある正月休みのうちに習得して,寝ながら気持よくパソコンやる当初の計画を実現したい.