2014年12月13日土曜日

OpenCVでimreadが失敗するときは

概要と結論を先に書く。

Microsoft Visual Studio の 出力モードを Debug にしたうえで Release としてビルドされた OpenCV の cv::imread を使うと、内部で外側のライブラリか何かを読み込む処理が不味いらしく cv::imread から得られる Mat の data が NULL になる、つまり cv::imread が画像を読み込まない。解決法は出力モードを Release にするか OpenCV のビルドを Debug にするか、のどちらか。

//未試験ではあるがおよそOpenCVをDebugにしてVSをReleaseにしても似たような不具合が起こるかもしれない。

より子細にググりたい人向けに、私の用いた検索ワードは以下の通り

opencv imread debug

気付いた理由はただの勘。

参考になりそうなStackOverFlowの質問へのリンクを張っておく。

c++ - OpenCV imread(filename) fails in debug mode when using release libraries - Stack Overflow - http://stackoverflow.com/questions/9125817/opencv-imreadfilename-fails-in-debug-mode-when-using-release-libraries

--

ググってきた人向けに結論を先に書いておいた。以下は私の日記帳だ。

日記と混ざった技術系エントリを書いてくれる方がたまにいるが、結論にたどり着くまでに日記を読むのはつらいことが多い。誰があなたの食べたラーメンを知りたいのだろうか?技術の話を聞きに来たのに。

人のふり見てわがふり直すべきなので、ググってきた人には先に結論を。日記が読みたい人は日記を読めば良い。読む人がいない?日記帳というのはそういうものだ。

さて本題。久々にOpenCV。といっても最近はOpenCVでC++/C#なコードを息抜きに書くので、まあ10日ぶりくらいのOpenCV。

まあそんなわけでOpenCVでSURFでもやろうと思った。こいつは物体を認識してくれるすごいやつだ。詳しくはググったほうが私の説明より良いだろう。

今回、SURFを用いて、「探される画像」と「探したい画像」を使い、探される画像のどこらあたりに探したい画像が存在するかを検出したかった。

当然だがテストとしても、実際に動かすにしても、「探したい画像」くらいはどこかにあるファイルとして入力した方が良い。

そのために使えるのがOpenCVのimreadだ。こいつはパスを入れるだけで画像を読み込んでくれる。非常にシンプルだ。

で、まあ、結論に書いたとおりである。こいつが動作しなかった。

ReleaseとDebugのモードに原因があると気付いたのは完全に勘で、試しに動かしたらどうやら挙動が変わったので詳しくググってみたらそのようである、というStackOverFlowの記事等があった。'

ほかのメソッド類はきちんと動くので、実際わけがわからないが、まあとにかく内部のことなら仕方がないだろう。変えられない理由もあるはずだ(ないなら即座に変えてくれ。頼むから)。

そういうわけで、C++のdllがReleaseでコンパイルされていくことになった。OpenCVをDebugで再ビルドするのは手間なので、問題が起きるまではひとまずこれで進めていく。

最後に、せっかくの日記なので私が最近食べたラーメンについて記しておこう。

私は現在静岡県浜松市に住んでいるのだが、ここのつけ麺屋が最近のお気に入りだ。

麺喰いカケル (kakeru) - 遠州曳馬/ラーメン [食べログ] - http://tabelog.com/shizuoka/A2202/A220201/22026427/

私のオススメはさらっとした中華スープのほう。もちろん濃厚スープも美味しいが。

2014年12月7日日曜日

パッチワーク地形生成


というわけでTwitterにこういったpostをした。

書ききれないところと、ソースコードの構成の解説をしたい。

ソースコードはgithubにアップロードしておいた。

https://github.com/TakafumiFukuyo/LookLikeTerrain/tree/master/ChildrenDraw

簡単に説明すると、ランダムウォークする4つの点(増加可能)が、既存の描画部分を上書きするか否かをランダムに決定しつつ、手持ちのペンの色(ランダム)とサイズ(固定)でキャンバス内を塗りつぶしていく。

キャンバスがすべて塗りつぶされたら終了である。

点は初期位置と最大到達可能距離、そして上書きするかどうかの毎ループごとの決定に使う値(powerと呼んでいる)を持っている。

1ループごとに、ランダムな角度と到達可能距離以内の範囲を極座標系でえらび、そこまでまっすぐに塗りつぶす(塗りつぶし可能であれば)。

ペンの情報は単純にintである。デバッグ用の描画関数がintをColorに変換してTexture2Dに入力している。

キャンバスの1単位分の情報が0のとき塗りつぶしていないと判定している。

単純にランダムにキャンバスを塗っていくだけなので、きまぐれな子供のような動きと思って名付けたのだが、これがなかなか面白い模様を作ってくれるように思える。

動かすまでまさかそんなうまく行くわけないと思っていたのだが。

このあとこのキャンバスの情報から塊の情報を得て、その塊に対して特定のアルゴリズムで地形を作る。

最後に地形の境界をなだらかにしてやれば、およそMinecraft風の「役割付けされた地形」のようなものができるように思える。

…ところでMinecraftの実際の地形生成はどうなっているのだろうか…。企業秘密というやつだろうか…。