メモ帳DPA

ぐぐってあまり引っかからないような何かがあったら書いたりする

デレステ あんずのうた(Master)のフルコン狙いをなるべく楽するための簡略化

LEGNEと並んで現状最難のこの曲、素直にガチ押ししてても一向に繋がる気配がありませんでした。
仕方ないので出来無いなりにいろいろ小細工を考えてみたところ、最終的にそこそこ上手く行くようになったのでせっかくだしメモしておきます。

コンボカッター1:メデメデ

このゲームでフルコンを阻んでくる要素のほぼ10割くらいはフリックです。
中でもこの曲の4連は拾いづらい上6回も降ってくるので安定させない限りフルコンがかなりの運ゲーになります。
逆に言えばここさえどうにかすればあとは気合とかを駆使すれば流れで何とかなるはず。(何とかなった)


左:元譜面、右:対策版
空打ち判定とスライド始点のタップ判定が存在しない仕様なので、指四本使えば一回で拾えてしまう。
f:id:de0:20150912143649p:plain

実例

ちなみにこの他の方法として

  • 両手で交互に押す
  • 左右組み合わせ(左左右右/左右右右/右右右左...)
  • 右手の人差し指と中指で交互に押す
  • 右スライド後に左スライドを入れて全部一本に繋ぐ

とかも考えたんだけれどもどれもあんまり安定しなかったので結局没。(ただ合うかどうかは人によると思う)

コンボカッター2:むにゃむにゃ

システム上、連続スライドのガイドラインに判定は一切存在しない。
つまり別に一筆書きで取る必要はなく、左右で分業が可能。
f:id:de0:20150912135459p:plain

コンボカッター3:寝ぼけ眼擦ったら

ここだけ等間隔でなく真ん中に半拍入る。ここは取り方というより意識の問題。
f:id:de0:20150912135500p:plain

コンボカッター4:皿

素直に全部右で取ると着地もきつくなるので、むにゃむにゃと同様左右分業に変えることで二重に楽になる。ここ切らなかったら勝ちです。
f:id:de0:20150912135502p:plain


おわりに

LEGNEは対策不可なので頑張りが必要。つよい。

譜面画像の元ネタ

小細工無しでどうにかなってる人の動画

芽兎めうが何故か社畜化するまでとそのテンプレのルーツについて

今週に入ってから何故かめうめうが上司等から理不尽な目に遭う系の改変コピペを頻繁に目にする。
この文書フォーマット自体は音ゲー関連のクラスタではかなり前から何度か見かけてはいたが、それがここに来て何かの拍子で全然関係ないユーザ層にまで到達したんだと思われる。

社畜キャラ?芽兎めうちゃんネタツイートまとめ - さまざまなめりっと


twitter上(の一部)ではだいぶ前の時点から社畜キャラとしてのポジションみたいな所を確立してしまっているが、そもそも芽兎めうは特に社畜とは全く関係ないキャラである。(一応はんこ屋をやっていることになってるが働いてるシーン自体全然ない)

キャラクター:芽兎 めう|「ひなビタ♪」公式サイト

にも関わらず、どうしてこうなってしまったのかが謎過ぎるし誰も大本をちゃんと知らないっぽいのでざっと調べることにした。


めうめうの社畜


めうめうが理不尽に酷い目に逢う起こりはおそらく以下だと思われる。(2014/2/12)

芽兎めうに焼きごてをあてるスレ

勢いで建てられたいわゆるクソスレだが、どういうわけか沈まずに生き残り続け現行でpart10まで伸びている。(中身は別に読まなくてよい)


2013年後半あたりからめうと社畜を関連付けたツイートが徐々に出てくるものの、
この時点では各ユーザ個人での思いつきみたいなものがぽつぽつ展開されているような感じであって、まだ大してバズってはいなかったようだ。


時は少し進んで 2014/7/9、個人的な結論としては、めうめうの社畜イメージを方向づけたのはこれまで文中のみの存在だった社畜めうめうを描いたこの一枚のイラストではないかと思う。

2014.07.09 - SOUDESCA

(補足:ちなみにこれは あかり大好きbot のコンテキストを汲みつつ、徐々に出てきていた社畜ネタを合わせたものと思われる。なおbot以前でも最古では 2012/1/27 から同等の文自体はあり)


