2008年4月アーカイブ

安定化の次は、プログラムの高速化などをやってみようと思ってましたが、
高速化のためには、ARToolKitのソースをもっと理解していなければなりません。

そこで、次に「ARToolKitの解析」を行うことにしました。


解析のその1は、変換行列の計算アルゴリズムの解説をやってみます。
ここでいう変換行列とは、マーカー(オブジェクト)座標系から、グローバル(カメラ)座標系へ変換する行列のことです。

これは、ARToolKitの重要な仕組みの1つです。



---- < 変換行列計算の概要 > ----



BGM:エコテロニカ(sansuiさん)

 OpenGLなどの3DCGでは、3Dモデルの移動・回転などを行うために、座標系の変換行列を用います。
ARToolKitの場合も、この変換行列がないと、マーカー上にモデルを表示できません。

プログラムでは、スクリーン上に映ったマーカーの画像から、この変換行列を計算しています。
計算のプロセスは、大まかに以下のようになります。

1.マーカーの黒い四角形を認識する
2.四角形の枠である、4辺を計算する
3.それぞれの辺を、カメラの投影方向に伸ばし、面を作る
4.面の法線を計算
5.向かい合った面同士の法線から、外積を計算する
6.その外積同士から、さらに外積を計算
7.現在わかっている式を用いて、行列の残り値を計算する


今回は"スクリーン上の4角形の4辺"から、"変換行列の3×3の要素"を計算するとこまでを中心に、解説していきます。



---- < 1.マーカーの黒い四角形を認識 > ----

四角形の認識ではまず、カメラに映った画像を2値化(白黒に)します。
そして、その白黒画像から、4角形を探します。
さらに、見つけた4角形が登録されているマーカーかどうか調べます。

この部分の詳しいアルゴリズムについては、後日解説するつもりです。



---- < 2.四角形の枠である、4辺を計算する > ----

ここも、1と一緒に解説いたします。



---- < 3.それぞれの辺を、カメラの投影方向に伸ばし、面を作る > ----

4角形の辺が取得できたら、この辺を伸ばして、面にします。
伸ばし方は、辺がスクリーンへ投影された方向に伸ばします。

つまりこの面は、3次元空間上のマーカーの4辺も通ることになります。
カメラの視点、2Dのマーカーの辺、3Dのマーカーの辺を繋ぐ面です。



---- < 4.面の法線を計算 > ----

それぞれの面の法線(面に対して、垂直なベクトル)を計算します。



---- < 5.向かい合った面同士の法線から、外積を計算する > ----

法線が計算できたら、向かい合った面同士の法線から、外積を計算します。
外積は、2つの法線に対し垂直になります。

この外積は、マーカー座標系の1つの軸を表すベクトルになります。



---- < 6.その外積同士から、さらに外積を計算 > ----

さらに、外積同士の外積をとります。
この3つの外積が、それぞれマーカー座標系のX軸, Y軸, Z軸になります。

さらに値を補正すると、変換行列の3×3の要素になるわけです。



---- < 8.現在わかっている式を用いて、行列の残り値を計算する > ----

変換行列の3×3の要素は、回転や拡大縮小を表しています。
変換行列に必要な残りの要素は、平行移動です。

平行移動分を計算するには、それまでに用いられた行列等の式を使い、答えを出します。



以上が、僕が理解できた範囲でのアルゴリズムの説明です。
間違いや不足があった場合には、連絡をお願いします。


お待たせしました。ソースを公開いたします。
時間がかかってしまい、申し訳ありません。

また、作者も非常に経験不足ゆえ、ファイルのミス、プログラムの不具合、説明不足、コードが読みにくい、等々予期せぬ問題が発生するかと思われます。

そういった問題は、可能な限り改善していきたいと思いますので、
メールなどで、できるだけ詳細な連絡(動作環境、現象の発生手順等)をいただけると非常にありがたいです。

では、Ver1.0になります。

MultiRelate1.0.zip
こちらも、Readmeの詳細説明用に使用いたします。

プログラムの大まかな処理は、その①その②を見てもらっても大体はわかります。
今回は少しプログラム寄りな説明になります。

安定化プログラムでは以下のような処理を行っています
・設定ファイルを読み込む
・通常表示
・関係値の計算
・計算結果を表示する
・補完処理を加えた表示
・関係値の保存

このプログラムでは、関係値のデータと処理を行うクラス"CObjectMultiCreator"があり、
上記の処理のほとんどは、このクラスのメンバ関数内で行っています。



