タグ「programming」が付けられているエントリー

Google Developer Day 2010 DevQuiz

| | コメント(0) | トラックバック(0) Google Developer Day 2010 DevQuiz

今年の夏の自由研究を何やるか決められないまま,既に夏休みなんですが,どうしましょう?と思っていたところ,タイミング良くGoogle Developer Day 2010 DevQuizが始まったので,参加中です.脳味噌コネコネにはちょうど良いです.昨晩から参加して,今のところ,こんな感じです.

gdd2010devquiz01.jpg

とりま,共通問題はサクッとやって,HTML5間違い探しもサクッと終わらせました.認証屋としてOAuthができないなんてのは問題外(というかそういうデモを作ってるくらいだし)なので,サクッとPHPで挑戦して,ムリってなりましたw.Pecl::OAuthはダメだ.realm指定できないw.仕方ないから,PerlのOAuth::Lite::Consumerを使いました.パッケージのスペルを間違えてて,小一時間悩んだのは良い思い出.

んで.Top Favoritesは一切何も関与していないことが判明したので,Super HackersかNext Generationに応募するしかないので,とりま,Super Hackersに挑戦中です.Shiritoriはレベル2までは適当にブルートフォース的なやり方で解けました.レベル3は単語数が増えるので,プログラムを作って挑みました.実装はC言語で.なんとなくPerlの方が簡単に作れた気がする・・・.久しぶりの再帰関数にちょっと四苦八苦しながら,見事に撃退しました.ちなみに,相手の手のことを考えていなくて,解答が合わなくてパニクったのは良い思い出.

残るはPAC-MANとエッセイです.エッセイはまぁいいとして,PAC-MANをどうするかなぁ・・・.これは結構マジで作らないとダメだよなぁ・・・.そもそもパックマンは苦手だから,戦略アルゴリズムを立てられないorz.

というわけで,PAC-MANは置いておいて,解けそうなGoogle Maps APIをやろうかなと思っている.中身的にはMaps APIを叩いて最短経路問題を解けばいいので,高々10点らしいので,マップを作ってダイクストラ法の総当たりでフィニッシュです.でも,手元にダイクストラのプログラムがないので,自宅に戻ってから.

まとめ:
なかなか楽しいです!全く解法が解らないでもなく,めちゃめちゃ簡単でもない.挑戦しがいのある問題って素敵.ところで,GDD2010の開催日が9月28日で,大腸内視鏡検査とバッティングしそうなんだよね・・・.無駄に終わるかもしれんorz.

ちょっと所用があるので,OpenID AXを喋るOPとRPを作ってみた.厳密に言えば,作ってみたではなく動かしてみたなのだが,ネット上に情報が少なすぎる,特にAXを喋るOPの情報が皆無に等しいので,とりあえず書き残しておく.実装はOpenID EnaledのPHP Library 2.1.3を使いました.PHPは5.3系で上手く動かなかったので,5.2.10でやってます.apacheは2.2.12で,OSはUbuntu9.10x64です.

AXを喋るRPの実装
まずはRP側を実装します.examples/consumerを用いれば,RPは簡単に作れます.しかも,サンプルにはSregとPAPEを喋るように作られています.まぁ,普通に動かせば動きます.んで,AXを喋るようにいくつか改変します.基本的にAXはSregやPAPEと同じExtensionなので,参考にしながら実装します.実装に当たっては,当然ながらドキュメントが役に立ちます.読みにくいですけどね.

まずはcommon.phpをいじります.AX関連のクラスを使いますので,doIncludes()の中で,require_once "Auth/OpenID/AX.php"しておきます.papeを参考にすると,ここらで定数などを宣言しているようなので,真似して宣言してみます.

global $ax_attributes;
$ax_attributes = array(
'http://axschema.org/contact/email' => 'email',
'http://axschema.org/namePerson/first' => 'firstname',
'http://axschema.org/namePerson/friendly' => 'nickname');

属性型はaxschema.orgにしました.別に他のでもいいです.次に,index.phpを変更しておきましょう.PAPEの部分を参考にします.というか,バッサリ頂きます.61-67行目を以下のように置き換えちゃいます.

<p>Optionally, request these attributes:</p>
<p>
<?php
global $ax_attributes;
while (list($key, $val) = each($ax_attributes)) {
print "<input type=\"checkbox\" name=\"ax_requests[]\" value=\"$key\" checked />";
print "$key ($val)<br/>";
}
?>
</p>

恐ろしく汚いコードですが,気にしたら負けです.これでIdentifierの入力を尋ねるときに,要求するAXを3種類の中から選べるようにしています.デフォでは全部ONですが. 続いて,try_auth.phpをいじります.まず,SregとPAPEは使わないので,該当部分をバッサリ捨てます.30-38行目がSregで,40-45行目がPAPEなので,コメントアウトするなり,消しちゃうなりして,機能しないようにしておきます.で,この辺りにAXのコードを書きます.