元ツイート自体は20RT程度とそこまで伸びていないが、twitter,2ch,tumblr等でこの画像を何度も目にしており、他の音ゲー関連イラストに比べこの画像はかなり各所で使われる頻度が高かったように記憶している。
出典良く分からないまま広まっていて、そのこともあってかどうなのかは知らんが割と気軽に素材的にポンポン貼られていた気がする。

この画像については作者を把握している人のほうが少ないのではないかと思う。自分も実際ちゃんと調べるまで知らなかった。

なおその後に投稿されている以下イラストも同様に出典謎のまま各所に出回っており、イメージの固定化に一役買っていると思われる。(補足しておくと、他にもいろいろと描かれている中からネタ的ないくつかだけが幸か不幸かたまたまヒットしすぎただけであって、作者はむしろ原作にはかなり好意的な方と見受けられる)

2014.07.16 - SOUDESCA

(補足:こっちは ちくわパフェだよ☆CKP を踏んでる)

2014.10.08 - SOUDESCA


twitterで期間指定して適当に検索して見ると分かるが、7月後半あたりからめうめうと社畜を関連付けるツイートが増加しているっぽい。


テンプレ


今のテンプレの原型はおそらくこれだと思われる。(2014/11/26)

華凉 on Twitter: "上司「今日も残業お疲れ様。報告書を書かなきゃね。」
めう「わかっためう。」
上司「めうちゃんは残業を140時間×12ヶ月したことになってるけど、ここに書くのは0時間」
めう「残業時間は0時間…」
#実話を基にしたノンフィクションです"

こちらも元ネタはあまり伸びていないが、これをベースにした以下の診断が作られている。

中卒めう

※訂正:タイムスタンプ的に診断の方が早かったので逆に診断が元だったようです。指摘感謝します
https://twitter.com/N_kuream/status/537300023562616832


なおこの改変は当時からちらほら見かけたものの、2015/2あたりまでは大幅に伸びたものは現れていなかったようだ。

パクころ - 検索 : めうちゃん

おわりに

ひなビタが途中でHDD少女(復活してくれ)の後を追って消滅せずに4期まで来れたのはめうめうの功績が少なからずあるのでもうちょっと労ってあげろ。

パクられてるツイート元をRTするbot(@pakurares)による影響度合いとか伸びたツイートとかについて

以前、 パクられてるツイート元をRTするbot( [twitter:@pakurares] )を作った。
特に手を加えることなく今も継続して稼働し続けている。

de0.hatenablog.com

途中から動作時に多少情報を記録するようにしてたが結局全然使っていなかった。
作ってから一年位経ったことだしせっかくなので暇つぶしにデータを見てみることにした。

データについて

RTする際にその時点でのrt数とfav数を記録している。
なお同ツイートを複数回RTしている場合がたまにあるが2度目以降は記録していない。

基本的に投稿されてすぐのツイートはRTする確率がかなり低く、大体は数ヶ月から数年立っているものが対象になっている。
なので、pakuraresがRTしなかった場合数値はほぼ変動しなかった、というかなり雑な仮定を行うとおおよその効果が見えそうに思う。

統計

4/26時点のRT/fav数から、初回RT時点のRT/fav数をそれぞれ引いた値を計算した。
相当大雑把だが、掘り返したことで新たに加算された値と見ることができる(と思う)

現時点でpakuraresの総ツイート数は2755あるが、
記録し始めたのは途中からなのでデータが有るのはそのうち1635ツイート分になる。

RT fav
平均値 4256 330
中央値 3059 92
最小値 -5679 -1610
最大値 52867 9460
標準偏差 4575 853
RT:favの比率

RT数がfav数に比べ思ったよりもかなり多かった。なんとなく 3:1 くらいの比率の印象に思っていたが意外とそうでもないっぽい。

マイナス値

RTした時点よりも現時点のfav数およびrt数が低くなっているものが割とあった。
RT数で負なのは20個、fav数では371個あった。
あんまり後から消したりは普通しないと思うので、アカウントが消えたことで減少しているっていうのが主要因な気がする。

ただ、ここではfavがRTの値に比べやけに多い。複数アカウントでfav数水増ししているようなアカウントをtwitterがどんどん潰していってるっていうことなんだろうか。わからん。

