<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Pipe Render</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/" />
    <link rel="self" type="application/atom+xml" href="http://render.s73.xrea.com/pipe_render/atom.xml" />
    <id>tag:render.s73.xrea.com,2008-02-13:/pipe_render//1</id>
    <updated>2008-11-05T10:22:34Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Publishing Platform 4.01a</generator>

<entry>
    <title>ARToolKitの物体認識 その⑤ 指認識プログラムの公開</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/11/artoolkit-18.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.752</id>

    <published>2008-11-05T10:06:57Z</published>
    <updated>2008-11-05T10:22:34Z</updated>

    <summary>パブリックドメインソースを公開したので、次にプログラムをまとめたものを公開します...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="プログラミング" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの物体認識" label="ARToolKitの物体認識" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitソースの公開" label="ARToolKitソースの公開" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[パブリックドメインソースを公開したので、次にプログラムをまとめたものを公開します。<br /><br /><span class="mt-enclosure mt-enclosure-file"><a href="http://render.s73.xrea.com/pipe_render/program/artoolkit/FingerDetect1.0.zip">FingerDetect1.0.zip</a></span><br /><br /><br /><b>-- &lt; プログラムの使い方 &gt; ---<br /></b><br />０．Webカメラが２つあることが最低条件です。<br />ちなみに僕のは"Qcam Pro for Notebooks"。他のカメラでは試していないので、動くかどうかはわからないです。<br />あと、２つのカメラの設定を同じにしてください。<br />１．２つのカメラの向きを平行にして、まっすぐに並べる。<br />２．緑色のキャップのようなもの（作者は風船を使用）を用意し、それを親指に付けます。<br />３．TwoViewに関する説明(http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview.html)を読み、"WDM_camera_flipV_01.xml"、"WDM_camera_flipV_02.xml"を作成し、Dataフォルダに入れる。<br />４．マーカーと手を表示し、マーカーと指の距離が表示されることを確認します。<br />５．親指と人差し指を近づけて、カーソルがクリック状態になるかどうか（２つの指の間の線が赤くなる）を確認します。<br />６．マーカー上の立方体に指近づけて、クリック状態にします。<br />７．クリック状態で指を移動すると、立方体も移動します。<br />８．立方体の移動中にクリックを解除すると、立方体の移動が止まります。<b><br /><br /><br /></b><br /> <b>--- &lt; ソースの概要 &gt; ---</b><br /><br />今回のプログラムでは、いくつかのクラスを追加しました。<br />・CHandContourクラス：手の輪郭線を扱います。指の認識などを行えます。<br />・CPointActionクラス：複数の点を用いたカーソルアクションを行います。<br /><br />こちらについては、近いうちにドキュメントを公開する予定です。<br /><br /><br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの物体認識 その④ パブリックドメインソースの公開</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/11/artoolkit-17.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.748</id>

    <published>2008-11-03T11:35:25Z</published>
    <updated>2008-11-05T10:14:54Z</updated>

    <summary>ソースの公開ですが、まず最初に新規に作成した指認識のソースだけ公開いたします。こ...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="プログラミング" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの物体認識" label="ARToolKitの物体認識" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitソースの公開" label="ARToolKitソースの公開" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[ソースの公開ですが、まず最初に新規に作成した指認識のソースだけ公開いたします。<br />これは一応ライセンス上の体裁を整えるためだけの行為なので、この後にまとめたソースをちゃんと公開いたします。<br /><br />というのも、このソースについてはGPLライセンスではなく、パブリックドメインになっています。<br />なので、この部分だけ分離し、先に公開しました。<br /><br />（実際にはここまで厳密にやらなくてもいいと思いますが。<br /><br /><br />指認識部分のソース：<br /><a href="http://render.s73.xrea.com/pipe_render/program/artoolkit/CHandContour1.0.zip">CHandContour1.0.zip </a><br /><br /><br /><br />パブリックドメインソフトウェア<b>（PDS）</b>については以下のよう説明されています。<br /><a href="http://ja.wikipedia.org/wiki/%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2">Wikipedeia:パブリックドメインソフトウェア</a><br /><br />ここで、日本では著作人格権を放棄できないので、以下のようにしなくてはいけないと書かれています。<br /><br /><blockquote>...「将来にわたって著作権（及び著作者人格権）を主張しないことを宣言する」などと明記することによって、<b>事実上の PDS</b> として扱われる...<br /><br /></blockquote>これによりこの部分のソースについては、利用者は著作権による制限なしにソフトウェアを利用することができます。GPLのような「ソース公開の義務」も発生いたしません。<br /><br /><br />それから今回、コメントを<a href="http://www.doxygen.jp/">doxygenの形式</a>に対応いたしました。近いうちにドキュメントを作成し、公開する予定です。<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの物体認識 その③ 指認識によるポインティング</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/10/artoolkit-16.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.733</id>

    <published>2008-10-13T08:18:07Z</published>
    <updated>2008-10-13T11:28:01Z</updated>

    <summary>指が認識できたら、これをポインティングデバイスとして利用します。これで、普段僕ら...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="プログラミング" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの物体認識" label="ARToolKitの物体認識" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[指が認識できたら、これをポインティングデバイスとして利用します。<div><br /><div>これで、普段僕らがやっている「手で掴む・離す」という作業をそのままＵＩとして利用できるので、より自然な操作が可能になるはずです。</div><div><br />

<script type="text/javascript" src="http://www.zoome.jp/swfwrite?param=de3d1686fffdf7f1d95510227ae5ae3c72836cd15f5624836223656ca048827938552f5118ebcade022d0d02b18e2a29e6a7826e3c&amp;width=360&amp;height=288"></script>

</div><div><br /></div><div><br /></div><div><br /></div><div>--- &lt; 概要 > ---</div><div><br /></div><div>今回、「つまむ」という動作を検出するために、以下の２つが必要になりました。</div><div><br /></div><div>・親指の判断</div><div>・指がくっついた状態でも手の領域が重ならないようにする</div><div><br /></div><div>この問題を解決するために、親指に緑色のキャップを装着しました。</div><div><br /></div><div>これで、指先に緑の領域がある場合は親指であると判定でき、さらに指がくっついた状態でも、キャップの緑が邪魔をして肌色領域が混ざるのを防ぐことができました。</div><div><br /></div><div>ここで指がくっついた状態では、親指じゃない方の指が親指だと判定される現象が発生しましたが、そのときの２つの指の座標はほぼ同じになるので、あまり問題ありませんでした。</div><div><br /></div><div><br /></div><div><br /></div><div>ポインティングのために行った処理を説明します。</div><div><br /></div><div>１．指を認識する</div><div>２．親指を探す</div><div>３．親指と他の指との距離を測る</div><div>４．距離がある程度近い場合はドラッグ開始</div><div>５．ドラッグ中に距離が離れたら、ドラッグ終了</div><div><br /></div><div>それぞれの詳細は以下の通りです。</div><div><br /></div><div><br /></div><div><br /></div><div><div>--- &lt; １．指を認識する > ---</div><div><br /></div><div>指の認識は、<a href="http://render.s73.xrea.com/pipe_render/2008/07/artoolkit-15.html">前回の処理</a>とほぼ同様です。</div><div>今回追加した処理では、左右のカメラで指を一致させるために、指のマッチングを行いました。</div><div><br /></div><div>左右画像での指のマッチングは単純で、基準の位置座標を各指を元に変えながら、その他の指の距離を測定し、最も近いものを探しているだけです。</div><div><br /></div><div>マッチングで指先だけでなく、指の付け根も比較対象に加えることで、マッチングの精度が上がりました。さらに指認識の精度も上がります。</div><div><br /></div><div>

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/finger_match01.jpg" alt="finger_match01.jpg" />


<br /></div><div><br /></div><div><br /></div><div><br /></div><div>--- &lt; ２．親指を探す > ---</div><div><br /></div><div>親指には緑のキャップがあるはずなので、各指先でその緑を探します。</div><div>そして、最も緑の領域が多い指を親指であるとします。</div><div><br /></div>

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/find_thumb_01.jpg" alt="find_thumb_01.jpg" />

</div><div><br /></div><div>また、親指のマッチングも行います。</div><div><br /></div><div><img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/match_thumb_01.jpg" alt="match_thumb_01.jpg" />

<div><br /></div><div><br /></div><div><br /></div><div>--- &lt; ３．親指と他の指との距離を測る > ---</div><div><br /></div><div>左右の画像で一致した指の座標が取得できたので、前回と同様三角測量で指の３次元座標を計算します。</div><div><br /></div><div>全ての指の３次元座標が分かったら、親指とその他の指との距離を計算します。そして、距離が最も近い指を探します。</div><div><br /></div><div><br /></div><div><br /></div><div>--- &lt; ４．距離がある程度近い場合はドラッグ開始 > ---</div><div><br /></div><div>近い指までの距離が分かったら、その距離がある値より小さいかどうか調べます。そして、小さいときに「つまんでいる状態」のフラグを立てます。</div><div><br /></div><div>「つまんでいる状態」で立方体との衝突判定を行い、</div><div>衝突していたら、ドラックを開始します。</div><div><br /></div><div>ドラッグ中は立方体が指に追従して移動します。</div><div><br /></div><div><br /></div><div><br /></div><div>--- &lt; ５．ドラッグ中に距離が離れたら、ドラッグ終了 > ---</div><div><br /></div><div>親指と近傍の指との距離が一定値より離れた場合、</div><div>「つまんでいる状態」フラグを下げます。</div><div><br /></div><div>ドラッグ中に「つまんでいる状態」フラグが下がったら、ドラッグを中止します。これでドロップができます。</div><div><br /></div><div>最後のドラッグ＆ドロップは、<a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-4.html">前回の色認識ポインティング</a>と同様です。</div><div><br /></div><div><br /></div></div></div>]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの物体認識 その② 指認識</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/07/artoolkit-15.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.713</id>

    <published>2008-07-18T11:55:14Z</published>
    <updated>2008-07-18T13:27:25Z</updated>

    <summary>最近はARToolKitのプログラムも少しできてきたので、次は手とかをそのまま認...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの物体認識" label="ARToolKitの物体認識" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[最近はARToolKitのプログラムも少しできてきたので、<br />次は手とかをそのまま認識させたいと思っていました。<br /><br />そしたらちょうど<a href="http://masafumi.cocolog-nifty.com/masafumis_diary/">masafumiさんという方のブログ</a>で<a href="http://masafumi.cocolog-nifty.com/masafumis_diary/2008/07/ar_c4da.html">手認識を使ったAR</a>という記事を見つけました。<br />この方法は認識精度が高そうなので、twoViewでの物体認識にも使えそうです。<br /><br /><br /><a href="http://ilab.cs.ucsb.edu/projects/taehee/HandyAR/HandyAR.html">この手認識ARの研究</a>は、手を認識することによってマーカーの代わりにしようというものです。<br />ソースも公開されているので、すぐにこのプログラムを使った動画がアップされています。<br /><br />

<iframe src="http://ext.nicovideo.jp/thumb/sm3857083" style="border: 1px solid rgb(204, 204, 204);" scrolling="no" width="312" frameborder="0" height="176">&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a
href="http://www.nicovideo.jp/watch/sm3857083"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;【ニコニコ動
画】HandyARで初音ミクが手のひらの上でｳｯｰｳｯｰｳﾏｳﾏ(ﾟ
∀ﾟ)&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;</iframe>

<br /><br />見ての通り、指認識の精度は非常に高いです。<br /><br />というわけで今回は、この指認識のアルゴリズムだけをいただき、<br />この情報を元にtweVIewから指の３次元座標を計算してみました。<br /><br />これで綿棒や色の付いた目印を使う必要がなくなります。<br /><br /><br />

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/disttrans01.jpg" alt="disttrans01.jpg" width="240" height="200" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/labeling01.jpg" alt="labeling01.jpg" width="240" height="200" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/finger02.jpg" alt="finger02.jpg" width="240" height="200" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/finger3d01.jpg" alt="finger3d01.jpg" width="240" height="200" />&nbsp; 

<br /><br /><b><br /><br />--- &lt; 指認識の概要 &gt; ---</b><br /><br />指認識では、おおまかに以下のような処理を行っています。<br /><br /><b>１．手の色に近い領域を探し、輪郭線で分ける<br />２．距離変換画像を作成する<br />３．輪郭線を使ったラベリング<br />４．手の輪郭のカーブ具合を調べる<br />５．カーブ具合から指の判定<br /></b><br />僕が感動したのは、手の輪郭線から指を判定する処理です。<br /><br /><br /><br /><b>--- &lt; </b><b>１．手の色に近い領域を探し、輪郭線で分ける</b><b> &gt; ---</b><br /><br />やはり最初は手の色を判定し、それを元に２値画像を作成します。<br /><br />元のプログラムではここでRGBを<a href="http://en.wikipedia.org/wiki/YCbCr">YCrCbという色空間</a>に変換し、<br />ヒストグラムなどを使って肌色を判定していました。<br /><br />ですが、僕のプログラムでは<a href="http://render.s73.xrea.com/pipe_render/2008/06/artoolkit-hsv.html">前回のHSV色空間</a>を使用しました。<br /><br />そしてさらに、この肌色の２値画像から輪郭線情報を作成します。<br />輪郭線はOpenCVの<span class="entry-content">cvFindContoursを使用して作成します。</span><br /><br /><br /><br /><b>--- &lt; </b><b>２．距離変換画像を作成する</b><b> &gt; ---</b><br /><br />次に、２値化画像から<a href="http://opencv.jp/sample/special_transforms.html#disttrans">距離変換画像</a>を作成します。<br />距離変換とは、値のある現在の点から値のない点への最短距離を求める計算です。<br /><br />この最短距離を画像に書き込むと、上の<a href="http://render.s73.xrea.com/pipe_render/image/artoolkit/disttrans01.jpg">１つめの画像</a>のようになります。<br />この距離変換によって、肌色に近い領域で一番大きなものが大体分かります。<br /><br />今回は、「その一番大きな領域が手である」という判定をしています。<br /><br /><br /><br /><b>--- &lt; </b><b>３．輪郭線を使ったラベリング</b><b> &gt; ---</b><br /><br />この手の領域を判別するために、輪郭線を使用します。<br /><br />１．まっさらな画像を用意<br />２．画像に対し、各輪郭ごとに内部を塗りつぶしていく<br />３．塗りつぶすたびに、「距離変換の値が最大となる座標」が塗り潰されたかどうか判定する。<br />４．もし塗りつぶされいれば、その輪郭が「求める手の領域」のものになる。<br /><br />この処理によってラベリングを行わずに、最大面積の領域を判定できてしまいます。<br />ラベリング処理は重いものが多いので、これはとても便利です。<br /><br />結果的に上の<a href="http://render.s73.xrea.com/pipe_render/image/artoolkit/labeling01.jpg">２つ目の画像</a>のようなものができあがります。<br /><br /><br /><br /><b>--- &lt; </b><b>４．手の輪郭のカーブ具合を調べる</b><b> &gt; ---</b><br /><br />手の輪郭を取得できたので、次にこれを用いて指を判定します。<br />指判定には、各輪郭点の狭い範囲で内積と外積を計算します。<br /><br />１．輪郭線上の全ての点を調べる<br />２．各点の狭い範囲で、先の輪郭点へのベクトルと、後の輪郭点へのベクトルを取得する。<br />３．２つのベクトルの内積を計算し、それがある程度大きければ、その点はカーブしていると判定<br />４．２つのベクトルの外積を計算し、そのカーブの方向を判定<br />５．調べる範囲を変えて、２～４の処理を繰り貸す。<br />６．求める値になったら、そのカーブが指に似た曲がり具合であると判断する。<br /><br />この処理で、上の<a href="http://render.s73.xrea.com/pipe_render/image/artoolkit/finger02.jpg">３つ目の画像</a>ができあがります。<br /><br /><br /><br /><b>--- &lt; </b><b>５．カーブ具合から指の判定</b><b> &gt; ---</b><br /><br />上記の処理で指っぽいカーブは分かりましたが、これが本当に指かどうかはまだ分かりません。<br />また、場合によってはその指がどの指なのかも判定が必要です。<br /><br />ですが、今回のプログラムではその処理を入れていません。<br />ここでは最後に、前回同様ステレオでこの２次元座標を３次元に変換して終わりです。<br /><br />これで上の<a href="http://render.s73.xrea.com/pipe_render/image/artoolkit/finger3d01.jpg">最後の画像</a>のようになります。<br /><br /><br />元の研究では、事前に指の理想的な位置を取得しておいて、<br />それと比較することで各指を認識したりしているようです。<br /><br />僕のプログラムも指っぽい形状の認識の精度は高くなりましたが、<br />その後の指判定はまだできていません。<br /><br /><br />ソースの清書も含め、その辺が今後の課題となります。<br /><br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの物体認識 その① HSV色空間での色認識</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/06/artoolkit-hsv.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.712</id>

    <published>2008-06-29T09:38:56Z</published>
    <updated>2008-06-29T11:00:47Z</updated>

    <summary>新しいプログラムは「物体認識」とか凄そうな名前を付けましたが、基本的にはtwoV...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの物体認識" label="ARToolKitの物体認識" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[新しいプログラムは「物体認識」とか凄そうな名前を付けましたが、<br />基本的にはtwoViewを使ったプログラムの延長です。<br /><br />今回は、前回のプログラムの色認識を改良しました。<br />少しずつ純粋なARToolKitから離れてきています。<br /><br /><br /><b>--- &lt; HSV色空間について &gt; ---</b><br /><br />HSVなんて聞きなれない単語ですが、簡単に言うとRGBの親戚みたいなものです。<br /><br />知っての通り、RGBは「赤・緑・青」の色を組み合わせて多くの色を表現しますが、<br />HSVでは代わりに「色相・彩度・明度」という属性を組み合わせることで色を作ります。<br /><br />詳しくは、<a href="http://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93">Wikiを参照</a>してください。<br /><br /><br />なぜRGBじゃなくてHSVを使うのかというと、こっちの方が特定の色を見つけやすいからです。<br /><br />Wikiを見てもらえば分かるように、HSVでは赤とか青とかの情報は色相を見れば大体分かります。<br />残りの彩度や明度は、言ってみれば明るさや暗さみたいなもので、ほとんど無視していいものです。<br /><br />逆に言えば「明るい赤」も「暗い赤」も、同じ赤として認識してくれることになります。<br />実際には、物体の「影の部分」や「光が反射している部分」まで認識してくれる可能性がある、<br />ということです。<br /><br /><br /><br /><b>--- &lt; 実行結果 &gt; ---</b><br /><br />今回は、このHSV色空間で画像を扱うために、OpenCVというフリーの画像処理ライブラリを使用しました。<br />また指定色の物体は綿棒ではなく、色風船の端を切って指にはめてみました。<br /><br />
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/LabelRect01.jpg" alt="LabelRect01.jpg" width="240" height="200" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/Labeling01.gif" alt="Labeling01.gif" width="240" height="200" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/pointing01.jpg" alt="pointing01.jpg" width="240" height="200" />&nbsp;&nbsp;

<br /><br />HSV色系を用いる以外の処理は、今までと一緒です。<br />とりあえずはうまくいっているようです。<br /><br /><br />しかし、欠点もあります。<br />HSV色系はそのままだと感度が良すぎて、余計なものまで認識してしまいます。<br /><br />上の画像では、閾値を狭くしたので指の先を正しく認識できていません。<br />そこで、閾値を広くすると下の画像のようになります。<br /><br />
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/LabelRect02.jpg" alt="LabelRect02.jpg" width="240" height="200" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/Labeling02.gif" alt="Labeling02.gif" width="240" height="200" /> <br /><br />閾値が広いと指の部分を正しく取得できますが、同時に関係ない部分まで誤認してしまっています。<br /><br />このような結果にならないように、「彩度・明度」も考量しなくてはならず、<br />「色相」の閾値も、そのつど微調整が必要です。<br /><br />またこれまで以上に、撮影環境に気を使わなくてはいけないかもしれません。<br /><br /><br />この辺は今後の課題です。<br /><br />&nbsp;
<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのtwoView　その⑤　ステレオのソースの公開</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/06/artoolkittwoview-5.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.711</id>

    <published>2008-06-17T10:20:00Z</published>
    <updated>2008-06-17T23:33:56Z</updated>

    <summary>お待たせしました。twoViewを使った、ステレオマッチングプログラムのソース公...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitのtwoview" label="ARToolKitのtwoView" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitソースの公開" label="ARToolKitソースの公開" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[お待たせしました。<br />twoViewを使った、ステレオマッチングプログラムのソース公開です。<br /><br /><a href="http://render.s73.xrea.com/pipe_render/program/artoolkit/StereoAnyColor1.0.zip">StereoAnyColor1.0.zip</a><br /><b><br /><br />--- &lt; プログラムの使い方 &gt; ---</b><br /><br />０．Webカメラが２つあることが最低条件です。<br />ちなみに僕のは"<span class="lh12">Qcam Pro for Notebooks"</span>。他のカメラでは試していないので、動くかどうかはわからないです。<br />あと、２つのカメラの設定を同じにしてください。<br />１．２つのカメラの向きを平行にして、まっすぐに並べる。<br />２．赤・黄・青など特徴的な色の物体を用意し、場所は白いテーブルの上など選んだ色が他にはないような所にする。<br />３．<a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview.html">TwoViewに関する説明</a>を読み、"WDM_camera_flipV_01.xml"、"WDM_camera_flipV_02.xml"を作成。<br />４．プログラムを起動して"Video Source 1"ウィンドウで、用意した特長的な色の物体を画面に表示して、それを左クリックします。<br />５．物体が画面に映っている状態で、Fキーを押してラベリング画像を表示。<br />６．Kキーを押して続けて閾値を下げ、目的の物体が一番大きくラベリングされるようにします。<br />７．押しすぎて全くラベリングされなくなったら、Jキーを押して閾値を上げます。<br />８．もう１つの物体を認識させたいときは、右クリックで画面上の物体の色を指定します。<br />９．２つの物体が一番大きくラベリングされるようになったらOKです、Fキーを押して元の画面に戻ります。<br />１０．マーカーを表示し、マーカーと２つの物体の距離が表示されることを確認します。<br />１１．２つの物体の距離を近づけて、カーソルがクリック状態になるかどうか（２つの物体間の線が赤くなる）を確認します。<br />１２．マーカー上の立方体にカーソルを重ねて、クリック状態にします。<br />１３．クリック状態でカーソルを移動すると、立方体も移動します。<br />１４．立方体の移動中にクリックを解除すると、立方体の移動が止まります。<br /><br />以上です。<br />まだ色の識別が甘いので、上手く認識しないかもしれません。<br />今後の課題です。<br /><br /><br /> <b>--- &lt; ソースの概要 &gt; ---</b><br /><br />今回のプログラムでは、いくつかのクラスを追加しました。<br /><b>・CCamerasRelationクラス：カメラ間の関係<br />・CStereoAnyColorPointクラス：指定色のステレオ処理を行う<br />・CFindColorPosInImgクラス：画像認識を行い、指定色のスクリーン上の座標等を計算<br />・CCamSimpleTriangulationクラス：３角測量を行う<br /></b><br />以上のクラスは次のように使います。<br /><b>１．インスタンスの定義<br />２．クラスの初期化<br />３．画像認識の計算<br />４．結果の取得<br /></b><br /><br /><b>--- &lt; </b><b>１．インスタンスの定義</b><b> &gt; ---</b><br /><br />改良したtwoView.cでは、以下のようにクラスのインスタンスを作成します。<br /><blockquote><b>CCamerasRelation&nbsp;&nbsp;&nbsp; gCamRelate(CONTEXTSACTIVECOUNT);</b><br /><b>CStereoAnyColorPoint g_stereoOperator;</b><br /></blockquote>今回はグローバル変数で定義しました。<br /><br /><b><br />--- &lt; </b><b>２．クラスの初期化</b><b> &gt; ---</b><br />
<br />
次に、この変数を初期化します。<br /><blockquote>// グローバル変数の初期化<br />static void InitGlobalValue()<br />{<br />&nbsp;&nbsp;&nbsp; // 画像認識の色を指定<br />&nbsp;&nbsp;&nbsp; <b>g_stereoOperator.ClearTargetColor();</b><br />&nbsp;&nbsp;&nbsp; <b>g_stereoOperator.AddTargetColor( g_cnColorRealRed );</b><br />&nbsp;&nbsp;&nbsp; <b>g_stereoOperator.AddTargetColor( g_cnColorRealYellow );</b><br /><br />&nbsp;&nbsp;&nbsp; // カメラの投影行列<br />&nbsp;&nbsp;&nbsp; <b>gCamRelate.SetCamParam( 0, arParam.mat );</b><br />&nbsp;&nbsp;&nbsp; <b>gCamRelate.SetCamParam( 1, arParam.mat );</b><br />}<br /></blockquote>CStereoAnyColorPointの初期化では、指定色をAddTargetColorで追加します。<br />CCamerasRelationの初期化では、SetCamParamで各カメラに透視投影行列を設定します。<br /><br /><br />マーカーを認識できた時点で、もう１度別の初期化を行います<br />CCamerasRelationで、カメラ間の関係を計算します<br /><blockquote>// 2つのカメラが、同じマーカーを認識できてるかどうか<br />if ( gContextsActive[0].id == gContextsActive[1].id )<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp; // カメラ１の変換行列を保存<br />&nbsp;&nbsp;&nbsp;&nbsp; CopyArray3x4ToMatrix4x4( mtrxTemp1, gContextsActive[0].patt_trans );<br />&nbsp;&nbsp;&nbsp;&nbsp; CopyArray3x4ToMatrix4x4( mtrxTemp2, gContextsActive[1].patt_trans );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<b> gCamRelate.CalcRelation(0, 1, mtrxTemp1, mtrxTemp2 );</b><br />}<br /></blockquote>CStereoAnyColorPointでは、新しいカメラ画像をセット<br /><blockquote><b>g_stereoOperator.InitImgSource(&nbsp;&nbsp;&nbsp; arImXsize, arImYsize, <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gContextsActive[0].ARTImage, <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gContextsActive[1].ARTImage );</b><br /></blockquote><br /><br /><b>--- &lt; </b><b>３．画像認識の計算</b><b> &gt; ---</b><br />

<br />

必要な情報をセットできたら、画像処理を行います。<br /><blockquote><b>g_stereoOperator.RecognitionColor3DPos(&amp;gCamRelate);</b><br /></blockquote>画像処理では、カメラの関係を引数として指定します。<br /><br /><br /><b>--- &lt; </b><b>４．結果の取得</b><b> &gt; ---</b><br />


<br />計算が上手くいったら、結果の３次元ベクトルを取得します<br /><br /><blockquote>for ( int iTarget = 0 ; iTarget &lt; <b>g_stereoOperator.GetTargetPosCount()</b> ; iTarget++ )<br />{<br />&nbsp;&nbsp;&nbsp; double dPos[3];<br />&nbsp;&nbsp;&nbsp; if ( !<b>g_stereoOperator.GetTargetPos(iTarget, dPos)</b> )<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<br />}<br /></blockquote><b>GetTargetPos(const int ciTarget, double dPos[3])</b>で、指定色のベクトルを取得できます。<br /><br /><b></b><br />



<br />
<br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのtwoView　その④　色認識を用いたポインティングデバイス</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-4.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.710</id>

    <published>2008-05-31T11:36:48Z</published>
    <updated>2008-05-31T22:18:15Z</updated>

    <summary>twoViewを使ったプログラム、４つ目はポインティングデバイスです。これは、前...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitのtwoview" label="ARToolKitのtwoView" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[twoViewを使ったプログラム、４つ目はポインティングデバイスです。<br />これは、前回の３つのプログラムの機能を合わせて作成しています。<br /><br /><b>------- &lt; 機能の概要 &gt; -------</b><br /><br />

<script type="text/javascript" src="http://www.zoome.jp/swfwrite?param=de3d1686fffdf7f5db4410227ae5ae3c72836cd15f56248b7a686864b343d46165542f4805e0c5d009416a6483d24447f9f1976f&amp;width=360&amp;height=288"></script>

<br /><br />以下、プログラムの処理です。<br /><b><a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-1.html">１．最初にカメラ間の関係を表す、変換行列を計算しておく</a><br /><a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-2.html">２．次に、特徴的な色の検出を行う</a><br /><a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-3.html">３．２の結果から、その色の物体の位置を検出</a><br />４．２つの物体の位置を元に、ポインティングを行う<br /></b><br />１～３までは、これまでのtwoViewを用いたプログラムに対応しています。<br /><br /><br /><br /><b>------- &lt; </b><b>４．２つの物体の位置を元に、ポインティングを行う</b><b> &gt; -------</b><br /><br />ポインティングは次のような手順です<br />１．２つの目印の距離を測る<br />２．距離が短いときは、クリックしていると判定<br />３．クリック中に、３Dモデルとの衝突判定を行う<br />４．衝突していたら、モデルをカーソルと一緒に移動する<br />５．距離が離れてクリックが解除されたら、モデルの移動も止める<br /><br /><br /><br /><b>------- &lt; 参考にした作品 </b><b> &gt; -------</b><br /><br /><br /> 

<iframe src="http://www.nicovideo.jp/thumb/sm2060821" style="border: 1px solid rgb(204, 204, 204);" frameborder="0" height="176" scrolling="no" width="312">&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;a href="http://www.nicovideo.jp/watch/sm2060821"&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;【ニコニコ動画】ARToolKitでリモコンミク v2&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;</iframe>
<br /><br />③にも書きましたが、色認識を用いて物体の位置を求めるアイデアは、こちらの動画からいただきました。<br /><br /><br />
<iframe src="http://www.nicovideo.jp/thumb/sm3238847" style="border: 1px solid rgb(204, 204, 204);" frameborder="0" height="176" scrolling="no" width="312">&amp;amp;amp;amp;amp;amp;amp;lt;a href="http://www.nicovideo.jp/watch/sm3238847"&amp;amp;amp;amp;amp;amp;amp;gt;【ニコニコ動画】ARToolKitでARDeskTopもどき（その２）&amp;amp;amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;amp;amp;gt;</iframe><br /><br />求めた物体の座標をポインティングデバイスとして使用するアイデアは、この動画からのものです。<br /><br /><br />お二人には、この場を借りて感謝いたします。<br />また、他の開発者の皆さんからも、たくさんアイデアを頂いています。<br /><br />良い作品を見せていただき、ありがとうございました。<br />これからも、よろしくお願いします。<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのtwoView　その③　特徴点の距離検出</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-3.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.709</id>

    <published>2008-05-28T10:51:13Z</published>
    <updated>2008-05-30T13:47:01Z</updated>

    <summary>長い時間上手くいかず悩んでいましたが、やっとそれらしい結果が出るようになりました...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitのtwoview" label="ARToolKitのtwoView" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[長い時間上手くいかず悩んでいましたが、やっとそれらしい結果が出るようになりました。<br />前回の特徴物体の位置から、物体までの距離を求めます。<br /> <br />

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/featureDist01.jpg" alt="featureDist01.jpg" height="200" width="240" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/featureDist02.jpg" alt="featureDist02.jpg" height="200" width="240" />&nbsp;&nbsp;<br /><br />
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/featureDist03.jpg" alt="featureDist03.jpg" height="200" width="240" />&nbsp;&nbsp;
<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/featureDist04.jpg" alt="featureDist04.jpg" height="200" width="240" />&nbsp;&nbsp;<br /><br /><br />参考にしたのは、以下の動画です。<br /><br />

<iframe src="http://www.nicovideo.jp/thumb/sm2060821" style="border: 1px solid rgb(204, 204, 204);" frameborder="0" height="176" scrolling="no" width="312">&amp;amp;amp;amp;amp;lt;a href="http://www.nicovideo.jp/watch/sm2060821"&amp;amp;amp;amp;amp;gt;【ニコニコ動画】ARToolKitでリモコンミク v2&amp;amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;amp;gt;</iframe>

<br /><br />この方は、他にもARToolKitと物理演算を合わせたりと、かなり高度なことをやっています。<br /><br />

<iframe src="http://www.nicovideo.jp/thumb/sm2888459" style="border: 1px solid rgb(204, 204, 204);" frameborder="0" height="176" scrolling="no" width="312">&amp;amp;amp;amp;lt;a href="http://www.nicovideo.jp/watch/sm2888459"&amp;amp;amp;amp;gt;【ニコニコ動画】ARでかもしてみた&amp;amp;amp;amp;lt;/a&amp;amp;amp;amp;gt;</iframe><br /><br /><br /><br />今回は、簡単な三角測量を用いて距離計算を行っています。<br />簡単なケースでは、２つのカメラの向きを平行にして、Y・Z座標の位置も同じにします。<br /><br />ちなみに失敗していた理由は、<b>VIEW_SCALEFACTOR</b>という値を考えていなかったからでした。<br />これは、ARToolKitの長さの単位から、OpenGLの単位へ変換するときに必要になります。<br /><br />まだ誤差などがあるようなので、これから調整します。<br /><br /><br /><br /><b>--------- &lt; 追記 &gt; ---------</b><br /><br />○08/05/29<br /><br />誤差が安定してきたので、処理を大まかに説明。<br /><br />前回(<a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-2.html">その②</a>)の各カメラでの、特徴点の<b>スクリーン座標系の位置</b>を取得。<br />これを、透視投影変換の逆行列を使って、<b>カメラ座標系の位置</b>に変換。<br /><br />また、<a href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-1.html">その①</a>で求めたカメラ間の変換行列から、カメラのX座標系での距離を取得しておく。<br /><br />そこで、以下の計算を行う。<br />１．<b>a</b> = カメラ間のXの距離 / (カメラ１での特徴点のX座標 - カメラ２での特徴点のX座標)<br />２．カメラ１の特徴点の座標（カメラ座標系）を<b>a</b>倍する。<br />３．２の結果が、特徴点で示した物体の<b>３次元空間上での座標</b>（カメラ座標系）になる。<br />４．カメラ１で、マーカーからの変換行列の逆行列を計算しておく<br />５．２の結果に対し、４の逆行列をかけて、<b>マーカー座標系での特徴物体の座標</b>を計算する。<br />６．５に対し、<b>VIEW_SCALEFACTOR</b>をかけて、OpenGLの長さの単位にする。<br /><br /><br />このようにして、出た座標を表示すると、最初のような画像になります。<br />画像では、[マーカー座標系の原点]から[特徴物体の真下]までの線と、そこから[特徴物体]までの線を描画しています。<br /><br /><br />○08/05/30<br /><br />まだ微妙な誤差がありましたが、三角測量の倍数の計算で、<br />X値だけじゃなくY値も入れた距離で計算したら上手くいきました。<br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのFlash版があるようです</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkitflash.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.708</id>

    <published>2008-05-19T12:37:10Z</published>
    <updated>2008-05-19T12:56:13Z</updated>

    <summary>日々ARToolKitに関するニュースを探しているPipeRですが、先日ARTo...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitのニュース" label="ARToolKitのニュース" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[日々ARToolKitに関するニュースを探しているPipeRですが、<br />先日<a href="http://saqoosha.net/2008/05/16/665/">ARToolKitをFlashに移植されたというブログ</a>を見つけました。<br /><br />FlashのActionScriptは昔少しだけ触ったことがありますが、<br />これでARToolKitを作ってしまえるとは驚きました。<br /><br /><br /><br /><cite></cite><a href="http://nyatla.jp/nyartoolkit/wiki/index.php">ARToolKitをJAVAに移植したA虎@さんのNyARToolkit</a>といい、<br />スキルの高い開発者の方々が、ARToolKitのさらなるマルチプラットフォーム化を進めています。<br /><br />これは、より多くの人がARToolKitを使えるようになる、すばらしいことです。<br /><br />私の開発の目的はあくまで自分の勉強のためですが、<br />このような方々のように、もっと有用なプログラムを作りたいですね。<br /><br /><br /><br />あと有用なプログラムといえば、<a href="http://www.gizmodo.jp/">ギズモード・ジャパン</a>で紹介されていた、<br /><a href="http://www.gizmodo.jp/2007/10/levelhead.html">ARToolKitを使ったゲーム</a>なんてのもあります。<br /><br />これも非常に面白くて、ARToolKitを上手く生かしてると思いました。<br /><br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのtwoView　その②　特徴色の認識</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-2.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.707</id>

    <published>2008-05-19T11:58:23Z</published>
    <updated>2008-05-28T11:23:54Z</updated>

    <summary>twoViewを使ったプログラム、２回目は特徴色の認識ですが、正直これだけならt...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitのtwoview" label="ARToolKitのtwoView" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[twoViewを使ったプログラム、２回目は特徴色の認識ですが、<br />正直これだけならtwoViewは関係ありません。 <br /><br />ですがこれができれば、次に面白いことができます。<br /><br /><br />ということで、軽く説明いたします。<br />基本は、解析のところでやったことに似ています。<br /><br /><br /><b>--- &lt; 処理の概要 &gt; ---</b><br /><br />

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/recogFeatureColor01.jpg" alt="recogFeatureColor01.jpg" height="274" width="164" />&nbsp;&nbsp;

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/recogFeatureColor02.jpg" alt="recogFeatureColor02.jpg" height="274" width="164" />&nbsp;&nbsp;

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/recogFeatureColor03.jpg" alt="recogFeatureColor03.jpg" height="274" width="164" /><br /><br /><br />処理は以下のようなものになります。<br /><b>１．認識したい特徴的な色を取得する。<br />２．カメラに映った画像を、特徴色で２値化する。<br />３．２値化画像に対して、各閉領域を区別する。<br />４．閉領域を絞り込んで、適切なものを選択する。<br /><br /><br /></b><b><br /></b><b>--- &lt; </b><b>１．認識したい特徴的な色を取得する </b><b>&gt; ---</b><br />
<br />最初に認識したい物体の色を取得します。<br />この色は、周囲の色とは違う特徴的な色でなくてはいけません。<br /><br />マウスで画面内の特徴色をクリックし、その色を取得します。<br /><br /><br /><br /><b>--- &lt; </b><b>
２．カメラに映った画像を、特徴色で２値化する </b><b>&gt; ---</b><br />
<br />次に、与えられた画像を特徴色で２値化します。<br />画像の全ての点の色を調べ、特徴色に近いものだけ白にして、その他は黒にします。<br /><br /><br /><br /><b>--- &lt; </b><b>
３．２値化画像に対して、各閉領域を区別する </b><b>&gt; ---</b><br />
<br />白い領域に対してのみラベリングを行い、各閉領域を区別します。<br />ここでは、異なる色で各閉領域を表しています。<br /><br />またこのとき、閉領域の面積や外接矩形も計算しておきます。<br /><br /><br /><br /><b>--- &lt; </b><b>
４．閉領域を絞り込んで、適切なものを選択する </b><b>&gt; ---</b><br />
<b><br /></b>最後に、特徴色だと判定する閾値を変えたり、<br />閉領域の面積が小さい・大きいものを除外したりして、目的の閉領域を求めます。<br /><br />目的の閉領域が、影などにより分かれてしまっていた場合、<br />外接矩形を見てくっつける、なんてこともできそうです。<br /><br /><br /><br /><br /><br />さて次はこれを使って、とても面白いプログラムができるはずなのですが、<br />勉強不足のため、なかなか上手くいきません。<br /><br />ついつい、学生の頃愛用していた<a href="http://www.amazon.co.jp/%E3%82%B2%E3%83%BC%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE3D%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9%E6%95%B0%E5%AD%A6-Eric-Lengyel/dp/4939007375"><span class="sans"><span id="btAsinTitle">3Dグラフィックス数学</span></span></a>の本を買ってしまいました。<br />もっと数学の勉強をしないとだめです。<br /><br /><a href="http://www.amazon.co.jp/%E3%82%B2%E3%83%BC%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE3D%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9%E6%95%B0%E5%AD%A6-Eric-Lengyel/dp/4939007375"><span class="sans"><span id="btAsinTitle"> </span></span></a>]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのtwoView　その①　カメラ間の関係</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview-1.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.704</id>

    <published>2008-05-11T09:24:03Z</published>
    <updated>2008-05-28T11:24:24Z</updated>

    <summary>ARToolKitのtwoViewを使ったプログラム、その① カメラ間の関係を保...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitのtwoview" label="ARToolKitのtwoView" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの安定化" label="ARToolKitの安定化" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[ARToolKitのtwoViewを使ったプログラム、その①<br /><br />
カメラ間の関係を保持し、それを使ってマーカーを補間します。<br />

ここでも、安定化と似たような計算を行います。<br />

<strong><br /><br /></strong>


今回は動画では短すぎるので、画像のみです。<br /><br />

<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/cameraRelate01.JPG" alt="cameraRelate01.JPG" height="300" width="180" />　　　<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/cameraRelate04.JPG" alt="cameraRelate03.JPG" height="300" width="180" /><br /><br /> <img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/cameraRelate02.JPG" alt="cameraRelate02.JPG" height="300" width="180" />　　　<img src="http://render.s73.xrea.com/pipe_render/image/artoolkit/cameraRelate03.JPG" alt="cameraRelate03.JPG" height="300" width="180" /><strong><br /><br /><br /><br />--- &lt; 処理の概要 &gt; ---<br /><br /></strong>

まず、どちらのカメラにもマーカーが映っている場合に、以下のような計算をします。<br /><br />

・"<b>マーカー→カメラ１</b>"、"<b>マーカー→カメラ２</b>"　が分かっている。<br />
・"<b>マーカー→カメラ１</b>"を反転して"<b>カメラ１→マーカー</b>"にする。<br />
・"<b>カメラ１→マーカー→カメラ２</b>"という行列計算を行い、”<b>カメラ１→カメラ２</b>”を取得する。<br /><br />次に、片方のカメラでマーカーが見つからなかった場合に、次のような計算で補間を行います。<br /><br />カメラ１のみでマーカーが見つからなかった場合<br />・”<b>カメラ１→カメラ２</b>”、"<b>マーカー→カメラ２</b>"　が分かっている。<br />・”<b>カメラ１→カメラ２</b>”を反転して、”<b>カメラ２→カメラ１</b>”にする。<br />・"<b>マーカー→カメラ２→カメラ１</b>"という行列計算を行い、"<b>マーカー→カメラ１</b>"を取得する。<br /><br />カメラ２の場合も同様です。<br /><br />これで、片方のカメラにさえマーカーが映っていれば、<br />マーカーが見えなくてもその位置を特定することができます。<br /><br /><br /><br /><strong>--- &lt; 処理の特徴 &gt; ---<br />
</strong><br />この方法を使うと安定化にも繋がりますが、そのために以下のような制限が付きます。<br /><br />・一番最初に、２つのカメラに同じマーカーを映すなどして、変換行列を計算する。<br />・片方のカメラが動いた場合、変換行列を再計算する。<br />・両方のカメラでマーカーを発見できないときは、補間ができない。<br /><br />等々です。<br />これを解決するためには、いくつか方法が考えられます。<br /><br />１．カメラを絶対に動かさないようにする。<br />２．２つのカメラを固定して、変換行列を変えないまま移動できるようにする。<br />３．カメラ１に、マーカーとカメラ２が必ず映るようにして、カメラ２にもマーカーを付ける。<br /><br />こんなところでしょうか。<br />他にも方法がありそうですね。<br /><br /><br /><br /><strong>--- &lt; 最後に &gt; ---<br />
</strong><br />上記のように、twoViewを使うには少し工夫をしないといけないようです。<br />ですが、そこから得られる機能には、いろんな使い道がありそうです。<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの解析　その③　ソースの公開</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkit-14.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.703</id>

    <published>2008-05-10T06:29:46Z</published>
    <updated>2008-05-10T08:58:01Z</updated>

    <summary>作成した処理の可視化プログラムを公開いたします。ARToolKitAlgo1.0...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの解析" label="ARToolKitの解析" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitソースの公開" label="ARToolKitソースの公開" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[作成した処理の可視化プログラムを公開いたします。<br /><br /><a href="http://render.s73.xrea.com/pipe_render/program/artoolkit/ARToolKitAlgo1.0_080510.zip">ARToolKitAlgo1.0_080510.zip</a><br /><br /><br />今回のプロジェクトは"Microsoft Visual C++ 2008 Express Edition"で開発いたしました。<br />ライブラリに、いくつかコメントを追加しましたが、不完全で間違っている可能性があります。<br /><b><br /><br />--- &lt;実行ファイルの使い方&gt; ---</b><br /><br />○変換行列の計算プログラム<br /><br />・とりあえず実行<br />０．カメラにマーカーが映るようにします<br />１．画像が表示されているウィンドウを選択して、[C]キーを押し、３Dモデルのみの画面が大きく表示されるようにします。<br />２．画面内で、右クリックしながら３Dモデルをズームアウトして、仮想的なカメラが表示されるようにします。<br />３．[1]キーを押して、仮想的なディスプレイを表示します。<br />４．[2]キーを押して、ディスプレイに映ったマーカーを表示します。<br />５．[3]キーを押して、マーカーの辺１を伸ばした面を、１つ表示します。<br />６．[4]キーを押して、面１の法線を表示します。<br />
７．[5]キーを押して、辺１の向かいの辺での面と法線を表示します。<br />

８．[6]キーを押して、２つの法線の外積を求めます。<br />



９．[7]キーを押して、残りの面と法線を表示します。<br />

１０．[8]キーを押して、その外積を表示します。<br />

１１．[9]キーを押して、２つの外積の外積を表示します。<br />
<br />・その他の操作<br />[0]キー：処理の表示を初期状態に戻す<br />[b]キー：立方体オブジェクトの表示/非表示<br />[m]キー：マーカーオブジェクトの表示/非表示<br /><br /><br />○マーカーの認識プログラム<br /><br />[1]キー：２値化した画像を表示します。<br />[2]キー：ラベリングした画像を表示します。<br />[3]キー：頂点１を表示します。<br />[4]キー：輪郭を表示します。<br />[5]キー：頂点２を表示します。<br />[6]キー：頂点３，４を表示します。<br />[0]キー：表示を元に戻します。<br />[c]キー：画像の位置を変更<br />[o]キー：輪郭線を表示/非表示<br />[q]キー：頂点１を表示/非表示<br />[w]キー：頂点２を表示/非表示<br />[e]キー：頂点３を表示/非表示<br />[r]キー：頂点４を表示/非表示<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitのTwoViewを触ってみる</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkittwoview.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.702</id>

    <published>2008-05-09T11:42:35Z</published>
    <updated>2008-05-10T12:53:53Z</updated>

    <summary>やっと２つめのカメラを購入したので、さっそくTwoViewを触ってみました。遅く...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの解析" label="ARToolKitの解析" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[やっと２つめのカメラを購入したので、さっそくTwoViewを触ってみました。<br />遅くなってしまったので、コメントを頂いた方はもう解決したかもしれませんが、一応書いておきます。<br /><br />基本的には、<a href="http://bbs1.fc2.com/php/e.php/12741/?act=reply&amp;tid=4077610">工学ナビ様のBBSで説明されている手順</a>通りです。<br />詳しく書いてみます。<br /><br />ちなみに僕の環境は以下の通りです。<br />OS&nbsp;&nbsp; &nbsp;&nbsp; : Microsoft Windows XP Home Edition (SP2)<br />CPU&nbsp;&nbsp;&nbsp; : AMD Athlon^(TM) 64 X2 プロセッサ 3800+<br />メモリ&nbsp;&nbsp; : DDR SDRAM 1GB<br />Webカメラ:<span class="lh12">Qcam Pro for Notebooks ×2</span><br /><br /><br /><b>１．</b><span class="lh12"><b>GraphEditの入手</b><br /></span><span class="lh12">GraphEditは、DirectX</span> SDKの中に入っています。<br />ひとまず、"C:\Program Files\"内で、<span class="lh12">GraphEditとか、</span>graphedtで検索してみてください。<br />見つからない場合は、DirectX SDKをインストールしてください。<br /><br /><br /><b>２．Webカメラのデバイス名を取得</b><br /><span class="lh12">GraphEditを起動したら、</span>メニューから[Graph]-&gt;[Insert Filters...]を選択、ダイアログを開きます。<br />ダイアログのツリーから[Video Capture Source]を開き、その中の各Webカメラ名を選択します。<br />僕の場合は、[<span class="lh12">Qcam Pro for Notebooks</span>]が２つあります。<br /><br />各Webカメラ名を選択したときに、一番下のエディットボックスに表示される長い文字列が、そのWebカメラのデバイス名になります。僕の場合は、<br /><br /><blockquote>@device:pnp:\\?\usb#vid_046d&amp;pid_0991&amp;mi_00<br />#6&amp;22a7aaac&amp;0&amp;0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\<br />{bbefb6c7-2fc4-4139-bb8b-a58bba724083}<br /><br />@device:pnp:\\?\usb#vid_046d&amp;pid_0991&amp;mi_00<br />#6&amp;a9d31db&amp;1&amp;0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\<br />{bbefb6c7-2fc4-4139-bb8b-a58bba724083}<br /></blockquote>という文字列でした。<br /><br />この文字列は、もちらんそのカメラ固有のもので、僕のカメラのものを他の人が使っても上手くいきません。<br /><br /><br /><b>３．ARToolKitの設定ファイルを書き換える</b><br />Dataフォルダの"WDM_camera_flipV.xml"というファイルを、適当なエディタで開きます。<br />その中で、<br /><br /><blockquote>&lt;camera show_format_dialog="true" friendly_name="PGR"&gt;<br /></blockquote><br />という行があるはずです。これに"device_name"追加して、以下のようにします。<br /><br /><blockquote>
&lt;camera show_format_dialog="true" friendly_name="PGR" device_name=""&gt;<br /></blockquote><br />

ここで、先ほど取得したカメラのデバイス名を、device_nameの""内にコピーします。<br /><br /><blockquote>&lt;camera show_format_dialog="true" friendly_name="PGR" device_name="@device:pnp:\\?\usb#vid_046d&amp;pid_0991&amp;mi_00#<br />6&amp;22a7aaac&amp;0&amp;0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\<br />{bbefb6c7-2fc4-4139-bb8b-a58bba724083}"&gt;<br /></blockquote><br /> 次に、コピーした文字列で"&amp;"になっている部分を"&amp;amp;"に置き換えます。<br /><br /><blockquote>
&lt;camera show_format_dialog="true" friendly_name="PGR"
device_name="@device:pnp:\\?\usb#vid_046d&amp;amp;pid_0991&amp;amp;mi_00#<br />6&amp;amp;22a7aaac&amp;amp;0&amp;amp;0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\<br />{bbefb6c7-2fc4-4139-bb8b-a58bba724083}"&gt;<br /></blockquote><br />

この変更したファイルを、別名で保存します。<br />ここでは、"WDM_camera_flipV_01.xml"とします。<br /><br />もう１つのデバイス名についても同じ作業をして、名前を変えて保存します。<br />こっちは、"WDM_camera_flipV_02.xml"としました。<br /><br /><br /><b>４．プログラムを書き換える</b><br />プロジェクトを開いて、twoView.cを変更します。<br />"WDM_camera_flipV.xml"のところを、新しく作ったファイルに置き換えます。<br /><br /><blockquote>#if defined(_WIN32)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "Data\\WDM_camera_flipV.xml",<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "Data\\WDM_camera_flipV.xml",<br />#elif defined(__APPLE__)<br /></blockquote><br />を<br /><br /><blockquote>#if defined(_WIN32)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "Data\\WDM_camera_flipV_01.xml",<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "Data\\WDM_camera_flipV_02.xml",<br />#elif defined(__APPLE__)<br /></blockquote>に変更しました。<br /><br /><br /><br />以上で終わりです。<br />僕の場合は、これでうまくいきました。<br /><br />これでも失敗する場合は、残念ながら僕には分かりません。<br />twoViewについては、他にも解説しているサイトがあるので、そちらを参照してください。<br /><br />Webカメラの種類も関係あるみたいです。<br /><br /><br /><br /><br />※追記　<br /><br />○08/05/09 <br /><br />一方のカメラのフレームレートだけ、やけに遅い問題が発生していましたが、<br />"videoWin32DirectShow.cpp"ファイルの<br /><br /><blockquote>const long&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; frame_timeout_ms = 0L;<br /></blockquote>というのを<br /><br /><blockquote>const long&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; frame_timeout_ms = 100L;<br /></blockquote>ぐらいにしたら、直りました。数値は適当です。<br /><br /><br />○08/05/10<br /><br />一方のカメラの画面が上下反転していた問題がありました。<br />調べてみると、"WDM_camera_flipV_02.xml"ファイルだけ、<br /><br /><blockquote>&lt;RGB32 flip_h="false" flip_v="true"/&gt;<br /></blockquote>が<br /><br /><blockquote>&lt;RGB32/&gt;<br /></blockquote>となっていたのが原因でした。<br />このファイルを作るのに、"WDM_camera.xml"を利用したのが間違いだったみたいです。<br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの解析　その②　マーカーの認識</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/05/artoolkit-13.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.701</id>

    <published>2008-05-05T08:28:10Z</published>
    <updated>2008-05-05T14:54:28Z</updated>

    <summary>解析の２回目は、マーカーの認識についてです。前回の変換行列の計算で、省略した部分...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの解析" label="ARToolKitの解析" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[解析の２回目は、マーカーの認識についてです。<br />前回の変換行列の計算で、省略した部分を説明します。<br /><br /><br /><b><br />---- &lt; マーカー認識の概要 &gt; ----</b><br />

<b><br />※注意<br />
この動画で、画像の色分けでは、そのつど色が計算されるため、多くの色が点滅するような動画になっています。<br />
また、画像の生成等の重い処理を行っているので、フレームレートは低くなっています。<br />
<br />
光過敏性発作などがある方は、予めご注意ください。</b><br />
<br /><script type="text/javascript" src="http://www.zoome.jp/swfwrite?param=de3d1686fffdf7f5db4410227ae5ae3c72836cd15f5624877a686864b343d4326459294805e0c5d00941656483d24447f9f1976f&amp;width=360&amp;height=288"></script><b><br /></b><br /><br />BGM：エコテロニカ（sansuiさん）<br /><br />なんだかムーンサイドみたいですね。<br />ちょっと誤字があるようですが、気にしないでください。<br /><br /><br />ARToolKitでは、変換行列を計算する前に、その基となるマーカーを知っていなければなりません。<br />
カメラに映った画像から、どこにマーカーがあるのか判定するために、おおまかに以下のような処理を行います。<br /><br /><br />
<b>１．</b><b>カメラからの画像を</b><b>２値化して、画像の暗い部分を探す<br />２．暗い部分で、それぞれの閉じた領域に印を付ける<br />３．各閉領域で、一番端の点を最初の頂点（頂点１）とする<br />４．頂点１から、領域の輪郭を探す<br /></b><b>５．輪郭が分かったら、２番目の頂点を探す</b><br /><b>６．残りの頂点３，４を探す<br />７．４つの頂点をもつ領域を４角形と判断する<br />８．４角形内の画像を単純化する<br />９．単純化された画像に対して、パターンマッチングを行う<br /><br /></b>それぞれの処理を見てみます。<br /><br /><br /><br /><b>---- &lt; </b><b>１．カメラからの画像を２値化して、画像の暗い部分を探す</b><b> &gt; ----<br /><br /></b>カメラから得られたカラー画像を、２値化して白or黒のみの画像にします。<br />ARToolKitでは、黒枠のマーカーを認識するので、<br />ここでの画像は白黒を反転したようなものになっています。<br /><br /><b><br /><br /></b><b>---- &lt; </b><b>
２．暗い部分で、それぞれの閉じた領域に印を付ける</b><b> &gt; ----<br /><br /></b>画像を２値化すると、閉じた領域がたくさんできます。<br />それぞれの閉領域を区別するために、ラベリングと呼ばれる作業を行います。<br /><br />これは、各領域を走査して、繋がっている部分に同じ番号を割り振っていく作業になります。<br /><br /><br /><br /><b>---- &lt; </b><b>
３．各閉領域で、一番端の点を最初の頂点（頂点１）とする</b><b> &gt; ----<br /><br /></b>２で閉領域が見つかったので、各閉領域の外接矩形を求めます。<br /><br />そして、外接矩形の辺上にある点を探します。<br />これが、最初の頂点（頂点１）になります。<br /><br /><b><br /><br /></b><b>---- &lt; </b><b>
４．頂点１から、領域の輪郭を探す</b><b> &gt; ----</b><br /><br />次に、輪郭を探します。<br />頂点１からスタートして、閉領域の輪郭を辿るように、点を見つけていきます。<br />最後に、頂点１に戻ってきます。<br /><br /><br /><br /><b>---- &lt; </b><b>
５．輪郭が分かったら、２番目の頂点を探す</b><b> &gt; ----<br /><br /></b>輪郭は点の集まりなので、その中で頂点１から最も離れたものを探します。<br />それを頂点２とします。<br /><br /><br /><br /><b>---- &lt; </b><b>
６．残りの頂点３，４を探す</b><b> &gt; ----<br /><br /></b>頂点１、２から頂点３，４を探します。<br />まず輪郭点を、"頂点１→２"　と　"頂点２→１"　の２つに分けます。<br /><br />２つの輪郭点で、頂点１・２の線分から、最も離れた点を探します。<br />これを再帰的に繰り返して、残りの頂点も見つけ出します。<br /><br /><b><br /><br /></b><b>---- &lt; </b><b>
７．４つの頂点をもつ領域を４角形と判断する</b><b> &gt; ----<br /><br /></b>上記の処理の途中で、領域が望みの４角形かどうかが、だいたい判定されます。<br /><br />最初に、面積が非常に小さい、または大きい領域は除外されます。<br />他にも、４つの頂点がうまく見つからない領域も除外されます。<br /><br />４つの頂点は、順番に並んでいるとは限らないので、<br />そのつど調整されます。<br /><br /><br /><br /><b>---- &lt; </b><b>
８．４角形内の画像を単純化する</b><b> &gt; ----</b><br /><b><br /></b>４角形が見つかったので、やっとパターンの判別に入ります。<br />判別のために、４角形内の画像は単純かされます。<br /><br />マーカーが斜めに映っている場合も、内部の画像は修正され、真正面からのものになり、<br />解像度も非常に小さくなります。<br /><br /><b><br /><br />---- &lt; </b><b>
９．単純化された画像に対して、パターンマッチングを行う</b><b> &gt; ----</b><br /><br /> この単純化された画像に対して、パターンマッチングを行います。<br />パターンマッチングでは、基となるパターンと単純化された４角形内の画像を比較し、誤差を計算します。<br /><br />この誤差が、ある決まった値より小さい場合に、これが求めるマーカーであると判定されることになります。<br />（実際には、最も誤差が小さいパターンが、その４角形に割り当てられ、後の判断はプログラマに委ねられます。<br /><br /><br /><br /><b>---- &lt; 最後に</b><b> &gt; ----</b><br /><br />調べてみて分かりましたが、すばらしいアルゴリズムですね。<br />非常に勉強になりました。<br /><br />やはり、所々怪しいところはありますので、間違い等はご指摘いただければありがたいです。<br /><br /><br /><br />あまり関係ないですが、BGMを使用させてもらっているsansuiさんつながりで、「ゆめにっき」というフリーゲームを現在やっています。<br />RPGツクールで作られた、夢の中を探索するという戦闘のないゲームなんですが、<b>「とても怖いゲーム」</b>です。<br />まるで、マザー２のムーンサイドのような怖さで、今回作った動画もプログラムもそれっぽいと思ってしまいました。<br /><br /><br /><br />]]>
        
    </content>
</entry>

<entry>
    <title>ARToolKitの解析　その①　変換行列の計算</title>
    <link rel="alternate" type="text/html" href="http://render.s73.xrea.com/pipe_render/2008/04/artoolkit-12.html" />
    <id>tag:render.s73.xrea.com,2008:/pipe_render//1.700</id>

    <published>2008-04-27T07:38:08Z</published>
    <updated>2008-05-05T14:55:00Z</updated>

    <summary>安定化の次は、プログラムの高速化などをやってみようと思ってましたが、高速化のため...</summary>
    <author>
        <name>PipeR</name>
        
    </author>
    
        <category term="拡張現実" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="artoolkit" label="ARToolKit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="artoolkitの解析" label="ARToolKitの解析" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://render.s73.xrea.com/pipe_render/">
        <![CDATA[安定化の次は、プログラムの高速化などをやってみようと思ってましたが、<br />高速化のためには、ARToolKitのソースをもっと理解していなければなりません。<br /><br />そこで、次に「ARToolKitの解析」を行うことにしました。<br /><br /><br />解析のその１は、<b>変換行列の計算アルゴリズム</b>の解説をやってみます。<br />ここでいう変換行列とは、マーカー（オブジェクト）座標系から、グローバル（カメラ）座標系へ変換する行列のことです。<br /><br />これは、ARToolKitの重要な仕組みの１つです。<br /><br /><br /><br /><b>
---- &lt; 変換行列計算の概要 &gt; ----</b><br />
<br /><script type="text/javascript" src="http://www.zoome.jp/swfwrite?param=de3d1686fffdf7f5db4410227ae5ae3c72836cd15f5624877a686864b343d433320d7c4805e0c5d00941646483d24447f9f1976f&amp;width=360&amp;height=288"></script><br /><br />BGM：エコテロニカ（sansuiさん）<br /><br />&nbsp;OpenGLなどの３DCGでは、３Dモデルの移動・回転などを行うために、座標系の変換行列を用います。<br />ARToolKitの場合も、この変換行列がないと、マーカー上にモデルを表示できません。<br /><br />プログラムでは、スクリーン上に映ったマーカーの画像から、この変換行列を計算しています。<br />計算のプロセスは、大まかに以下のようになります。<br /><br /><b>１．マーカーの黒い四角形を認識する<br />２．四角形の枠である、４辺を計算する<br />３．それぞれの辺を、カメラの投影方向に伸ばし、面を作る<br />４．面の法線を計算<br />５．向かい合った面同士の法線から、外積を計算する<br />６．その外積同士から、さらに外積を計算<br />７．現在わかっている式を用いて、行列の残り値を計算する</b><br /><br />今回は"スクリーン上の４角形の４辺"から、"変換行列の３×３の要素"を計算するとこまでを中心に、解説していきます。<br /><br /><br /><br /><b>---- &lt; １．マーカーの黒い四角形を認識 &gt; ----</b><br /><br />四角形の認識ではまず、カメラに映った画像を２値化（白黒に）します。<br />そして、その白黒画像から、４角形を探します。<br />さらに、見つけた４角形が登録されているマーカーかどうか調べます。<br /><br />この部分の詳しいアルゴリズムについては、後日解説するつもりです。<br /><br /><br /><br /><b>---- &lt; ２．四角形の枠である、４辺を計算する &gt; ----</b><br /><br />
ここも、１と一緒に解説いたします。<br /><br /><br /> <br /><b>---- &lt; ３．それぞれの辺を、カメラの投影方向に伸ばし、面を作る &gt; ----</b><br /><br />４角形の辺が取得できたら、この辺を伸ばして、面にします。<br />伸ばし方は、辺がスクリーンへ投影された方向に伸ばします。<br /><br />つまりこの面は、３次元空間上のマーカーの４辺も通ることになります。<br />カメラの視点、２Dのマーカーの辺、3Dのマーカーの辺を繋ぐ面です。<br /><br /><br /><br /><b>---- &lt; ４．面の法線を計算 &gt; ----</b><br />
<br />それぞれの面の法線（面に対して、垂直なベクトル）を計算します。<br /><br />
<br /><br /><b>---- &lt; ５．向かい合った面同士の法線から、外積を計算する &gt; ----</b><br />

<br />法線が計算できたら、向かい合った面同士の法線から、外積を計算します。<br />外積は、２つの法線に対し垂直になります。<br /><br />この外積は、マーカー座標系の１つの軸を表すベクトルになります。<br /><br /><br /><br /><b>---- &lt; ６．その外積同士から、さらに外積を計算 &gt; ----</b><br />


<br />さらに、外積同士の外積をとります。<br />この３つの外積が、それぞれマーカー座標系のX軸, Y軸, Z軸になります。<br /><br />さらに値を補正すると、変換行列の３×３の要素になるわけです。<br /><br /><br /><br /><b>---- &lt; ８．現在わかっている式を用いて、行列の残り値を計算する &gt; ----</b><br />



<br />変換行列の３×３の要素は、回転や拡大縮小を表しています。<br />変換行列に必要な残りの要素は、平行移動です。<br /><br />平行移動分を計算するには、それまでに用いられた行列等の式を使い、答えを出します。<br /><br /><br /><br />以上が、僕が理解できた範囲でのアルゴリズムの説明です。<br />間違いや不足があった場合には、連絡をお願いします。<br /><br />]]>
        
    </content>
</entry>

</feed>