global $ax_attributes;
$ax = new Auth_OpenID_AX_FetchRequest;
$ax_uris = $_GET['ax_requests'];
while (list($key, $val) = each($ax_attributes)) {
if(in_array($key, $ax_uris)) {
$attribute[] = Auth_OpenID_AX_AttrInfo::make($key, 1, false, $val);
}
}
foreach($attribute as $attr){
$ax->add($attr);
}
$auth_request->addExtension($ax);

3行目の$_GET['ax_requests']はindex.phpのチェックボックスからどの属性がリクエストされたかを受け取っています.そんで,その要求されたものを$ax_attributesと比較して,Auth_OpenID_AX_AttrInfoでAXのリクエストにあうように準備します.ちなみに,第3パラメータをfalseにしているので,要求する属性はrequiredではなく,if_availableになります.そんで,$ax->add($attr)で属性セットして,最後にextensionに追加する感じです.このコードはExample usage of AX in PHP OpenIDを参考にしました. 最後に,finish_auth.phpを書き換えます.SregとPAPEを無効にしたいので,41-90行目をバッサリと消しちゃいます.かわりにAX用のコードを書き加えます.

$ax_resp = Auth_OpenID_AX_FetchResponse::fromSuccessResponse($response);
$success .= '<dl>';
global $ax_attributes;
while (list($key, $val) = each($ax_attributes)) {
$ax_data = $ax_resp->get($key);
if(!is_object($ax_data)) {
$success .= "<dt>$val</dt><dd>$ax_data[0]</dd>";
}
}
$success .= '</dl>';

特に解説することもないですけど,AXの返事は$ax_resp->get($key)で取り出しています.Type URIをキーにして,取り出しています.コードを見ればわかると思いますが,何を要求したとか,何が返ってきているかは全く考えず,総当たりにチェックしてます.大した量じゃないし.そのため,!is_object($ax_data)でエラートラップしてます.getメソッドで取り出せなかった場合,Auth_OpenID_AX_Errorが返りますので,objectかどうかのチェックでさばいてます.複数の属性値が返ってきた場合でも最初の1つしか表示しない辺りも詰めが甘いですが,気にしないで下さい.気になるなら,自分で工夫して下さい.僕には必要がないコードです.

AXを喋るOPの実装
続いて,OP側を作ります.examples/serverを使います.こっちが結構に四苦八苦でした.勝手にはまっただけですけど.こっちはいじくる部分はlib/common.phpだけです.まずはSregとPAPE関連を消し去ります.56-76行目がSregで,PAPEは・・・ないですねw.なんだ,OP側のPAPEは実装されていないのか.それはそれとして,Sregが書いてあった辺りに,AX用のコードを書き加えます.

$attributes = array(
'http://axschema.org/contact/email' => 'email@example.com',
'http://axschema.org/namePerson/first' => 'first',
'http://axschema.org/namePerson/friendly' => 'nickname');

$ax_requested = Auth_OpenID_AX_FetchRequest::fromOpenIDRequest($info)->getExtensionArgs();
$ax_response = new Auth_OpenID_AX_FetchResponse();
while (list($key, $val) = each($attributes)) {
if(in_array($key, $ax_requested)) {
$ax_response->addValue($key, $val);
}
}
$ax_response->toMessage($response->fields);

実に,このコードにたどり着くまでに苦労しました.何にはまっていたかは後で説明します.コードは解説する必要がないくらいに簡単です.$attributes[]の中は連想配列でType URIをキーとして,属性値を格納します.んで,$ax_requestedと比較して,リクエストされている属性を$ax_response->addValue($key, $val)でセットします.以上で完成です.

動作例

100608_ax01.jpg

これはRP側です.http://localhost/rp/です.色々突っ込みどころ満載ですが,デモですからスルーして下さい.Identity URLのところに,自前OPのidentifierを入れます.AXで取得したい属性をチェックボックスから選びます.とりま,全選択で.

100608_ax02.jpg

こっちがOPからの返事を受け取ったRPです.要求した属性が全て取得できています.下の黄枠の中にはAXレスポンスの内容を表示してみました.aliasがext0とかになっています.ここで勝手にはまってました.結果的には,これで良かったんです.問題なく動いています.これで,AXを喋るOPとRPはできあがるので,後は煮るなり焼くなり・・・.

はまったところ
OPのレスポンスを作るのに苦労しました.というか,勝手な思い込みです.上記で示したOPのコードでAXを喋らせると,違和感があったんです.例えばこのエントリで例示されているように,ax.type.nicknameでリクエストしたら,レスポンスもax.type.nicknameとax.value.nicknameで返るのが自然のように思います.僕もそうだと思っていましたが,これは全然どうでもいい話でした.ここで例示したnicknameというのはaliasなのですが,aliasについては以下のように書かれています.

The <alias> will further be used to identify the attribute being exchanged.

Final: OpenID Attribute Exchange 1.0 - Final

