C

Exifをパースした話

JPEGにはExifと呼ばれるメタデータがはいっていて、F値やらジオタグやらなんやらが入っている(ことがある)のだが、Windowsphoneでそれをいい感じにパースして、さらにジオタグを足してくれるライブラリが見当たらなかったので、自分で適当に書いていた

基本的なフォーマットはぐぐれば割と出てくる(のだが、断片的な解説だけだったりして、複数の情報をながめながら感覚で作っていくしかない)。当然、公式の規格書[PDF]を読む根性など持ち合わせていない。

そんなかんじで自分のプロジェクトで使っていたのだが、最近になってバグがぽろぽろ見つかったのでテストをがんがん増やして直したりしていた。つらかった。はまったことをメモしておく。

  • App1 marker内はbig endianかlittle endianかがベンダによって異なる。すごい。にも関わらずその外側はだいたいbig固定。意味が不明。
  • App1 marker内だけ見たいので固定アドレスを見に行きたくなるが、なぜかたまにApp0 markerとかいうのを持ってるやつがいる。最新の規格書には記載がないようだが… いずれにせよフォーマットは同じなのでしっかり無視してあげればよさそう。
  • だいたいの値がUnsignedなのでまったく気付かなかったのだが、signedな負の数もたまに入ってくる。露出補正値とか。ちなみに2の補数で入っているっぽい。ぐぐってもわからんかったので適当にやってたらばぐって苦労したが、いま仕様書みたらちゃんと書いてあった。最初から読めばよかった。
  • 基本的に小数(実数)は分数の形で入っているのだが、カメラメーカー以外はシャッター時間の入れ方が雑。QX100とかはちゃんと分子に1, 分母に100とかって入れてくるのだが、Lumia 920なんかはすごくて、40003/1000000 みたいな値を入れてくる。おまえその3/1000000秒絶対嘘だろ。表示に気を遣う必要がある。だるい。
  • なんかフォーマットたくさんありそうだしあらゆる画像にちゃんと対応するの無理感がある
  • NFCは単純な構造で楽だった
  • Windowsのエクスプローラは1クリックでメタデータをいじれるようになってしまっているので危険。当然だが1カ所でもいじるとメタデータすべて再構成されるのでバイトオーダも変わるしただひたすらつらい
  • 0th IFDにGPS IFDへのOffsetが書いてあるにもかかわらずGPS IFDの中身が空とかそういう画像もあった。規格上問題ないのかもしれないがつらい。
  • つらい

 

以上

Leap motion が届かないので、SDKだけ入れてみた

Leap motionが発送されるとかされたとか話題になってるけど、特に俺の所に届く気配がない。おもしろくないので、SDKでも入れてみようと思った。

とは言っても3Dとかグラフィックとかまったくわからないし、そもそもWin環境のアプリなんて書いたことないので、どっから手を付けたらいいかわからない。

VC++のsampleがあったので、ビルドできるまでの環境を整えることにした。Unityとかわかる気がしないし、Pythonもアレだしなあ。

Continue reading

Differential Evolution on Ubuntu

Differential Evolution という手法があって、GAより少ない計算量で良い結果が出るかもしれないという話を聞いたので、試してみることにした。
とりあえずhttp://www.icsi.berkeley.edu/~storn/code.htmlでC++(けっこう種類があるのにPerlはなかった)のソース(devcpp.zip)を落としてきて、コンパイルしてみる。C++をまともに自分でコンパイルしたことがほとんど無かったので困った。Makefileくらいつけといてくれたらいいのに。仕方ないのでMakefileの書き方を勉強して書いた。

CXXFLAGS = -Wall
testobjs = DETest.o DESolver.o
bin = test

all: $(testobjs)
	$(CXX) $(CXXFLAGS) -o $(bin) $^

DESolver.o: DESolver.h DESolver.cpp
	$(CXX) $(CXXFLAGS) -c $^

DETest.o: DETest.cpp
	$(CXX) $(CXXFLAGS) -c $^

clean:
	rm $(testobjs) $(bin)

で、これでmake叩くがコンパイルは通らない。このページを良く読むと、MS Visual C++ 5.0とか書いてある。えー。g++じゃないんですか。僕の環境は、Ubuntu 10.04 + gcc 4.4.3です。VC++なんてもちろんないです。

$ make
g++ -Wall -c DETest.cpp
DETest.cpp:71: error: ‘::main’ must return ‘int’
DETest.cpp: In function ‘int main()’:
DETest.cpp:96: error: return-statement with no value, in function returning ‘int’
make: *** [DETest.o] エラー 1

これはまあいい。main()がvoidじゃ嫌だというので、int型に直して、return 0;してあげればおk。

int main(void)
{
  (中略)
	return 0;
}

で、またmake叩くが通らない。

$ make
g++ -Wall -c DETest.cpp
g++ -Wall -c DESolver.h DESolver.cpp
DESolver.cpp: In member function ‘void DESolver::Setup(double*, double*, int, double, double)’:
DESolver.cpp:57: error: argument of type ‘void (DESolver::)(int)’ does not match ‘void (DESolver::*)(int)’
DESolver.cpp:61: error: argument of type ‘void (DESolver::)(int)’ does not match ‘void (DESolver::*)(int)’
・・・・・
(後略)
えー。で、いろいろ調べて、そもそもこの::*的な何かは関数ポインタ的な何かではないのか、とか勉強して、そもそも型が違うじゃないかと。とりあえず&つけとけばいいんじゃない?と思ってつけたら、コンパイラに&DESolver::hoge ってしろ、と言われたので、ぜんぶこうした。

    // 略
		case stBest1Exp:
		    calcTrialSolution = Best1Exp;
			break;

                //↑before after↓

		case stBest1Exp:
		    calcTrialSolution = &DESolver::Best1Exp;
			break;
    // 略

そしたらmake通って、無事Testプログラムも動作した。めでたしめでたし。まあ、この計算結果が正しいのかどうかは知らん。つーかDifferencial Evolutionって日本語だとあんまり情報無いんだけど、いまいちなのかな?あんまり新しい手法でもないみたいだし。まあ試してみるけど。