全体として

botの効果として100程度伸びてくれたら御の字かなと思って作ったのだけれども、想定とは大分桁が違っていた。よいことだ。
しかし仮定の雑さが現れているだけとも読めなくはない。

誤検出について

パクころ をベースに処理しているので、検出は当然完璧ではない。

本当のオリジナルじゃないものをRTするとおかげさまで誰かしら親切な方が指摘してくれる。これのお陰で結構助かっており、誤検出の訂正が行えるのはほぼ全てがこの情報提供によるものである。

オリジナルの情報付きで教えて貰えた場合はそれをRTし、オリジナルでないが元ネタは不明って情報の場合は自力で探している。
どっちにしても、もらった情報には星をつけているので、pakuraresのお気に入り数が大体の誤検出数にあたると思う。

現状のツイート数2755に対してお気に入り数が73だったので、大体 2.6% 程度と思われる。
思ったよりは結構低いが、それでもそこそこミスっているとも取れる値なので、何か対処が打てれば良さそうに思う。が、思いつかないので保留。

人力での元ネタ探しについて

以下のステップで確認している。そんなに大した手間は掛からず数分で済むのでやってみて欲しい。

  1. パクころ - 検索 : に特徴的なワードを入れて収集済みのツイートに類似の文面が無いか
  2. 特徴的なワードをGoogle検索し、検索ツール>期間指定 から終了日に疑惑のツイートの日時を指定し、より古いものはないか
  3. ツイートの画像URLをGoogle検索し、画像で検索 のモードにした上で日時指定して古いものはあるか

RT数増分

どんな感じのが伸びたのかを貼っていく。
10000以上伸びてたのは130個、1000以上伸びてたのは1285個あった。

1位
RT fav
RT時点 7423 7423
現在 60290 12272
増分 52867 4849

パクころ - パクリ詳細 : 467485894052573186



2位
RT fav
RT時点 29848 29848
現在 79950 35195
増分 50102 5347

パクころ - パクリ詳細 : 372324956253589504

3位
RT fav
RT時点 18632 18632
現在 53901 18608
増分 35269 -24

パクころ - パクリ詳細 : 498135114530824193

4位
RT fav
RT時点 40933 40933
現在 73997 43731
増分 33064 2798

パクころ - パクリ詳細 : 488900649086484481

5位
RT fav
RT時点 12982 12982
現在 45852 15440
増分 32870 2458

パクころ - パクリ詳細 : 455908776722178048



fav数増分

3000以上伸びてたのが25個、1000以上伸びてたのは157個。

1位
RT fav
RT時点 14339 14339
現在 33471 23799
増分 19132 9460

パクころ - パクリ詳細 : 451299782598721536

2位
RT fav
RT時点 9383 9383
現在 33134 18752
増分 23751 9369

パクころ - パクリ詳細 : 344433191278501888

3位
RT fav
RT時点 7682 7682
現在 20028 15873
増分 12346 8191

パクころ - パクリ詳細 : 484465161017647104

4位
RT fav
RT時点 5010 5010
現在 18425 12940
増分 13415 7930

パクころ - パクリ詳細 : 457490024351547392

5位
RT fav
RT時点 6943 6943
現在 13994 14591
増分 7051 7648

パクころ - パクリ詳細 : 497367349356281856




その他

上記は元々伸びていたやつが掘り返しにより更に再燃した感じである。では埋もれていたものに対する効果はどうか。
初回RT時点でのRT数が400以下のものからの増加率の高いものからいくつか見てみた。

良い例1
RT fav
RT時点 304 304
現在 4941(16.3倍) 2188(7.2倍)
増分 4637 1884

パクころ - パクリ詳細 : 292424545040756736




良い例2
RT fav
RT時点 350 350
現在 3425(9.8倍) 444(1.3倍)
増分 3075 94

パクころ - パクリ詳細 : 227322315627696128




良い例3
RT fav
RT時点 397 397
現在 3604(9.0倍) 3044(7.7倍)
増分 3207 2647

パクころ - パクリ詳細 : 399376423804076032




悪い例1
RT fav
RT時点 322 322
現在 5642(17.5倍) 391(1.2倍)
増分 5320 69

パクころ - パクリ詳細 : 288250656681230338