とのことですので,identify出来ればよろしく,何だっていいようです.なので,ここではnicknameでリクエストしても,レスポンスはfriendlyでもいいわけです.問題なのはレスポンスにおいて,friendly.typeとfriendly.valueが紐付きますので,その関係だけが保たれていれば,aliasは何でもokです.

実際のところ,上記に示したOPが喋るAXはレスポンスとしてext0とかext1というaliasを張ります.最初はこれをみて正規の手続きでやっていないからまずいんだと思い込み,AX.phpやMessage.phpの中にまでダイブして,色々と調査しました.で,追っていけば行くほど,コードは正しそうに見えてくるんです.おかしいと思って確認してみたところ,さっきの例示したエントリでも,profile_imgでリクエストして,imageでレスポンスされている.つまりまとめると,重要なのはaliasではなく,Type URIである.aliasは一意ではない(そんな定めがない)が,Type URIは一意なので,そっちを見ろということである.なるほど当然の道理である.

まとめ:
PHPでAXを喋るOPとRPを実装した.簡易版なので,色々と不十分な実装(特にOP側)となっているが,実証コードには十分である.

201006081344追記:
Apache License 2.0らしいので,10はてブ超えたらソースコード公開する.

ずっと前から書こう書こうと思っていたものをヴァァァーーーーに任せて書こうと思う.「お金が無くてオフィスが買えない!」という人や「金を払うのがばからしいから不正コピーでチーッス」っていうバカのための,ソフトウェアは全部無料でありながらも,まともに研究や勉強ができる環境を準備するお話です.不正イクナイ!

前提:とりあえずパソコンはある(XP時代のもので十分です)

さて,早速ですが,無料のOSから手に入れてみたいと思います.MicrosoftのWindowsはパソコンを買うとついてきますが,基本的に有料です.パソコン代にOS代が含まれているんですよ!Macのことはよく知りませんが,間違いなく有料だと思います.というわけで,それ以外の選択肢となると,思いつくのがLinuxです.というわけで,オレご贔屓のUbuntuを使いたいと思います.また,今回は調子をぶっこいて最新版すぎるDaily BuildなLiveCDを使いたいと思います.i386かamd64のどちらか適切なisoファイルをダウンロードしてください.わからなければ,i386を選んでください.なお,isoのダウンロードは後述のUNebootinでも可能ですが,速度が出にくいので,先にダウンロードしておく方法をオススメしました.どちらでも結構です.

さて,ダウンロードができたらインストールの準備を始めます.isoイメージなので,CDに焼いてしまえば良いと思いますが,最近の流行はUSBメモリブートです.ということで,UNetbootinというツールを利用します.1GB以上あるUSBメモリをPCに差し込んで,ソフトを起動します.なお,ここでisoイメージをダウンロードして自動でゴー!ってしたい方は1番上のDisribuionからUbuntuを選んでDaily_Liveを選びましょう.

100420_ubuntu01.jpg

こんな感じで,さっきダウンロードしたisoファイルを指定して,USBメモリが指定されていることを確認して,okを押します.あとはメッセージに従ってください.なお,USBメモリの中身は消えちゃいますので,その辺だけは注意してください.完成したら,USBメモリからブートさせてください.Ubuntuが起動するはずです.

なお,これ以降の説明は実機ではなくVMware上で行っていますが,基本的に同じですので,気にしないでください.仮想環境を作りたかったんだよー.だからついでに書いているんだよー.ちなみに,VMwareにインストールしたら,簡易インストールがなんたらですごく簡単にインストールできた旨をお知らせしておきます.いや,普通にやっても簡単だけどさ.

100420_ubuntu02.jpg

さて,それはさておき,作成したUSBからブートしたUbuntuはこのような感じだと思います.

100420_ubuntu03.jpg