では、それぞれの処理を見てみます

・設定ファイルを読み込む : 関数 LoadMultiRelationInf
設定ファイルには、"複数オブジェクトファイルへのパス"と、"関係値の値"が保存されています。
初期状態では"関係値の値"は存在しません。
詳しくは、その④-EXEの使い方を参照してください。


・通常表示
通常表示では、従来のARToolKitとほぼ同様の処理を行っています。


・関係値の計算 : 関数 CalcAllMarkerRelate
キー操作により、編集モードに入ったときに、関係値の計算が行われます。
関数に入る前に、従来と同じ方法で、各マーカーの座標変換行列  "object.trans" が計算されます。

ここでマーカーA, Bが見つかったとします。
そのとき次のような計算を行います。

1.座標変換行列、"A→カメラ"と、"B→カメラ"、が分かっている。
2.1の"B→カメラ"を反転して、"カメラB"にする。
3.1と2から、"A→カメラB"という行列計算を行う。
4.3から"A → B"という座標変換行列を得る。

平均値計算用に、サンプル数と行列の合計値を、メンバ変数に蓄えておきます。

ある程度、サンプル数が溜まったら、上記と同じ方法で誤差を計算します。
これも、サンプル数と合計値の形で、持っておきます。


・計算結果を表示する
計算が大体終了したら、それを表示し、ユーザーに知らせます。
ユーザーはこの表示を見て、計算の頃合を計り、編集モードを終了します。

表示に使用される値は、マーカー関係情報の構造体"MARKER_RELATE_INFO"の、誤差の合計値"dError"や、サンプル数"lRelCount"を使用します。


・補完処理を加えた表示  : 関数 GetGLTransFromRelate
関係値が計算できても、マーカーを問題なく取得できた場合には、通常の描画を行います。
問題は、マーカー情報が正しく取得できなかった場合です。

例えば、マーカーAの情報が取得できず、マーカーBは取得できたとします。
その時は、以下のような計算になります。

1.座標変換行列 "A →B"と"B → カメラ" が分かっている
2.1より、" A → B → カメラ" という行列計算を行う
3.2の結果から、"A → カメラ" という座標系変換行列を得る

というような感じです。


・関係値の保存 : 関数 SaveMultiRelationInf
最後に関係値の保存を行います。
ファイルにデータとして保存してしまえば、時間使用時、又は他のプログラムでも再利用できます。
実行のたびに関係値を計算する手間を、省けるわけです。



更なる詳細については、プログラムを読んだり、デバック実行して、理解していただくか、
それでも分からない場合は、メールにてご連絡ください。
Readmeの詳細説明に必要なので、ソース公開前に書いておきます。
実行ファイルの使用方法です。


--- < とりあえず実行してみる > ---


0.GULTをインストール
 実行にはGLUTが必要です。

1.マーカーを印刷
 \patternsフォルダ内の、マーカーを印刷します。
 印刷できない場合は、ディスプレイにマーカーの画像を表示するだけでも、大丈夫です。

2.実行ファイルを起動
 \binフォルダ内の"MultiRelate1.0.exe"を実行します。
 設定ダイアログが出て、Webカメラから画像が表示されるはずです。

3.確認
 マーカー上に色のついた立方体が表示されるはずです。

4.編集モードにする
 キーボードの"E"キーを押して、編集モードにします。
 操作キーは、画像が映っているウィンドウを選択していないと、実行されません。

5.関係値のリセットを行う
 キーボードの"C"キーを押して、関係値をリセットします。

6.関係値を設定する
 できるだけ多くのマーカーが認識されるように、カメラを移動してください。
 そして表示が安定するまで、その場でカメラを動かさないようにしましょう。
 立方体の線が緑や黄色で安定したら、だいたい計算ができています。

7.全てのマーカーで、6の作業を行う
 6の作業を、全てのマーカーに対して行います。
 2つ以上のマーカーが認識されていないと意味がありません。

8.通常モードに戻す
 もう一度"E"キーを押して、通常モードに戻ります。

9.関係値の確認
 関係値が正しく計算できていれば、1つのマーカーの認識に失敗しても、他の成功したマーカーから補完されます。

10.保存する。
 "S"キーを押して、関係値の保存をします。
 プロンプト(文字しか表示されない、もう一つの黒い画面)に、保存ができたという旨の文章が表示されれば、完了です。
 再実行した時にも、保存された関係値を使用し、何度も計算する必要がなくなります。