この件についてざっとGoogle先生に伺うと、文字の強調とかが大好きな感じのテンション高めの記事ばかりが出てきて冷静な情報が見つからず、かなり煽り感が高いが、少なくとも 神戸市のサイト を見ると現時点では普通に氏名という表記が使われている。
3年も4年も前の情報である上に眉唾ワード大集合みたいな感じにも関わらず大幅にRT数が伸びており、誰も日付をろくに見ていないことが分かる。
そもそもこれをパクっている人がいるのが謎だ。


悪い例2
RT fav
RT時点 359 359
現在 5657(15.8倍) 3549(8.0倍)
増分 5298 3190

パクころ - パクリ詳細 : 515080312867409920

このツイートと別に以下のようなツイートがある。


偶然にしても内容の構成がかなり似通っており、より強い単語に書き換えただけに見えなくもなく、オリジナルとしてはかなり黒いラインではある。
検出アルゴリズムの都合上、完全なパクリでないこういうものまでは検出出来ないのでこんなケースも起こりうる。



おわりに

twitterにコメント付きリツイートが付いた
要はpermalinkをただ貼るだけで良いので、これを使えば既存のbotツール自体に手を加えなくても似たようなことは出来ると思う。

また、公式RTを使わないにせよ、出典が辿れるということが重要であると思う。
Twitter / Account Suspended
はpixivの画像で構成されており、全てリンクが付加されているのでシンプルかつ誰も損しない良い手法である。


公式RTを使用するbotが増えてくれればと思っていたが一年経った今もその兆しは無いように見える。
丸パクリを自分のアカウントで流すのに比べ、RTばかりしているアカウントを見つけること自体がかなり難しいので、自分が発見できていないだけなのかもしれないが、少なくとも自分の観測範囲では見つけられなかった。

周知が難しいとはいえ、上記に示したようにある程度の効果は収めることが出来てるっぽいので、もっと作ると良いと思う。
botのアカウントから手動で紹介しようと思うので良い感じのがあったり作ったりしたら教えて欲しい。

自分が家に居るかどうかセンサ類無しで検知して照明空調を自動制御させる

やりたいこと

  • 自分が家に戻った際に、ディスプレイ、エアコン、照明を自動でONにする
  • 自分が家から出た際に、ディスプレイ、エアコン、照明を自動でOFFにする

閃いた方法

最初は部屋の扉に赤外線センサでも付けて判別しようかと思っていたんだけれども、もっと良い方法を思いついた。
よく考えたら外出時は端末を常時持ち歩いているので、端末が自宅のLANに繋がっている時は自分が存在すると判別できる。
単純かつ追加機器も一切要らない上にセンサ類を使うよりも確実に思える。

やったこと

  1. 携帯端末のMACに対するDHCPサーバの払い出しIPアドレスを固定する
  2. 端末に対してping打って疎通を見る
  3. 結果に応じ学習リモコンを制御

リモコンはAVC300を使っているがPCから制御の効く学習リモコンなら何でも良い。

別に学習リモコンが無い環境でも、特定アプリ立ち上げたりとかWOLさせたりとかいろいろと応用が効くと思う。

Autohotkeyスクリプト

超絶単純なのでAHKじゃなくても何でも書けるはず。

Loop{
	runwait, %ComSpec% /c ping 192.168.1.5 | find "=32" , ,Hide
	if Errorlevel ;未接続時処理
	{
		if (status=FALSE)
			continue

		ControlClick,Button49,AVC300 ; モニタ電源
		Sleep,2000
		ControlClick,Button33,AVC300 ; ライト切
		Sleep,2000
		ControlClick,Button32,AVC300 ;エアコン切
		
		status:=FALSE
	}
	else ;接続時処理
	{
		if (status=TRUE)
			continue

		ControlClick,Button49,AVC300 ; モニタ電源
		Sleep,2000
		ControlClick,Button38,AVC300 ; ライト入
		Sleep,2000
		ControlClick,Button31,AVC300 ; エアコン入

		status:=TRUE
	}
}
  • 状態が変化した際にしか動かないようにしたので、自動で立ち上がった後手動で切っても勝手に上げ直したりもない。
  • pingでわざわざfindしてるのは応答しようがしまいが戻り値が0だったから。
  • pingタイムアウトや回数を減らすと誤爆があったので、安全寄りにデフォのままで良いやってことにした。

