Coding Memorandum

プログラミングに関する備忘録

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

OpenCVのSURF実装

画像認識などで使われる局所特徴量SURFの特徴量記述は次の式で定義される。(ここではdx, dyの詳細は説明しない)

これを4x4領域のピクセル毎に求めて結合した64次元のベクトルがSURFとなる。

OpenCV(2.0以降)の該当コードは次のようになっている。

/* Construct the descriptor */
vec = (float*)cvGetSeqElem( descriptors, k );
for( kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++ )
    vec[kk] = 0;
double square_mag = 0;

/* 64-bin descriptor */
for( i = 0; i < 4; i++ )
    for( j = 0; j < 4; j++ )
    {
        for( y = i*5; y < i*5+5; y++ )
        {
            for( x = j*5; x < j*5+5; x++ )
            {
                float tx = DX[y][x], ty = DY[y][x];
                vec[0] += tx; vec[1] += ty;
                vec[2] += (float)fabs(tx); vec[3] += (float)fabs(ty);
            }
        }
        for( kk = 0; kk < 4; kk++ )
            square_mag += vec[kk]*vec[kk];
        vec+=4;
    }
}

/* unit vector is essential for contrast invariance */
vec = (float*)cvGetSeqElem( descriptors, k );
double scale = 1./(sqrt(square_mag) + DBL_EPSILON);
for( kk = 0; kk < descriptor_size; kk++ )
    vec[kk] = (float)(vec[kk]*scale);

求めた特徴量を正規化する処理が入っている(28-30行)。SURFの元論文には正規化に関する記述は見受けられなかったので、OpenCV特有の処理であるようだ。

以前にSURFを実装したNTL MM1では、Bag of FeaturesでSURF特徴量をクラスタリングして用いているが、正規化を行うか否かでクラスタリング結果が変わってくるはずである。ちゃんと検証したわけではないが、直観的に正規化を行わない方がよい結果が得られそうだと思い、このときは論文に合わせて正規化を行わなかった。

ちなみにOpenCV 1.1では次の実装となっている。

vec = (float*)cvGetSeqElem( descriptors, k );
for( kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++ )
    vec[kk] = 0;

/* 64-bin descriptor */
for( i = 0; i < 4; i++ )
    for( j = 0; j < 4; j++ )
    {
        for( y = i*5; y < i*5+5; y++ )
        {
            for( x = j*5; x < j*5+5; x++ )
            {
                float tx = DX[y][x], ty = DY[y][x];
                vec[0] += tx; vec[1] += ty;
                vec[2] += (float)fabs(tx); vec[3] += (float)fabs(ty);
            }
        }
        double normalize = 0;
        for( kk = 0; kk < 4; kk++ )
            normalize += vec[kk]*vec[kk];
        normalize = 1./(sqrt(normalize) + DBL_EPSILON);
        for( kk = 0; kk < 4; kk++ )
            vec[kk] = (float)(vec[kk]*normalize);
        vec+=4;
    }
}

正規化をピクセル毎に行っており、OpenCV 2.xとは異なった計算式となっている(19-23行)。ピクセル毎に正規化を行うことは、SURFの特性から考えてもあまり良い結果になりそうになく、事実OpenCV 2.0で修正されている。

本来SURFの計算では正規化の必要はなかったが、OpenCVの何らかの都合で正規化の処理が行われているのではないかと思う。OpenCV 1.1の方法は良くなかったんで、2.0から直しておきましたみたいな感じかなぁ。

スポンサーサイト

Ubuntu 14.04 インストール失敗記

今日は、一日かけてUbuntuのインストールを試みたがあえなく失敗。とりあえずメモとして纏めておくこととする。

【やりたかったこと】

  • Windows8.1とUbuntu14.04のデュアルブート
  • Windows8.1はインストール済みでUEFIブートの構成である
  • HDDは1台で空き領域あり

【(自分の中の)結論】

  • HDD1台構成でUEFIのデュアルブートは無理

もう少し勘所を押さえれば簡単にできることなのかもしれませんが、現時点ではギブアップし増設HDDを調達することにしました。

下記参考にした情報源をまとめます。
今回の目的そのものずばりのサイト「デュアルブート(UEFI Win8.1 + Ubuntu14.04)その1」。 ここに書かれている通りで上手く行くと思いきや、私の環境ではブートマネージャGRUBが起動せず、Windowsが起動してしまいました。