--- < 使い方の詳細 > ---

○キー操作

・"E"キー:[編集モード]/[通常モード]への切り替えを行います。
・"C"キー:計算された関係値をリセットします。
・"S"キー:関係値を保存して、次回も使用できるようにします。
・"1~9"キー:1~9番の、マーカー上の3Dモデルの[表示]/[非表示]を切り替えます。
・"0"キー:全ての3Dモデルの[表示]/[非表示]を切り替えます。
・"R"キー:マーカー間の関係を表す線の[表示]/[非表示]を切り替えます。
・"M"キー:マーカー自体を表す、四角形の印の[表示]/[非表示]を切り替えます。
・"V"キー:現在表示されている3Dモデル間の関係値のみをリセットします。
・"T"キー:文字情報の[表示]/[非表示]を切り替えます。


○マーカー間の関係を表すファイル ”Data\MultiRelationInf.dat”
ファイルの内容は、概ね以下のようになっています。

#マーカーオブジェクトデータ
Data/multi/markerColor30_01_6.arobj

#マーカーの関係データがあるかどうか
1

#################################################################
#marker 1
#to 1
0
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000

#err
0
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
#Sum
-1.000000

#to 2
602
-601.079477 -6.103214 -29.765651 -224.731229
29.999639 -22.392234 -600.762449 -17661.005934
5.014032 -601.428488 22.542861 -21332.142015

#err
503
502.913258 -4.899541 2.086850 -469.029122
4.890394 502.880013 2.277454 -35.750323
-2.163808 -2.263550 502.959077 -328.080689
#Sum
4.299248

#to 3
    ・
    ・
    ・


最初に、複数のオブジェクトを記述したファイルのパスを書きます。
このファイルは既存のプロジェクト"loadMultiple"で使用されているのと、同じ形式なります。

自分で作ったマーカーを利用する場合には、この複数オブジェクトファイルの内容や、ここのパスを変更してください。

次に、マーカー間の関係値が事前に保存されているかを示すフラグが書かれています。
初期値は0になっていて、関係値を保存した後は1になります。
この値が0の場合は、後に関係値が続いていても読み込みません。

最後に、実際の関係値が書かれます。
ここに書かれる関係値は、
・全てのオブジェクトから全てのオブジェクトへの座標変換行列(サンプル数と合計値)
・その行列の誤差(サンプル数と合計値)
・誤差を合計した値
になります。見ての通り、非常に冗長です。

実際の関係は、各合計値をサンプル数で割った平均値が用いられます。
さて、いよいよソース公開の作業に入ります。
最初にGPLの詳細説明と、Readmeの作成についてです。

----------------------- < GPLの詳細 >
-----------------------

GPLについて、補足説明をさせていただきます。
自分がGPLについて、実際にどうソースを変更したかについてです。


○GPLの内容が書かれた文を配布ファイル内に入れる
ARToolKitにもともとあった"COPYING.txt"と、その日本語訳の文を、ファイルに付属しました。


○ファイルを変更した旨とその変更日とを、変更したファイル上に明確に表示すること。
これに関しては、従来のコメントの書き方で対応させていただきました。
ファイルの先頭のコメントで、以下のようなものを追加します。

/*******************************************************************************
 *
 * \file    object.h
 *
 * \brief    オブジェクトに関する情報と操作
 *
 * \date    08/02/02    PipeR    構造体にcf等の付加情報を追加しました
 *
*******************************************************************************/
又は、新規作成の場合は
/*******************************************************************************
 *
 * \file    MultiSetting01.c
 *
 * \brief    複数マーカー認識で用いる、
 * \brief    MultiMarkerInfoの設定ファイルを作成する
 *
 * \author    PipeR
 *
 * \date    08/02/02    PipeR    作成
 *
*******************************************************************************/
一番下の\dateで、「日付・名前・変更内容」を記述します。
コメントはDoxygen方式になっています。


○ソース内の著作権表示と無保証等の説明
追加したコメントは以下のような内容になります