良い

かなり正確というか完璧に判断して制御してくれている。
日々の動作が数アクション完全に無くなるってのはかなり気分が良い。


備考:一部Android端末がARPに応答しない件

一部Android端末に、ARPリクエストに応答しないバグ?があるらしく、使ってたのが対象機器だったようで見事に同事象が起きた。
Automateitで、該当のネットワークへの接続をトリガに、http://制御するPCのIP へのバックグラウンドアクセスするルールを作り、端末側からARPテーブル更新させるようにして回避した。

関連

介護用ベッドサイドテーブルのすすめ

言いたいこと

介護用ベッドサイドテーブルすごい使い勝手良いしヤフオクで1万くらいで安く買えるからおすすめ。

使用例

ベッドから横挿し可能かつ全面カバーできる幅がある

f:id:de0:20150110163246j:plain

完全にサイドテーブルとしても切り替え可能

f:id:de0:20150104204528j:plain

通常のデスクに加えてL字デスク的運用

f:id:de0:20150104204329j:plain

自炊時の作業卓

f:id:de0:20150104164436j:plain


キャスター式で一本軸かつ天板がかなり広いって点が重要。
非常に取り回しが良い。

以前のと何が違うか

広い

以前のが42x50cmだったのに対し90x45cmある。
倍以上の幅があり、小さめの普通のデスク程度の面積がある。

安定感高い

支柱は端に一本だけあるだけだがぐらつきが少ない。
耐荷重(スペックには書いてない)も結構高いと思われる。

昇降が容易

ガス式でレバーひとつで調整が可能。
いちいちネジ調整したりが不要。


でかい液晶使わないのであれば普通の机捨ててもこれ一個で行けそうな気がする。
簡易的な構成としては、普通のベッド+ノートPC+介護テーブル だけでもかなり快適な空間が実現出来ると思う。



購入

定価は5万かそれ以上するようだが、ヤフオクでちょくちょく安く出品されており、だいたい1万前後で買える模様。

オフィスチェアとかもそうだが、家具系は全体的に中古だとかなり安くなるっぽい。
自分は12000円で買えたが、もっと安く終了していた場合もあった。

主要な品のリストはAmazonで見れる(値段は高い)ので、適当に当たりをつけておきオークションアラート設定しておけばそのうち買えると思う。


関連

音ゲープレイ中何見てるか調べた+EyeTribe雑感

作った


雑感

良い点はほぼ前回書いてる通りなので、以下に追加で気になった点を書く。

The Eye Tribe 買ったので視線制御で手足を使わず本を読む - メモ帳DPA

見えてる領域に視線そのまま表示すると引きづられる

慣れれば何とかなりそうだが、地味に影響あるので分離したほうがよいと思われる。
ログを取るなり別撮りで合成するか等の手間が掛かるので割と面倒である。


画面は大きすぎても小さすぎてもよくない

でかすぎると端の精度が落ちる。「 The monitor must be max 24”」とある通りなのでこれは仕方ない。
下限については特に記載が無かったが、小さすぎるものも止しておいたほうが良い。
距離が近づくせいもあると思うが、キャリブレーションの難易度が上がり頭動かして良いエリアがだいぶ狭まる。
6.2は無理、9.7でもかなり厳しい。15~26インチくらいがベストな気がする。


ゲーム無理でしょ

公式のPVでWinタブっぽいのにEyeTribe貼り付けて手持ちでFruitNinjaやってる様子があるが、そもそも操作自体を高精度にするのが難しい上、上記の画面サイズの理由もあり実際全然使い物にならんと思う。
カーソル動かないか、爆弾切りまくるか、そうでないにしても手を前に突き出して固定する筋トレと同時プレイすることになるし誇大広告感ある。


同画面に表示さえできれば何でも使える

キャリブレートの際見ていた画面と同じ画面を見る状況にさえすれば、同座標を見ていることになる。
ソフト自体はWin/Macのみ対応だが、測定対象としては同画面から出力さえできれば何でも使える。
タブレットからEyeTribeの接続された機器にVNCすれば、難易度は高いが無理やりキャリブレート出来なくはない。
キャリブレート時のみ一時的にPCつなげば済むので、環境が許すなら表示側に外部入力さえ使えればサイネージでもゲーセンの筐体でもなんでもいけるかと。