このまま利用しても良いのですが,常用するのでハードディスクにインストールします!赤枠で括ったアイコンをクリックしてインストールします.手順は割愛しますが,ガイド通りに進めば良いと思います.インストールが終わったらUSBメモリを抜いて,再起動させます.もう終わりに近いです(ぇ.

100420_ubuntu04.jpg

インストール完了後にはもちろんアップデートです!と行きたいところですが,daily buildを使っているので,何もありませんでした.これはこれでつまらない・・・.さて,それでは利用環境を準備していきましょう.

なにはなくともインターネット!とにかくブラウジング!
クラウド時代においてインターネットは重要です.デフォでFirefoxが入っていますので,これを使っても良いと思います.でも,今日はGoogle chromeを入れてみたいと思います!chromeをダウンロードするためだけに,Firefoxを使いましょう(ひどい・・・)!それっぽいのをポチポチ押していって,最後は自動実行に任せてえいや!です(伝わってるかなぁ・・・).パッケージインストーラが起動すると思うので,そのままインストールをポチッとな!

100420_ubuntu05.jpg

こんな感じでパネルに追加すると便利です.これでokです.サクサクです.楽ちんです.

いやいや!オレyoutubeとかニコニコとかみたいねん!
パッケージマネージャを利用して「ubuntu-restricted-extras」をインストールだ!「依存により要求された変更を追加しますか?」と聞かれるので,迷わずにマークを選択でFA.最後に適用ボタンを押しておk.

100420_ubuntu06.jpg

簡単ねっ!

論文読みたいな!PDF!PDF!
Adobe Readerを入れるでもいいんですが,入れなくても普通に開けちゃいます.この辺がWindowsと違うところです.良い感じ♪Adobe Readerを入れる場合はこの辺からインストール

Microsoft Officeが使いたい!
Microsoftのオフィスはないけど,類似品のOpenOffice.orgはあるんです.

100420_ubuntu09.jpg

↑これがワードのかわりのWriterさん.

100420_ubuntu08.jpg

↑エクセルのかわりのCalcさん.

100420_ubuntu07.jpg

↑パワーポイントのかわりのImpressさん.

ちなみに,Googleドキュメントを使うという手もあると思います.悪くないですよ?OOoもGoogleドキュメントも,すごいんだぜ?保存する時にPDFで保存できるんだぜ.優しいね.優しさがにじみ出てるね.

C言語でプログラミングの勉強をしたい!
すればいいじゃん(え.標準でインストールされているはずです.安全のために,パッケージマネージャからbuild-essenialを入れておきましょう.あとは普通にプログラムを書いて,コンパイルして,実行です.コンパイルなどの手順は以下の通り.

$ vim foo.c
$ gcc foo.c
$ ./a.out

簡単だねっ!え?VisualStudioみたいな統合環境が良いだって??そしたら,パッケージマネージャでgeanyってのを入れると良いと思うよ!

100421_ubuntu01.jpg

まぁ,eclipseを入れても良いとは思いますが,依存パッケージが多いので,インストールに時間がかかりますよ?仰々しいプログラムを書くなら,eclipseもよろしいかと.インストールは同じくパッケージマネージャからeclipseを.日本語化とかC言語用の環境準備とか面倒くさいですよ?英語の勉強を兼ねて,英語のままで使うってのも良いかもしれません.

さてそろそろ論文書くか
TeXの出番ですね?わかります.でも,今日は疲れたよ.また今度にしよう!そうしよう!

参考:
軽量アプリを厳選し、Ubuntu 10.04 β2を入れた4GBのUSBメモリでブートした古いノートPCで仕事してみた | Viva! Ubuntu!!
Ubuntuで C言語を使おう | 不定期ソフトウェア開発

scis2010.png

SCISは宮崎からの参加で,今年は3年目になります.CSS×2.0デビューはしていますが,SCISナイトセッションにはデビューしていませんでした.今回,ひょうんなことから「理論と実装のギャップ(仮)」というタイトルで発表の機会を与えられましたので,全力で挑んできました.

SCIS2010ナイトセッション「理論と実装のギャップ(仮)」

発表資料は公開します.ナイトセッションで使わなかったスライドには右上に赤丸が表示されています.基本的には変更していませんが,一部を修正しています.なお,プログラムソースが見えると思いますが,見ないで下さい.

ナイトセッションでは研究速報枠を3分ほどいただきました.どの辺が研究速報なのかは不明ですが・・・.真面目な内容にもかかわらず,やや受けをいただいて,嬉しい限りです.みんなやさしい!

なお,この発表の様子はyoutubeで公開されています.別ソースもあるのですが,公開していいのかどうか・・・.

関連:
素因数分解twitterボットfactoring_botを作りました - 4403 is written
SCIS2009ナイトセッションの資料 - 4403 is written
CSS×2.0 in CSS2008 - 4403 is written
CSS×2.0 in CSS2009 - 4403 is written

まだ夏の自由研究が終わっていない気がしますが,冬の自由研究を決めました.冬はGoogle Chromeの拡張機能を書いてみようかと思っています.HTMLとJavaScriptで書けるらしいので,まぁなんとかなるかなって.JSが心配だけど.これが上手くいった暁にはお蔵入りしているid:d:kakku22との共著論文を再投稿したいと思う.っていつの話やねん!って言われかねないw.

関連:
「HTMLとJavaScriptで作れます」、グーグルが「Chrome拡張」を解説 - ニュース:ITpro
GoogleChromeの拡張を作る上でFirefoxアドオン作者が知っておくべき10の違い【GoogleChromeでニコ動拡張を作ってみた感想】 - love_firefoxportableの日記
青図~夏の自由研究 - 4403 is written
夏の自由研究が頓挫しそうな件について - 4403 is written
夏の自由研究をまだやっている件 - 4403 is written
CSS×2.0 in CSS2009 - 4403 is written

たぶん,まだ誰も書いていなさそうだから,勢いで書いてみる.今日公開になったような気がするGoogleの新しいプログラミング言語であるGoをUbuntu9.04(x86_64)で動かしてみる.てか,最初は失敗したんだ.なのに,ここの説明通りにやったら成功したんだ.何も違わないのに・・・.なので,手順はそのままです.

$ cd ~
$ mkdir bin
$ export GOROOT=$HOME/go
$ export GOOS=linux
$ export GOARCH=amd64
$ export PATH=$PATH:$HOME/bin
$ source .bashrc
$ sudo apt-get install python-setuptools
$ sudo easy_install mercurial
$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT
$ sudo apt-get install bison gcc libc6-dev ed
$ cd $GOROOT/src
$ ./all.bash
$ cat >hello.go <<EOF
package main
import "fmt"
func main() {
  fmt.Printf("Hello, Go!\n")
}
EOF
$ 6g hello.go
$ 6l hello.6
$ ./6.out
Hello, Go!
$

動いた.そんだけ.

関連:
The Go Programming Language
新プログラミング言語「Go」をCentOSにインストールしてみた « zaru blog

初めてjQueryを使った(やや嘘を含む)のだが,包み隠さず正直にその感想を述べるならば,「超便利」の一言に尽きると思う.JavaScriptでの実装をしたことがないわけではなく,普通のJSとPrototype.jsを少々.本格的にJSで何かを書いたことはないです.そんなボクが,やめればいいのに,クライアントサイドだけでグリグリ動くアプリを作ることに.一応,ほかの言語も検討しました.C言語とPHP.どっちも向かなさそうだったので,JSに頼った次第です.

JSを選んだのには理由があって,Twitterでもつぶやいた(誰も反応しなかったけど)んですが,Pubsubhubbubデモみたいなのを作りたかったんです.

http://www.youtube.com/watch?v=ewQBgbysSOQ&fmt=18#t=2m45s 大まじめなつぶやき.pubsubhubbubのデモvideoにある追加されたのがリアルタイムに更新されていく見せ方はどのように実装するんですか??

Twitter / 4403: http://bit.ly/AAYTg 大まじめなつ ...

で.いろいろと調べた結果,jQueryでできるらしかったのです.それがshow()とhide()なんです.そんなわけで,jQueryでプログラムを書いてみたんですが,テラ便利.何が便利かって,充実のプラグイン.かゆいところまで手が届きすぎます.車輪の再発明は不要なので,ライブラリをグリグリ使わせていただいて,自分が手を加える箇所は最小限に.怠けているんじゃないよ?コードの信頼性を上げているんだよ.オレの書くコードなんて信用ならないもんね.それから「そんなことまでできるの!?」と驚きを隠せないのが,jQuery UI.カラーピッカーやスライダーが秒殺実装可能です.

あとは,なんといっても,Ajaxも簡単にできます.AjaxはJSの醍醐味ですね(ちがう?).当初はサーバサイドにもスクリプト(PHPでやるつもりだった)をおいて,JSONでAjaxな感じを思い描いていたわけですが,想定外にjQueryが強力で,クライアントサイドだけで事足りました.すごいぞ!jQuery!デレデレです.

まとめ:
jQueryラブ. 

関連:
jQuery: The Write Less, Do More, JavaScript Library
Plugins | jQuery Plugins
jQuery UI - Home
jQuery 1.3.2 日本語リファレンス
jQuery入門 – ポンクソフト
jQuery 開発者向けメモ

前回,頓挫しそうだったのでぼやいたら,アドバイスをいただいたので,それに従って追試をしてみた.

まず,そもそもQRコードは読めるのか論だが,qr.quel.jpqr-coder.comの両方で作成したものをそのままlibdecodeqrにかけてみたところ,問題なく読み込めた.素材として,使える.

090924_qrcode01.png

続いて,これを印刷して,ARToolKitベースのあれで読み取って,射影変換したQRコードをlibdecodeqrに食わせてみた.結果からいえば,失敗.が.理由は単純で,QRコードの周りに適切な余白をつけることで,デコードできました.

090924_qrcode02.png

おおむね良好.

ということで,今後プログラムに起こす(連続かつ自動で流れるように)べきこと.

  1. QRコードの四隅の座標を取得する
  2. ネガポジ反転する(てか二値化を反転させておけばいい?)
  3. 射影変換する
  4. 周りに余白をつける
  5. libdecodeqrにデコードさせる

うん.だいたいの道筋はできたし,できそうな気配を感じ取った.射影変換に苦労しなくて良かったのは,画像処理屋でない視点からして嬉しい.

夏の自由研究の話なんですが,結構やばいです.図で説明します.

090918_qr01.jpg

こはカメラから取り込んで,二値化処理をしたQRコードと思われる部分です.うまくとれます.これはok.

090918_qr02.jpg

これは二値化して切り取ったQRコード(傾いている)を射影変換したもの.コードはOpenCVです.うまくいってます.これもok.後は,これをQRコードとしてデコードすればよろしい.

090918_qr03.jpg

これがいただけない.射影変換したQRコードをネガポジ反転して,QRコードデコーダであるlibdecodeqrに放り込んだ様子.ステータスコード2009(16進数だよ!)はエラーコードによりますと,以下の通りです.

  • QR_IMAGEREADER_DECODED 0x2000
  • QR_CODEDATA_NOT_SUPPORT_ECI 0x0001
  • QR_CODEDATA_UNRECOVERABLE 0x0008

重傷じゃん!どうすっかなー?こんなにきれいに復元できても,サポート外とか・・・.んなバカなって話ですよ.特定のQRコードしか読めないのかしら??それとも,このQRコードが亜種なのか.QRコードデコーダを自力で書かなくてはならないのだろうか・・・.ボスケテ!

200909200947追記:
nitechの先生からコメント頂きました.P906iでデコードできないそうです.iPhone 3GSの場合,QRコードが悪いのかリーダが悪いのか特定できないくらいに性能が悪いので,旧ケータイのW53CAを使ってみた.結果としては「24」とデコードできました.うーん.これはこれで困る結果だ.どうしよう・・・.

090812_overview01.png

やろうとしていることは,上図のような感じです.QRコードをデコードした後はどうするのかという話は,また別.初音ミクでも表示させておけば良いんじゃないかと思っている.おそらくは,そこから先はOpenGLの出番かと.うーん.勉強するべき技術が多いぜ.

何故こんな流れになっているかと申しますと.最初はlibdecodeqr付属のwebcamサンプルを拡張していたんですが,いかんせん歪みに弱く,QRコードをかなり大きめに撮影する必要がありました.これは複数のQRコードを同時に読ませようとする目的からして,かなり厳しいです.なので,OpenCVで画像処理してやればいいんじゃね?という発想からきています.射影変換等で多少変になっても,RS符号によって誤り訂正しまくってくれることを期待しています.そうすると,今度はOpenCVに処理させるべきQRコードと思われる部分をどのようにして切り出すかという話になるので,それはARToolKitに押しつけた形です.要するには,自力でコードを書く量は最小限にして,既存技術を最大限に活かそうという考えです.目的の本質じゃないところで苦労したくないんです.

というわけで,こんな感じの流れで実装していますが,「はっ?ばかじゃねーの?そんなの××で一発じゃん?」とか「○○を使ってARToolKitで直接QRの領域切り出せよ」とか「△△なら傾いたQRコードでもデコードするし,みたいな?」なんていうご意見や情報等がありましたら,どしどしとお寄せいただきたいと思います.特に,AR業界や画像処理業界の方々からのご意見をお待ちしております.異分野コラボレーションだ!(いや,マジでなにかご意見下さいorz)

090812_ar01.jpg

今日の成果.あとは,選択された領域を切り取って,射影変換して,libdecodeqrに投げてみる.上手くいけば,上手くいくはず.ただ,残念なことに,QRコード同士が近すぎて誤認識が多いです.領域が正方形に近いかどうかというチェックも必要かしら?実際はこんなに詰まった状態では使わないから,無視でも良いかな?

capture_11082009_012108.jpg

赤枠はイメージです.マーカパターンはhiroを使っているので,パターンをシンボルで作り直せば,もうちょっとちゃんと認識するかと.

libdecodeqrでがんばって,複数(といっても2個)のQRコードを同時に認識させることはできた.理論上は何個でも認識するはずなのだが・・・.Webカメラで読み込んでいたり,QRコードは模様が細かかったり,歪み等の補正を何もしていなかったりと,いろいろな状況が重なり合って,2個が限界の上に,全く安定しない.これは困った.

というわけで,libdecodeqrでがんばるのもどうかと思ったので,ARToolKitとOpenCVとlibdecodeqrを組み合わせる方向でがんばってみようかと思う.

で.結局のところ,基本アイディアはQRコード上の初音ミクに戻るのだが,これはlibdecodeqrを使っていないようだし,座標変換してるみたい.座標変換で平面に持ち込めば,libdecodeqrで認識できると信じている.てか,libdecodeqrは読めないQRコードパターンが多いような気がする.特に,バージョンが高くなるとダメぽ.これはカメラの性能だろうか?

なんだか,気合いの入り具合が間違った方向に向いてきた・・・.まずいまずいまずい.もっとさらっと仕上げる予定だったのに!QRコード上の初音ミクのソースが公開されていないから,こんなに苦労するんだ!(責任転嫁)

ARToolKit拡張現実感プログラミング入門

ARToolKit拡張現実感プログラミング入門
著者: 橋本 直
価格: ¥3129(税込)
出版社: アスキー・メディアワークス (2008/9/17)
ISBN-10: 4048673610
ISBN-13: 978-4048673617

工学ナビで有名な橋本氏が執筆したARToolKitの入門書.今更ですが,買ってみました.6日に注文して,8日に発送されて,10日に到着しました.いやいやまさに,入門書です.授業用の教科書にも使えるかと思います.サンプルもたくさん収録されているので,ARToolKitとはなんぞや?というレベルの方に最適です.中身はそれほどに難しくありませんが,行列がでてくるので,その辺の計算や表記法が分かっていないと,その部分を理解するのは難しいかもしれません.が,分からなくても,動かせますw.試しに動かしてみて,それから納得するのが工学ですよね?

まとめ:
入門には最適.オレには不適.もう1冊の方も買ってみようかな・・・.

調べたけど分からない.決定的なものが見当たらない.MSXMLを使うのが簡単そう.だけど,自宅では環境が足りない模様.明日,開発環境でテストしてみるコード.ちなみに,「実証コードには手間を掛けない」が持論なので,簡単にXMLをパースしちゃう言語をご紹介.「これはひどい」で有名なPHPで.

<?php
$string = <<<XML
<a>
<b>
<c>text</c>
<c>stuff</c>
</b>
<d>
<c>code</c>
</d>
</a>
XML;

$xml = new SimpleXMLElement($string);

/* <a><b><c> を探します */
$result = $xml->xpath('/a/b/c');

while(list( , $node) = each($result)) {
echo '/a/b/c: ',$node,"\n";
}

/* 相対パスでも動作します... */
$result = $xml->xpath('b/c');

while(list( , $node) = each($result)) {
echo 'b/c: ',$node,"\n";
}
?>

PHP: SimpleXMLElement::xpath - Manual

実行結果は以下の通り.

/a/b/c: text
/a/b/c: stuff
b/c: text
b/c: stuff

PHP: SimpleXMLElement::xpath - Manual

xpathもできて,かんたーん.

諸事情で,QRコードを複数認識したい衝動に駆られた.で.libdecoreqrってのが便利らしいので,試してみた.現時点までで分かったこと.

  • OpenCVが予想以上に便利だった
  • libdecodeqrで複数QRコードを認識させるには,外側からのアプローチじゃダメそうなので,中身を弄らないとダメそうなことは理解した
  • QRコードの方がイメージしやすいと思ったんだけど,
  • あきらめてARToolKitで複数マーカ認識にした方が良いだろうか
  • 実はARToolKitはあまり得意じゃないです><;
  • ニコニコ技術部のソースファイル(もしくは考え方)がみたい・・・
  • 具体的にはQRコード上のミク

おなかすいた.

学生会員の皆様には会誌6月号にマイクロソフト社の学生支援プログラムのパンフレットを同封いたします。
(これから学生会員に入会される方には入会承認通知に同封予定)
最新の製品を無償で提供するサービスですので、ぜひご活用ください。

パンフレットに自分専用の認証コードがついておりますので、お見逃しのないようご注意ください。

学生支援プログラム(Microsoft DreamSpark)

おや?情報処理学会の学生会員だと,国際学生証がなくても良いのかな?専用の問い合わせ先があるくらいだから,きっとそうなのだろうなぁ・・・.

200906181548追記:
研究室の学生に会誌が届いたので,中身を見せてもらった.

090618_dreamspark01.jpg

このような手順のようだ.この裏面(いや,表面)には認証コード(Microsoftでよく見かける5文字が5セットのやつ)が書かれていて,すぐに使えるようになっているみたいです.国際学生証が必要ないので,手軽に利用できます.

DreamSparkを提供して,1研究会登録費無料なんて,IPSJは学生に対して優しいですっ!入会はこちらから

理系トップクラスの大学院生でこの体たらくとは.CS系の学生には常識中の常識だと思うが,浮動小数点は信用ならないから,正確な演算結果が欲しいなら固定小数点でやる.以下,実証コードをC言語で.コンパイラはBCC32 5.5.1です.

#include <stdio.h>
union test {
double a;
int b[2];
} test;
void main() {
union test a;

a.a = 0.1;
printf("%lf=%x %x\n", a.a, a.b[1], a.b[0]);

a.a = 1.0;
a.a -= 0.9;
printf("%lf=%x %x\n", a.a, a.b[1], a.b[0]);

a.a = 0.09;
a.a += 0.01;
printf("%lf=%x %x\n", a.a, a.b[1], a.b[0]);
}

実行結果はこんな感じ.

C:\Temp>test
0.100000=3fb99999 9999999a
0.100000=3fb99999 99999998
0.100000=3fb99999 99999999

JK.0.1っていう数字を正確に表現できる君は,コンピュータよりも圧倒的に優れているよ.間違いなく.

関連:
Windows の更新の電卓のアクセサリ
グーグルの電卓機能が計算ミス:ニュース - CNET Japan

せっかくだからまとめ.こっちの環境は,Windows XP Pro SP3にVisual Studio 2008 Proです.

ARToolKit on Visual Studio 2008
なんというか,工学ナビ様の通りにやればいいと思うよ.このガイド通りで,トラブルフリーです.最高♪

PTAM on Visual Studio 2008 w/ Web-Camera
こっちはちょっと手こずる.手こずるっていっても,時間がかかるっていうだけで,以下の手順に従えば,できます.今回は現時点での最新ソース(v1.0-r111, Mon, 11 May 2009 16:38:02 +0100)を利用しています.基本的なガイドは以下の通り.

マーカレスAR(PTAM)のソースコードを動かしてみた(WindowsXP VisualC++) | happymeme

今回は最新ソースのREADME.txtに従って,TooN,libcvd,gvars3をCVSからとってくる.ガイド通りだと,build\vc2005となっているが,最新ソースのREADME.txtで示されているリビジョンをダウンロードすると,build\vc2008がありますので,それを使います・・・と見せかけて,slnが変になってるのか,読み込めないので,結局build\vc2005を使うのでした.どんまい!てか,gvars3だけ上手くコンパイルできない.config.hがない件については,config.h.inをリネームします.もう1つのエラーは,以下の通り.

以前のバージョンのソースを参考に、次の行を、

template static T& get(const std::string& name, const T& default_val=DefaultValue::val(), int flags=0);

次のように書き換える。

template static T& get(const std::string& name, const T& default_val=T(), int flags=0);

とりあえず、良しとする。

自己満足なBLOG

えーと.上手くいきません.上手くいかないので,gvars3.hの261行目を以下のように書き換える.

template<class T> static T& get(const std::string& name,
const T& default_val=T(), int flags=0);

実際には改行しないで下さい.準備が整ったら,PTAMをWebカメラで使えるようにいじります.もちろん,工学ナビ様の思し召しのままに.手順としては簡単に述べると以下の通り.VideoSource.hとVideoSource_Win32_EWCLIB.ccをPTAMのルートに.PTAM\Build\Win32にあるVideoSource_Win32_CMU1394.cc以外の3ファイルをPTAM直下にコピー.CameraCalibrator.vcorojの208行目とPTAM.vcprojの368行目を以下の通り書き換える.

書き換え前:RelativePath=".\VideoSource_Win32_CMU1394.cc"
書き換え後:RelativePath=".\VideoSource_Win32_EWCLIB.cc"

後は神に祈るのみ.あ.dxtrans.hの件を忘れていた.

そうですね。
ここにjiapeiさんが書かれている方法を元に編集したら若干警告はあるもののビルドできました。
SampleGrabber も使えました。
私の環境における編集内容は下記です。
//#include "dxtrans.h" ・・・ 495行目
IDxtCompositor //: public IDXEffect ・・・ 979行目
IDxtAlphaSetter //: public IDXEffect  ・・・1484行目
IDxtJpeg //: public IDXEffect ・・・1725行目
IDxtKey //: public IDXEffect ・・・2400行目

オラ検: DirectShowと戦うスレ Part 2 (990) via DirectX SDK November 2007にdxtrans.hが入っていない件について - DenpaFreak

これでコンパイルはできたが,Webカメラがないので,続きは月曜日以降に・・・.

関連:
SourceForge.net: ARToolKit
Parallel Tracking and Mapping for Small AR Workspaces (PTAM)
工学ナビの中の人の研究と周辺 ゼロからはじめるARToolKit on VisualC++ 2008 Express Edition
マーカレスAR(PTAM)のソースコードを動かしてみた(WindowsXP VisualC++) | happymeme
自己満足なBLOG
工学ナビ - BACKYARD
DirectX SDK November 2007にdxtrans.hが入っていない件について - DenpaFreak
オラ検: DirectShowと戦うスレ Part 2 (990)
マーカーレスAR技術「PTAM」をDVカメラで動作させてみる - program - 釣堀.net
PTAMをがんばってみる - 4403 is written

Linuxでやれば簡単なのに!(挨拶)

  1. おもむろに,VMware Playerをダウンロードして,インストールする.
  2. 適当なUbuntuのVMware用仮想マシンを入手する.
  3. 仮想マシンのUbuntuを起動させる.
  4. 適当に,apt-get updateやら,apt-get upgradeやらをやる.
  5. GMPを入れるために,以下のコマンドを打つ.
    $ sudo apt-get install libgmp3-dev
  6. PBC Libraryをダウンロードする.
    $ wget http://crypto.stanford.edu/pbc/files/pbc-0.4.18.tar.gz
  7. 余裕で解凍する.
    $ tar zxvf pbc-0.4.18.tar.gz
  8. ディレクトリに潜って,例のコマンドを放つ
    $ ./cofigure
    $ make
    $ sudo make install
  9. prefixを付けないと/usr/localに入れられるので,コンパイルは以下のように.
    $ gcc -o foo foo.c -I /usr/local/include/pbc -L /usr/local/lib
    -Wl,-rpath /usr/local/lib -l pbc

ね.簡単でしょ?

関連:
Visual Studio 2008でGMPを使う方法 - 4403 is written

タグ

あわせて読みたい