/*******************************************************************************
 *
 *   Copyright (c) 2008 PipeR
 *
 *   The distribution policy is described in the file "COPYING.txt" furnished
 *    with this library.
 *
 *    本プログラムは、GNU 一般公有使用許諾に準拠します。
 *    利用も配布も商用利用も自由ですが、著作権は放棄しておりません。
 *    また、改変も自由ですが、GPLである以上、改変バージョンの配布を行う際には、
 *    ソースの公開は必須条件となりますので、ご注意下さい。
 *    GNU 一般公有使用許諾については、付属の"COPYING_JPN.txt"をご覧ください
 *
 *
 * 本プログラムはフリー・ソフトウェアです。あなたは、Free Software
 * Foundation が公表したGNU 一般公有使用許諾の「バージョン2」或い
 * はそれ以降の各バージョンの中からいずれかを選択し、そのバージョン
 * が定める条項に従って本プログラムを再頒布または変更することができ
 * ます。
 *
 * 本プログラムは有用とは思いますが、頒布にあたっては、市場性及び特
 * 定目的適合性についての暗黙の保証を含めて、いかなる保証も行ないま
 * せん。詳細についてはGNU 一般公有使用許諾書をお読みください。
 *
 * あなたは、本プログラムと一緒にGNU 一般公有使用許諾の写しを受け取っ
 * ているはずです。そうでない場合は、Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA * へ手紙を書いてください。
 *
 *    ----------------------------------------------------------------------
 *    * 【注意】 現在、このバージョン2の発行者(FSF)住所は、正式に新
 *     しい住所の 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
 *     USA に変わっている。
 *    ----------------------------------------------------------------------
 *
*******************************************************************************/
この内容は、GPLの日本語訳に従っています。


○実行ファイル内での、著作権・無保証等の表示
これも、GPLの日本語訳に従い、プログラム実行直後に以下のプログラムを実行

printf("ARToolKitの安定化プログラム Ver1.0 Copyright (c) 2008 PipeR\n");
printf("ARToolKitの安定化プログラム は完全に無保証です。詳細はOpenGLのウィンドウで\"G\"キーをタイプしてください。\n");
printf("これはフリー・ソフトウェアなので、特定の条件の下でこれを再頒布することができます。詳細は付属の\"COPYING.txt\"か\"COPYING_JPN.txt\"をご覧ください。\n");

もちろん、"G"キー押下時にも以下の文を加えます。

        printf("ARToolKitの安定化プログラム Ver1.0 Copyright (c) 2008 PipeR\n\n");
        printf("he distribution policy is described in the file \"COPYING.txt\" furnished with this library.\n\n");
        printf("本プログラムは、GNU 一般公有使用許諾に準拠します。利用も配布も商用利用も自由ですが、著作権は放棄しておりません。また、改変も自由ですが、GPLである以上、改変バージョンの配布を行う際には、ソースの公開は必須条件となりますので、ご注意下さい。GNU 一般公有使用許諾については、付属の\"COPYING_JPN.txt\"をご覧ください。\n\n");
        printf("本プログラムはフリー・ソフトウェアです。あなたは、Free Software Foundation が公表したGNU 一般公有使用許諾の「バージョン2」或いはそれ以降の各バージョンの中からいずれかを選択し、そのバージョンが定める条項に従って本プログラムを再頒布または変更することができます。\n\n");
        printf("本プログラムは有用とは思いますが、頒布にあたっては、市場性及び特定目的適合性についての暗黙の保証を含めて、いかなる保証も行ないません。詳細についてはGNU 一般公有使用許諾書をお読みください。\n\n");
        printf("あなたは、本プログラムと一緒にGNU 一般公有使用許諾の写しを受け取っているはずです。そうでない場合は、Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA * へ手紙を書いてください。\n\n");
        printf("* 【注意】 現在、このバージョン2の発行者(FSF)住所は、正式に新しい住所の 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA に変わっている。\n\n");




----------------------- < Readmeの作成 > -----------------------

次にReadmeの作成です。Readmeとはいわゆる「お読みください.txt」などの説明書のようなものです。

これには、Readmeファイルの作成支援ソフト「れ~どみ~えじた~」を使用しました。
これは、ウィザードと各種テンプレートを使い、Readmeを簡単に作成してくれるソフトです。


ここでは注意すべき点は少ないですね。

・[再配布]は「GPLに基づく」
・今回は、[必要ランタイム]に「GLUT」を入れました。
・現状では動作環境としてXP、開発環境はVC++ 2005しか試していないので、他の環境での動作、開発では不具合が出るかもしれません。

ぐらいでしょうか。



このアーカイブについて

このページには、2008年4月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2008年3月です。

次のアーカイブは2008年5月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.01a