ディスプレイ設置ユニットほしい

これも公式にディスプレイ下部にスタンド使わずくっつけてる絵があるが実際には付いてこない。
画面の前に三脚置くの結構邪魔なのであれも付けて欲しかった。
ある程度上向きの角度をつけないとならないので、そのまま貼り付けるだけでは使えず、三脚使わないと実用的な認識ができない。




EyeProofについて

http://www.eyeproof.net/

公式から出た解析用webアプリ。
抽選式のβ版だがEyeTribe持ってると数日でアカウント貰える。


今のところ静止画に対しヒートマップとスキャンパスを作成可能。ヒートマップはこれを使った。


解析対象をWeb上から登録した上でそれと連動するデスクトップアプリのレコーダを起動しデータ収集する。

多数のサンプルからのデータ収集を前提としているらしく、登録時に氏名年齢性別のデータを付加させることが出来る。解析時に特定の対象群のみに絞るような処理やそれを元にした統計処理が出来るっぽい。


選択した可視化の形式が保持されないので一枚一枚選ばなきゃならなかったり、
解析時の画像サイズが解像度に依存しないので高解像度液晶だと画面真ん中に小さすぎる表示になったり、など細かい点は気になったが全体として使い勝手は悪くないしまだβなのでそのうち何とかなると思う。


対応形式増やすつもりもあるようでwebサイトの解析はまもなく対応すると書いてある。
この調子で動画にも対応してほしい。


ソース

SDKが優秀なのでサンプルにちょっと書き足しただけ。簡単。


描画の仕方いじるだけでも地味に遊べる。
やる気はないけどメディアアートとかそういう方向に使えるんじゃねと思った。


import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Color;
import java.awt.Graphics;

import com.theeyetribe.client.GazeManager;
import com.theeyetribe.client.GazeManager.ApiVersion;
import com.theeyetribe.client.GazeManager.ClientMode;
import com.theeyetribe.client.IGazeListener;
import com.theeyetribe.client.data.GazeData;

public class draw extends JPanel
{
	//ウィンドウサイズ
	final static int winwidth = 854;
	final static int winheight= 480;

	//○のサイズ
	static final int ovalsize = 30;
	//描画数
	static final int trackmax = 30;


	//解像度取得
	static java.awt.GraphicsEnvironment env = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
	static java.awt.DisplayMode displayMode = env.getDefaultScreenDevice().getDisplayMode();
	static int width = displayMode.getWidth();
	static int height = displayMode.getHeight();

	static int[][] positions = new int[trackmax][2];


	public static void main(String[] args){
	    JFrame frame = new JFrame();

		draw app = new draw();
		frame.getContentPane().add(app);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    frame.setSize(winwidth, winheight);
		frame.setTitle("");
		frame.setVisible(true);


		final GazeManager gm = GazeManager.getInstance();
		boolean success = gm.activate(ApiVersion.VERSION_1_0, ClientMode.PUSH);

		final GazeListener gazeListener = new GazeListener(frame);
		gm.addGazeListener(gazeListener);

		Runtime.getRuntime().addShutdownHook(new Thread()
		{
			@Override
			public void run()
			{
				gm.removeGazeListener(gazeListener);
			 gm.deactivate();
			}
		});
	}

	public void paintComponent(Graphics g){

		g.clearRect(0, 0, winwidth, winheight);

		for ( int i = positions.length-1; 0 <= i ; --i ) {
			//グラデーションかける
			Color c = new Color(255 - i * (255/positions.length),
								0,
					            i * (255/positions.length),
					            80 - i * (80/positions.length) );
			g.setColor(c);

			//ポイント間の直線
			if(i!=0){
				g.drawLine(positions[i-1][0], positions[i-1][1], positions[i][0], positions[i][1]);
			}

			//ポイント
			int size = ovalsize - (ovalsize/2 * i / positions.length);
			g.fillOval(positions[i][0] - size/2, positions[i][1] - size/2, size, size);

			if(i==0){
				g.setColor(Color.WHITE);
				size = ovalsize / 2;
				g.fillOval(positions[i][0] - size/2, positions[i][1] - size/2, size, size);
			}
		}
	}