それからUbuntuのフォーラム「UEFIでのデュアルブートについて」。他のサイトでも見かけたが、インストールCD/DVD、USBはUEFIモードでブートする必要があるとのこと。
しかしながら、私の使っているマザーボートH87-PROでは、 DVD、USBメモリのUEFIブートがどのようにやってもできなかった。この点が一番の問題であったようにも思う。

Ubuntuには「Boot-Repair」なるブートマネージャを修復してくれるツールがあるとのこと。Live DVDで起動しBoot-Repairで修復を試みた。処理途中に出るメッセージでは、UEFI環境であることを認識し、GRUBの再インストールをするとのことで、非常に期待が持てた。しかしながら残念なことに、このツールを持ってしてもGRUBが起動することなく、Windowsが起動してしまうという状況であった。

Haswell PC

HaswellでPCを組みました。今回使ったパーツは次の通り(かなり無難な構成です)。

マザーボード ASUS H87-PRO OCしないのでチップセットはH87で十分。
メジャーなメーカーを選択。
CPU Core i7 4770 OCしないので無印
メモリ Kingston 8GB (4GB×2) DDR3-1600 評判の良いメーカー
HDD WD Red 2.0TB 信頼性重視
電源 玄人志向 KRPW-GP650W/90+ 評判の良い電源。C6/C7ステートサポート。必要なケーブルのみ挿して使えるのでケース内がすっきりする。
ケース ANTEC NINEHUNDREDTWO-V3 冷えるケースを選択。天板に18cmファンが付く。
グラフィックボード 玄人志向 GeForce GTX660 GTX660で一番安いもの

DVDドライブ、キーボード、マウスは旧PCの流用です。同じようなPCを組む方の参考になれば。今のところ、問題なく稼働しています。OSはWindows8 64bitです。

今回は全部Amazonで揃えました。ここのところの暑さで秋葉原まで行く気力が出ませんでした…。

夏休み2013

今年の年明けからこの8月まで、とんでもない忙しさが続きまして、すっかりとプログラム系の活動が止まってしまいました。去年は絶望的なスケジュールの3ヶ月で大ダメージを受けましたが、今年はロングランの多忙さでダメージが蓄積しています。

仕事は一旦山を越え、次は9月にもう一山あるという状況で、束の間の谷間で気力の回復に努めています。夏休みの予定として、8/10からのICFPCに参加するつもりで事前登録まで済ませていたのですけど、残念ながら仕事のトラブルで流れてしまいました。

夏休みの残りの目標は、Haswell PCを組むことと、CVのアップデート記事を書くこと、この2点はやりたい。時間があれば、Haswellで遊びます。

問題だらけの問題解決

問題のない問題との付き合い方」のスピンオフ記事です。こちらでは,実社会での問題解決について書いてみたいと思います。

問題解決とは

「問題解決のシーンにおいて,学生と社会人の一番の違いはなんでしょうか?」

これはある研修で問われた質問です。そのときの答えは次のようであったと記憶しています。「学生は与えられた問題を解くことができる。一方,社会人は問題を発見することもできる」。

社会人としての問題解決とは「問題を発見することから始まり,またそれが大事な部分でもある」という話。

この話は学生が劣っているということではなくて,「今までの試験問題を解くことが全ての価値であったという価値観から,これからは問題を自分で見つけることに価値があるという価値観へ変えていこう」ということを示しています。

それでは,この「問題を発見する力」を得るためにはどうすれば良いでしょうか?それには,まず「問題とは何か?」を考えることから始めます。

問題とは何か?

「問題とは何か?」。この問いは答えることが意外と難しいかと思います。

ここでは(割と?)有名な「問題のモデル」を紹介したいと思います。問題とは『「望まれた事柄」と「認識された事柄」の差(Gap)である』と定義されます。

Gap=問題であり,Gapがなくなれば問題解決となります。

この定義は色々な本で見かけることがあるのですが,私の一押しの参考書として「ライト、ついてますか―問題発見の人間学 」を挙げておきます。機知にとんだ例え話で進行し,さらっと読めてしまいます。

この「問題の定義」はシンプルながら,かなり強力です。身の回りの問題をこの定義で捉えなおしてみると面白いかと思います。ほとんどの問題はこの定義でモデル化できます。またモデル化した後には,問題の新たな側面が見えてくるのではないでしょうか。漠然としていた問題ははっきりと定義付けされ,これによって解決方法にも色々なアイデアを思いつくことができるかもしれません。