	private static class GazeListener implements IGazeListener
	{
		static JFrame parent;
		public GazeListener(JFrame frame) {
			parent = frame;
		}

		@Override
		public void onGazeUpdate(GazeData gazeData)
		{
			int Xpos = (int) gazeData.smoothedCoordinates.x;
			int Ypos = (int) gazeData.smoothedCoordinates.y;

			//履歴の保持
			for ( int i = (positions.length-1); 0 < i; --i ) {
				positions[i][0] = positions[i-1][0];
				positions[i][1] = positions[i-1][1];

			}
			positions[0][0] = Xpos * winwidth / width;
			positions[0][1] = Ypos * winheight/ height;

			if(Xpos == 0 && Ypos ==0){
				positions[0][0] = positions[1][0];
				positions[0][1] = positions[1][1];
			}

			parent.repaint();

			if(Xpos ==0 && Ypos ==0){
				return;
			}
		}
	}
}

The Eye Tribe 買ったので視線制御で手足を使わず本を読む

The Eye Tribe買った

これ

The Eye Tribe

これは何か

$99で買える視線追跡デバイスです。
目の動きを検出し入出力に使えるようになります。

これまでこの手のデバイスは専門的なくっそ高いものを使うか赤外線webcamを頭に固定して自作するかの二択だったんですが、
専用の安価な装置はこれが初なんじゃないかと思います。


先駆者としては以下が詳しい。

The Eye Tribe Trackerを使った視線の記録 - ならば
http://strangelet.hatenablog.jp/entry/2014/03/30/134912

気になったこと

置き場所に結構制約がある

It is important that the Tracker is centered relative to the monitor. The monitor must be max 24”. Note the Tracker should not be positioned above or next to the monitor as the tracking will not function optimally.

http://dev.theeyetribe.com/start/

画面は24インチまで、モニタの中央かつ下限定です。Kinectのように画面上に置くと認識しません。
自分と画面の間に三脚で立つ形になるので常設すると視界の端に入って若干気になります。

実際のところ39インチモニタでも使えましたが、画面端での精度が落ちます。

ちょっと重い

Core i7 3770で常時CPU20〜40%くらい使います。
今のところ別に困るレベルではないものの貧弱なPCだときついかも。

認識エリアが限られる

http://dev.theeyetribe.com/start/

図の位置に頭が入っている必要があります。
姿勢を崩したりするとすぐ外れるのでエリアを意識する必要があり若干面倒ではあります。
ベッドで寝ながら使いたかったんですがしょっちゅう外れるので無理でした。
(それでも完全固定が必要なITU Gaze Trackerに比べれば大幅に認識域が広いのは確かなのですが)

Win/Mac限定

iPadあたりの適当な非対応機器でも視線記録くらいには使えるんじゃないかと甘く見てましたが無理でした。

うまいこと調整できれば使えないこともなさそうですが、

  • VNCで誤魔化してキャリブレーションしてみたがあまり正確でない
  • 液晶下に置く必要があるという制約により操作時に手で領域を塞ぐ
  • 画面まで近いので認識エリアが狭い

のでなかなか厳しかったです。


実用編

何やるにしても自作しないとならない

ソフトは通信用のサーバとキャリブレーションツールしかないので全部自作する必要があります。
最初に文句ばかり書いてしまいましたがそれ以外さして不満もなく精度も結構高いです。

Basics | eyetribe-docs

仕様などはここにありますが、要は視線座標を得るくらいしかないので結構組み込みは簡単です。

割り切り大事

マウス操作はそこそこ思い通りに追従してはくれるものの細かいところの操作までは厳しいので実用的でありませんでした。
とりあえずはある程度割り切って、Leeyesで自炊本を読むときのページ送りに使うことにします。

画面左下を見たらページ送り(下キー)、画面右上を見たらページ戻り(上キー)を送るだけ。
サンプルにちょこっと手加えただけの超単純なものです。

普通に読み進めるだけで何もしなくてもページが切り替わってくのでなかなか快適です。

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;

import com.theeyetribe.client.GazeManager;
import com.theeyetribe.client.GazeManager.ApiVersion;
import com.theeyetribe.client.GazeManager.ClientMode;
import com.theeyetribe.client.IGazeListener;
import com.theeyetribe.client.data.GazeData;

public class eyeControl
{

	//角から何px範囲で操作するか
	final static int areasize  = 700;
	//最速何ms間隔で操作するか
	final static int sleeptime = 1000;
	//何回同エリアで操作するか
	final static int threshold = 5;

	//位置調整
	final static int prevOffsetX = -100;


	//解像度取得
	static java.awt.GraphicsEnvironment env = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
	static java.awt.DisplayMode displayMode = env.getDefaultScreenDevice().getDisplayMode();
	static int width = displayMode.getWidth();
	static int height = displayMode.getHeight();

	//右上
	static int prevx1 = width  - areasize +prevOffsetX;
	static int prevx2 = width  +prevOffsetX;
	static int prevy1 = 0;
	static int prevy2 = areasize;

	//左下
	static int nextx1 = 0;
	static int nextx2 = areasize;
	static int nexty1 = height - areasize;
	static int nexty2 = height;


	//操作ごとに登録
	static keySend prev = new keySend(prevx1,prevy1, prevx2,prevy2, KeyEvent.VK_UP);
	static keySend next = new keySend(nextx1,nexty1, nextx2,nexty2, KeyEvent.VK_DOWN);


	public static void main(String[] args)
	{
		System.out.println(nextx1 + "," + nextx2 + "/" + nexty1 + "," + nexty2);
		System.out.println(prevx1 + "," + prevx2 + "/" + prevy1 + "," + prevy2);

		final GazeManager gm = GazeManager.getInstance();
		boolean success = gm.activate(ApiVersion.VERSION_1_0, ClientMode.PUSH);

		final GazeListener gazeListener = new GazeListener();
		gm.addGazeListener(gazeListener);

		Runtime.getRuntime().addShutdownHook(new Thread()
		{
			@Override
			public void run()
			{
				gm.removeGazeListener(gazeListener);
			 gm.deactivate();
			}
		});
	}

	static class keySend{
		int fromX;
		int fromY;
		int toX;
		int toY;
		int keycode;

		int count;

		static Robot robot;
		static boolean waitflg;

		keySend(int X1, int Y1, int X2, int Y2,int key){
			fromX = X1; toX   = X2;
			fromY = Y1; toY   = Y2;
			keycode = key;

			count = 0;
			waitflg = false;

			try {
				robot = new Robot();
			} catch (AWTException e) { e.printStackTrace(); }
		}
		void send(int Xpos, int Ypos){
			if (waitflg){ return; }

			if( (fromX < Xpos) && (Xpos < toX) && (fromY < Ypos) && (Ypos < toY)  ){
				count++;
				if ( count < threshold ){ return; }

				waitflg=true;

				robot.keyPress(keycode);
				robot.keyRelease(keycode);

				System.out.println(keycode + " \t X:" + Xpos + "\t Y:"+ Ypos);

				try{
					Thread.sleep(sleeptime);
				}catch(InterruptedException e){}

				count=0;
				waitflg=false;
			}else{
				count=0;
			}
		}

	}

	private static class GazeListener implements IGazeListener
	{
		@Override
		public void onGazeUpdate(GazeData gazeData)
		{
			int Xpos = (int) gazeData.smoothedCoordinates.x;
			int Ypos = (int) gazeData.smoothedCoordinates.y;

			prev.send(Xpos,Ypos);
			next.send(Xpos,Ypos);

		}
	}
}

操作よりは記録向きだと思う

アイディア次第でいろいろ作れそうな気はしますが、視線操作を積極的に取り入れるべき場面はあまり無いように思います。
公式のPVでは、レシピ動画送り、楽譜送り、ページ送り、ゲームなどを紹介していましたが、実際のところゲーム以外フットペダルで済みます。
ゲームは何かしら視線制御に対応したものが出ない限り現状ではどう考えても手でやったほうがましです。


記録用途についてはいろいろと調べようがありそうです。
今のところ環境が整ってないので出来てませんが音ゲーの視線位置の追跡なんかは面白そうな気がします。気が向いたらそのうちやる。


なおエロゲーにつきましてはおおむね以下に近い結果になりましたことをここに報告して記事を終えます。

http://strangelet.hatenablog.jp/entry/2014/03/26/205039