さあ,これで問題を発見する方法は分かりました!「望まれたコト」と「認識されているコト」を見つければいいのです。これであなたも問題発見のプロフェッショナル!

しかしながら,問題発見にはそれを難しくする難敵が待っているのでした。

望まれたコトとは何か?

「望まれたコト」とは何でしょうか?

問題定義の中の「認識されたコト」は誰にでも見つけられます。「認識されたコト」ですので当事者に聞けば簡単に分かります。一方,「望まれたコト」は自明なこともありますが,簡単には見つけられないこともあります。当事者ですら「どうしたいか」がはっきりしないことは良くある事ではないでしょうか。

仕事としての問題解決の場面では,「望まれたコト」を個人の思いだけで勝手に決めるわけにはいかないというケースもあるでしょう。裏付けを取ったりするなどの検証が求められます。その事柄に多くのステークホルダーが絡んでくると途端に検証の難易度が上がってしまうこともあります。

このように問題によっては「望まれたコト」を見つけることが困難であることがあります。しかしながら,これをおざなりにすると問題解決自体が台無しになってしまいます。

頑張って問題を解決し,現状を望まれた状態にすることができました。しかし,今の状態は私が本当に望んでいたコトではありませんでした。

悲劇的な話ですね・・・。問題発見のプロは「望まれたコト」を如何に上手く見つけてあげられるかが求められることとなります。

問題を解きたい病

問題発見を阻害する要因には次のこともあります。

冒頭に学生の話を書きましたが,大抵の日本人は学校教育で問題を解くことを鍛えられてきます。このため,問題を解決する能力(Gapを埋めるスキル)は非常に長けています(と言われています)。ひとたび問題が与えられれば,どんどんと解いて行ってしまう。

この問題解決能力が「望まれたコト」の発見を阻害してしまうことがあるのです。

問題解決が得意な人は問題を見るとすぐに解きたい衝動にかられます。このため問題の検討の途中でも,何か問題らしきものが見えてしまったら飛びつかずにはいられない。解くためのアイデアに意識が行ってしまい,議論もアイデアの検討へと移らせてしまいます。まだ,本当の「望まれたコト」が分かっていないにも関わらず。

手段の検討は楽しいので,一度そちらへ流れるともう止まりません。「手段のためなら目的も選ばず」の言葉のように,そのアイデアで解決できることが「望まれたコト」であったと本末転倒な状態になります。

このパターンでさらに悪いことは,間違った問題定義であっても問題を解決したところで解決したことの充実感で満足してしまうこと。まだ本当の問題を解決できていないにも関わらず,問題の検討を止めてしまうのです。

あなたの周りにも,やたらと手段の話をしたがる人はいないでしょうか?

問題を解く際には,『その「望まれたコト」は本当に正しいコトか?』を自問することでこの悲劇は多少なりとも減らせるのではないかと思います。

発展的話題

『「望まれたコト」を見つける』ということを『進むべき目標を決める』ということにすると,戦略策定のような問題になります。目標に対して現状(=認識されたコト)を分析して ,どうやれば目標に辿りつけるか(=Gapをなくす)を検討するというようにモデルにあてはまります。

この問題領域での最近流行りの(本屋で平積みされている)方法論に「仮説思考」があります。複雑な問題状況下では,「望まれたコト」なんていくら机上で考えても見つからない。それなら,(妥当な)仮説を立ててやってみたら何か分かるのではないかという考え方です。

上述の悲劇的なストーリーの最後には「本当に望んでいたコトではありませんでした」とあります。これは,逆に言えば「本当に望んでいたコトが分かった」ということが言えそうです。もしくは,少なくとも一つの望んでいないコトが消せたので,望んでいるコトをより絞りこみやすくなったと言えます。

「望まれたコト」を見つけることが本当に難しい問題では,必ずしも「望まれたコト」を完璧にすることなく柔軟に問題を解くこともあると心に留めておくと良いと思います。問題を解くことは手段であり,目的のためなら適切に手段を使っていくことが大事です。

終わりに

「問題」のモデルを導入し,問題解決での考慮点などをまとめてみました。問題は日々やってきます。今これを読んでいるあなたに「今,(少しでも)不快に思うことはなんですか?」と聞いた瞬間に,あなたは問題を抱えることになるのです。

本記事が,あなたをよりよい問題解決者にするきっかけになればと思います。

最後に「ライト、ついてますか―問題発見の人間学」は超おすすめです。大事なことなので2回 (ry

次のページ

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。