OSDN Git Service

[バックアップ]NyARToolkit for Java
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Sun, 17 May 2009 12:32:59 +0000 (12:32 +0000)
committernyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Sun, 17 May 2009 12:32:59 +0000 (12:32 +0000)
Idマーカシステム関連の修正。サンプルプログラムSingleNyIdMarker完成

12 files changed:
sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java
sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/SingleNyIdMarker.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerParam.java
src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerPattern.java [moved from src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerData.java with 89% similarity]
src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerPickup.java
src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerData.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerDataEncoder.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerDataEncoder_RawBit.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerData_RawBit.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/processor/SingleARMarkerProcesser.java
src/jp/nyatla/nyartoolkit/processor/SingleNyIdMarkerProcesser.java [new file with mode: 0644]
test/jp/nyatla/nyartoolkit/dev/PattPickupTest.java

index bac9461..ea64909 100644 (file)
@@ -31,24 +31,20 @@ import java.awt.*;
 import javax.media.Buffer;\r
 import javax.media.opengl.*;\r
 import com.sun.opengl.util.*;\r
+import jp.nyatla.nyartoolkit.*;\r
 import jp.nyatla.nyartoolkit.core.*;\r
 import jp.nyatla.nyartoolkit.core.param.*;\r
 import jp.nyatla.nyartoolkit.core.transmat.*;\r
 import jp.nyatla.nyartoolkit.detector.*;\r
 import jp.nyatla.nyartoolkit.jmf.utils.*;\r
 import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+\r
 /**\r
- * simpleLiteと同じようなテストプログラム\r
- * 出来る限りARToolKitのサンプルと似せて作ってあります。\r
- * 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
+ * simpleLiteと同じようなテストプログラム 出来る限りARToolKitのサンプルと似せて作ってあります。 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
  * \r
  */\r
 public class JavaSimpleLite implements GLEventListener, JmfCaptureListener\r
 {\r
-       private final String CARCODE_FILE = "../../Data/patt.hiro";\r
-\r
-       private final String PARAM_FILE = "../../Data/camera_para.dat";\r
-\r
        private final static int SCREEN_X = 640;\r
 \r
        private final static int SCREEN_Y = 480;\r
@@ -60,23 +56,26 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
        private JmfCaptureDevice _capture;\r
 \r
        private GL _gl;\r
+\r
        private NyARGLUtil _glnya;\r
 \r
-       //NyARToolkit関係\r
+       // NyARToolkit関係\r
        private NyARSingleDetectMarker _nya;\r
+\r
        private NyARParam _ar_param;\r
 \r
-       private double[] _camera_projection=new double[16];\r
-       \r
+       private Object _sync_object=new Object();\r
+       private double[] _camera_projection = new double[16];\r
+\r
        /**\r
         * 立方体を書く\r
-        *\r
+        * \r
         */\r
        void drawCube()\r
        {\r
                // Colour cube data.\r
                int polyList = 0;\r
-               float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体\r
+               float fSize = 0.5f;// マーカーサイズに対して0.5倍なので、4cmの立方体\r
                int f, i;\r
                float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
                float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
@@ -112,10 +111,27 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
 \r
        }\r
 \r
-       public JavaSimpleLite()\r
+       public JavaSimpleLite(NyARParam i_param, NyARCode i_ar_code) throws NyARException\r
        {\r
+               this._ar_param = i_param;\r
+\r
                Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+               this._nya = new NyARSingleDetectMarker(this._ar_param, i_ar_code, 80.0);\r
 \r
+               \r
+               // キャプチャの準備\r
+               JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();\r
+               this._capture = devlist.getDevice(0);\r
+               if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) {\r
+                       throw new NyARException();\r
+               }\r
+               this._capture.setOnCapture(this);\r
+               // NyARToolkitの準備\r
+               this._nya.setContinueMode(true);// ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+               // GL対応のRGBラスタオブジェクト\r
+               this._cap_image = new GLNyARRaster_RGB(this._ar_param, this._capture.getCaptureFormat());\r
+               \r
+               \r
                // 3Dを描画するコンポーネント\r
                GLCanvas canvas = new GLCanvas();\r
                frame.add(canvas);\r
@@ -137,39 +153,20 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
        {\r
                this._gl = drawable.getGL();\r
                this._gl.glEnable(GL.GL_DEPTH_TEST);\r
-\r
                this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
-               //NyARToolkitの準備\r
+               // NyARToolkitの準備\r
                try {\r
-                       //キャプチャの準備\r
-                       JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
-                       this._capture=devlist.getDevice(0);\r
-                       if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
-                               throw new Exception();\r
-                       }\r
-                       this._capture.setOnCapture(this);\r
-                       //NyARToolkitの準備\r
-                       this._ar_param = new NyARParam();\r
-                       NyARCode ar_code = new NyARCode(16, 16);\r
-                       ar_code.loadARPattFromFile(CARCODE_FILE);\r
-                       this._ar_param.loadARParamFromFile(PARAM_FILE);\r
-                       this._ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
-                       this._nya = new NyARSingleDetectMarker(this._ar_param, ar_code, 80.0);\r
-                       this._nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。\r
-                       //NyARToolkit用の支援クラス\r
+                       // NyARToolkit用の支援クラス\r
                        _glnya = new NyARGLUtil(_gl);\r
-                       //GL対応のRGBラスタオブジェクト\r
-                       _cap_image = new GLNyARRaster_RGB(this._ar_param,this._capture.getCaptureFormat());\r
-                       //キャプチャ開始\r
+                       // キャプチャ開始\r
                        _capture.start();\r
                } catch (Exception e) {\r
                        e.printStackTrace();\r
                }\r
-               //カメラパラメータの計算\r
-               _glnya.toCameraFrustumRH(_ar_param,_camera_projection);\r
-\r
-               _animator = new Animator(drawable);\r
-               _animator.start();\r
+               // カメラパラメータの計算\r
+               this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+               this._animator = new Animator(drawable);\r
+               this._animator.start();\r
                return;\r
        }\r
 \r
@@ -178,60 +175,62 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
                _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
                _gl.glViewport(0, 0, width, height);\r
 \r
-               //視体積の設定\r
+               // 視体積の設定\r
                _gl.glMatrixMode(GL.GL_PROJECTION);\r
                _gl.glLoadIdentity();\r
-               //見る位置\r
+               // 見る位置\r
                _gl.glMatrixMode(GL.GL_MODELVIEW);\r
                _gl.glLoadIdentity();\r
        }\r
-       private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();\r
-       private double[] __display_wk=new double[16];\r
-       \r
+\r
+       private boolean _is_marker_exist=false;\r
+       private NyARTransMatResult __display_transmat_result = new NyARTransMatResult();\r
+\r
+       private double[] __display_wk = new double[16];\r
+\r
        public void display(GLAutoDrawable drawable)\r
        {\r
-               NyARTransMatResult transmat_result=__display_transmat_result;\r
-               try {\r
-                       if (!_cap_image.hasData()) {\r
-                               return;\r
-                       }\r
-                       _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.          \r
-                       //画像チェックしてマーカー探して、背景を書く\r
-                       boolean is_marker_exist;\r
-                       synchronized (_cap_image) {\r
-                               is_marker_exist = _nya.detectMarkerLite(_cap_image, 110);\r
-                               //背景を書く\r
-                               _glnya.drawBackGround(_cap_image, 1.0);\r
-                       }\r
-                       //マーカーがあれば、立方体を描画\r
-                       if (is_marker_exist) {\r
-                               //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
-                               // Projection transformation.\r
-                               _gl.glMatrixMode(GL.GL_PROJECTION);\r
-                               _gl.glLoadMatrixd(_camera_projection, 0);\r
-                               _gl.glMatrixMode(GL.GL_MODELVIEW);\r
-                               // Viewing transformation.\r
-                               _gl.glLoadIdentity();\r
-                               //変換行列を取得\r
-                               _nya.getTransmationMatrix(transmat_result);\r
-                               //変換行列をOpenGL形式に変換\r
-                               _glnya.toCameraViewRH(transmat_result, __display_wk);\r
-                               _gl.glLoadMatrixd(__display_wk, 0);\r
-\r
-                               // All other lighting and geometry goes here.\r
-                               drawCube();\r
+               NyARTransMatResult transmat_result = __display_transmat_result;\r
+               if (!_cap_image.hasData()) {\r
+                       return;\r
+               }\r
+               // 背景を書く\r
+               this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+               this._glnya.drawBackGround(this._cap_image, 1.0);                       \r
+               try{\r
+                       synchronized(this._sync_object){\r
+                               // マーカーがあれば、立方体を描画\r
+                               if (this._is_marker_exist){\r
+                                       // マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+                                       // Projection transformation.\r
+                                       _gl.glMatrixMode(GL.GL_PROJECTION);\r
+                                       _gl.glLoadMatrixd(_camera_projection, 0);\r
+                                       _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+                                       // Viewing transformation.\r
+                                       _gl.glLoadIdentity();\r
+                                       // 変換行列を取得\r
+                                       _nya.getTransmationMatrix(transmat_result);\r
+                                       // 変換行列をOpenGL形式に変換\r
+                                       _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+                                       _gl.glLoadMatrixd(__display_wk, 0);\r
+               \r
+                                       // All other lighting and geometry goes here.\r
+                                       drawCube();\r
+                               }\r
                        }\r
-                       Thread.sleep(1);//タスク実行権限を一旦渡す\r
-               } catch (Exception e) {\r
+                       Thread.sleep(1);// タスク実行権限を一旦渡す\r
+               }catch(Exception e){\r
                        e.printStackTrace();\r
                }\r
 \r
        }\r
+\r
        public void onUpdateBuffer(Buffer i_buffer)\r
        {\r
                try {\r
-                       synchronized (_cap_image) {\r
-                               _cap_image.setBuffer(i_buffer);\r
+                       synchronized (this._sync_object) {\r
+                               this._cap_image.setBuffer(i_buffer);\r
+                               this._is_marker_exist =this._nya.detectMarkerLite(this._cap_image, 110);\r
                        }\r
                } catch (Exception e) {\r
                        e.printStackTrace();\r
@@ -242,8 +241,24 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
        {\r
        }\r
 \r
+       private final static String CARCODE_FILE = "../../Data/patt.hiro";\r
+\r
+       private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
        public static void main(String[] args)\r
        {\r
-               new JavaSimpleLite();\r
+               try {\r
+                       NyARParam param = new NyARParam();\r
+                       param.loadARParamFromFile(PARAM_FILE);\r
+                       param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+\r
+                       NyARCode code = new NyARCode(16, 16);\r
+                       code.loadARPattFromFile(CARCODE_FILE);\r
+\r
+                       new JavaSimpleLite(param, code);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return;\r
        }\r
 }\r
diff --git a/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/SingleNyIdMarker.java b/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/SingleNyIdMarker.java
new file mode 100644 (file)
index 0000000..fedd88c
--- /dev/null
@@ -0,0 +1,297 @@
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.sample;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.*;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import java.util.Date;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+\r
+import com.sun.opengl.util.*;\r
+import com.sun.opengl.util.j2d.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+import jp.nyatla.nyartoolkit.processor.*;\r
+\r
+\r
+class TextPanel\r
+{\r
+       private TextRenderer _tr;\r
+       public TextPanel(int i_size)\r
+       {\r
+               this._tr=new TextRenderer(new Font("SansSerif", Font.BOLD, 36));\r
+\r
+       }\r
+       public void draw(String i_str,float i_scale)\r
+       {\r
+               this._tr.begin3DRendering();\r
+           this._tr.setColor(1.0f, 0.2f, 0.2f, 0.8f);\r
+           this._tr.draw3D(i_str, 0f,0f,0f,i_scale);\r
+               this._tr.end3DRendering();\r
+               return;\r
+       }\r
+}\r
+\r
+/**\r
+ * 1個のIdマーカを認識するサンプルアプリケーション。\r
+ * 認識したIDマーカの上に情報を表示します。\r
+ * 構造的には、アプリケーションフレームワークのSingleNyIdMarkerProcesserにNyIdMarkerDataEncoder_RawBit\r
+ * をバインドしてあります。\r
+ *\r
+ */\r
+public class SingleNyIdMarker extends SingleNyIdMarkerProcesser implements GLEventListener, JmfCaptureListener\r
+{\r
+       private Animator _animator;\r
+\r
+       private GLNyARRaster_RGB _cap_image;\r
+\r
+       private JmfCaptureDevice _capture;\r
+\r
+       private GL _gl;\r
+       private NyARGLUtil _glnya;\r
+       private TextPanel _panel;\r
+\r
+\r
+       //NyARToolkit関係\r
+       private NyARParam _ar_param;\r
+\r
+       private double[] _camera_projection=new double[16];\r
+       \r
+       private Object _sync_object=new Object();\r
+       private NyARTransMatResult _ref_result=null;\r
+       private int _current_id=-1;\r
+\r
+       public SingleNyIdMarker(NyARParam i_cparam) throws NyARException\r
+       {\r
+               //アプリケーションフレームワークの初期化\r
+               super(i_cparam,new NyIdMarkerDataEncoder_RawBit());\r
+               this.setMarkerWidth(100);\r
+               this.setBaseThreshold(110);//基準閾値(そのうち自動にする)\r
+               JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
+               this._ar_param=i_cparam;\r
+\r
+               //キャプチャリソースの準備\r
+               this._capture=devlist.getDevice(0);\r
+               if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
+                       throw new NyARException();\r
+               }\r
+               this._capture.setOnCapture(this);\r
+               this._cap_image = new GLNyARRaster_RGB(i_cparam,this._capture.getCaptureFormat());              \r
+\r
+               //OpenGLフレームの準備(OpenGLリソースの初期化、カメラの撮影開始は、initコールバック関数内で実行)\r
+               Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+               GLCanvas canvas = new GLCanvas();\r
+               frame.add(canvas);\r
+               canvas.addGLEventListener(this);\r
+               frame.addWindowListener(new WindowAdapter() {\r
+                       public void windowClosing(WindowEvent e)\r
+                       {\r
+                               System.exit(0);\r
+                       }\r
+               });\r
+               \r
+               //ウインドウサイズの調整\r
+               frame.setVisible(true);\r
+               Insets ins = frame.getInsets();\r
+               frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+               canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+               return;\r
+       }\r
+       public void init(GLAutoDrawable drawable)\r
+       {\r
+               this._panel = new TextPanel(100);\r
+\r
+\r
+               this._gl = drawable.getGL();\r
+               this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+\r
+               this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+               //NyARToolkitの準備\r
+               try {\r
+                       this._glnya = new NyARGLUtil(this._gl);\r
+                       //カメラパラメータの計算\r
+                       this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+                       //キャプチャ開始\r
+                       this._capture.start();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+               this._animator = new Animator(drawable);\r
+               this._animator.start();\r
+               return;\r
+       }\r
+\r
+       public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+       {\r
+               \r
+               _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+               _gl.glViewport(0, 0, width, height);\r
+\r
+               //視体積の設定\r
+               _gl.glMatrixMode(GL.GL_PROJECTION);\r
+               _gl.glLoadIdentity();\r
+               //見る位置\r
+               _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+               _gl.glLoadIdentity();\r
+       }\r
+       private double[] __display_wk=new double[16];\r
+       \r
+       \r
+       public void display(GLAutoDrawable drawable)\r
+       {\r
+               NyARTransMatResult transmat_result = this._ref_result;\r
+               if (!_cap_image.hasData()) {\r
+                       return;\r
+               }\r
+               // 背景を書く\r
+               this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+               this._glnya.drawBackGround(this._cap_image, 1.0);                       \r
+               if(this._current_id<0 || transmat_result==null){\r
+                       \r
+               }else{\r
+                       try{\r
+                               synchronized(this._sync_object){\r
+                                       // Projection transformation.\r
+                                       this._gl.glMatrixMode(GL.GL_PROJECTION);\r
+                                       this._gl.glLoadMatrixd(_camera_projection, 0);\r
+                                       this._gl.glMatrixMode(GL.GL_MODELVIEW);\r
+                                       // Viewing transformation.\r
+                                       this._gl.glLoadIdentity();\r
+                                       // 変換行列をOpenGL形式に変換\r
+                                       this._glnya.toCameraViewRH(transmat_result, __display_wk);\r
+                                       this._gl.glLoadMatrixd(__display_wk, 0);\r
+                                       // All other lighting and geometry goes here.\r
+                                       this._gl.glPushMatrix();\r
+                                       this._gl.glDisable(GL.GL_LIGHTING);\r
+\r
+                                       \r
+                                       //マーカのXZ平面をマーカの左上、表示開始位置を10cm上空へ。\r
+                                       //くるーんくるん\r
+                                       Date d = new Date();\r
+                                       float r=(d.getTime()/50)%360;\r
+                                       this._gl.glRotatef(r,0f,0f,1.0f);\r
+                                       this._gl.glTranslatef(-1.0f,0f,1.0f);\r
+                                       this._gl.glRotatef(90,1.0f,0f,0f);\r
+                                       this._panel.draw("MarkerId:"+this._current_id,0.01f);\r
+                                       this._gl.glPopMatrix();\r
+                               }\r
+                               Thread.sleep(1);// タスク実行権限を一旦渡す\r
+                       }catch(Exception e){\r
+                               e.printStackTrace();\r
+                       }\r
+               }               \r
+               return;\r
+\r
+       }\r
+       /**\r
+        * アプリケーションフレームワークのハンドラ(マーカ出現)\r
+        */\r
+       protected void onEnterHandler(INyIdMarkerData i_code)\r
+       {\r
+               synchronized(this._sync_object){\r
+                       NyIdMarkerData_RawBit code=(NyIdMarkerData_RawBit)i_code;\r
+                       if(code.length>4){\r
+                               //4バイト以上の時はint変換しない。\r
+                               this._current_id=-1;//undefined_id\r
+                       }else{\r
+                               this._current_id=0;\r
+                               //最大4バイト繋げて1個のint値に変換\r
+                               for(int i=0;i<code.length;i++){\r
+                                       this._current_id=(this._current_id<<8)|code.packet[i];\r
+                               }\r
+                       }\r
+                       this._ref_result=null;\r
+               }\r
+       }\r
+       /**\r
+        * アプリケーションフレームワークのハンドラ(マーカ消滅)\r
+        */\r
+       protected void onLeaveHandler()\r
+       {\r
+               synchronized(this._sync_object){\r
+                       this._current_id=-1;\r
+                       this._ref_result=null;\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * アプリケーションフレームワークのハンドラ(マーカ更新)\r
+        */\r
+       protected void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result)\r
+       {\r
+               synchronized(this._sync_object){\r
+                       this._ref_result=result;\r
+               }\r
+       }\r
+\r
+       \r
+       /**\r
+        * カメラデバイスからのコールバック\r
+        */\r
+       public void onUpdateBuffer(Buffer i_buffer)\r
+       {\r
+               try {\r
+                       synchronized (this._sync_object) {\r
+                               this._cap_image.setBuffer(i_buffer);\r
+                               //フレームワークに画像を転送\r
+                               this.detectMarker(this._cap_image);\r
+                       }\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+       {\r
+       }\r
+\r
+\r
+       private final static int SCREEN_X = 640;\r
+       private final static int SCREEN_Y = 480;\r
+       private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
+       //エントリポイント\r
+       public static void main(String[] args)\r
+       {\r
+               try{\r
+                       NyARParam cparam= new NyARParam();\r
+                       cparam.loadARParamFromFile(PARAM_FILE);\r
+                       cparam.changeScreenSize(SCREEN_X, SCREEN_Y);            \r
+                       new SingleNyIdMarker(cparam);\r
+               }catch(Exception e){\r
+                       e.printStackTrace();\r
+               }\r
+               return;\r
+       }\r
+}\r
index f969595..4c1fb23 100644 (file)
@@ -37,7 +37,13 @@ package jp.nyatla.nyartoolkit.nyidmarker;
  */\r
 public class NyARIdMarkerParam\r
 {\r
+       /**\r
+        * マーカの方位値です。\r
+        */\r
        public int direction;\r
+       /**\r
+        * マーカ周辺のパターン閾値です。\r
+        */\r
        public int threshold; \r
        \r
 }\r
  */\r
 package jp.nyatla.nyartoolkit.nyidmarker;\r
 /**\r
- * IDã\83\9eã\83¼ã\82«ã\81®値を格納するクラスです。\r
+ * IDã\83\9eã\83¼ã\82«ã\83\91ã\82¿ã\83¼ã\83³値を格納するクラスです。\r
  * クラスは、未整形のマーカデータを格納しています。\r
  *\r
  */\r
-public class NyARIdMarkerData\r
+public class NyARIdMarkerPattern\r
 {\r
        public int model;\r
        public int ctrl_domain;\r
        public int ctrl_mask;\r
        public int check;\r
-       public int[] data=new int[16];\r
+       public int[] data=new int[32];\r
 }
\ No newline at end of file
index 7837346..53edc38 100644 (file)
@@ -53,14 +53,17 @@ class PerspectivePixelReader
        private NyARPerspectiveParamGenerator _param_gen=new NyARPerspectiveParamGenerator_O1(1,1,100,100);\r
        private double[] _cparam=new double[8];\r
 \r
+       private INyARRgbRaster _raster;\r
+       private NyARIntSize _raster_size;\r
+\r
        public PerspectivePixelReader()\r
        {\r
                return;\r
        }\r
-       private INyARRgbRaster _raster;\r
        public void setSourceRaster(INyARRgbRaster i_raster)\r
        {\r
                this._raster=i_raster;\r
+               this._raster_size=i_raster.getSize();\r
                return;\r
        }\r
        public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
@@ -81,14 +84,20 @@ class PerspectivePixelReader
         * @param o_pixel\r
         * @throws NyARException\r
         */\r
-       private void rectPixels(int i_lt_x,int i_lt_y,int i_step_x,int i_step_y,int i_width,int i_height,int i_out_st,int[] o_pixel)throws NyARException\r
+       private boolean rectPixels(int i_lt_x,int i_lt_y,int i_step_x,int i_step_y,int i_width,int i_height,int i_out_st,int[] o_pixel)throws NyARException\r
        {\r
                final double[] cpara=this._cparam;\r
                final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
                final int[] ref_x=this._ref_x;\r
                final int[] ref_y=this._ref_y;\r
                final int[] pixcel_temp=this._pixcel_temp;\r
+               final int raster_width=this._raster_size.w;\r
+               final int raster_height=this._raster_size.h;\r
+\r
                int out_index=i_out_st;\r
+               final double cpara_6=cpara[6];\r
+               final double cpara_0=cpara[0];\r
+               final double cpara_3=cpara[3];\r
 \r
                for(int i=0;i<i_height;i++){\r
                        //1列分のピクセルのインデックス値を計算する。\r
@@ -99,15 +108,16 @@ class PerspectivePixelReader
                        int pt=0;\r
                        for(int i2=0;i2<i_width;i2++)\r
                        {\r
-                               int cx0=1+i2*i_step_x+i_lt_x;\r
-\r
-                               double cp6_0=cpara[6]*cx0;\r
-                               double cpx0_0=cpara[0]*cx0;\r
-                               double cpx3_0=cpara[3]*cx0;\r
-                               \r
-                               final double d=cp6_0+cpy0_7;\r
-                               ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
-                               ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+                               final int cx0=1+i2*i_step_x+i_lt_x;                             \r
+                               final double d=cpara_6*cx0+cpy0_7;\r
+                               final int x=(int)((cpara_0*cx0+cpy0_12)/d);\r
+                               final int y=(int)((cpara_3*cx0+cpy0_45)/d);\r
+                               if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+                               {\r
+                                       return false;\r
+                               }\r
+                               ref_x[pt]=x;\r
+                               ref_y[pt]=y;\r
                                pt++;\r
                        }\r
                        //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
@@ -119,7 +129,7 @@ class PerspectivePixelReader
                                out_index++;\r
                        }                       \r
                }\r
-               return;\r
+               return true;\r
        }\r
        /**\r
         * i_freqにあるゼロクロス点の周期が、等間隔か調べます。\r
@@ -174,15 +184,15 @@ class PerspectivePixelReader
                \r
        \r
        //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
-       private static int FRQ_EDGE=5;\r
-       private static int FRQ_STEP=2;\r
-       private static int FRQ_POINTS=(100-(FRQ_EDGE*2))/FRQ_STEP;\r
+       private static final int FRQ_EDGE=5;\r
+       private static final int FRQ_STEP=2;\r
+       private static final int FRQ_POINTS=(100-(FRQ_EDGE*2))/FRQ_STEP;\r
        \r
 \r
-       private static int MIN_FREQ=3;\r
-       private static int MAX_FREQ=10;\r
-       private static int FREQ_SAMPLE_NUM=4;\r
-       private static int MAX_DATA_BITS=MAX_FREQ+MAX_FREQ-1;\r
+       private static final int MIN_FREQ=3;\r
+       private static final int MAX_FREQ=10;\r
+       private static final int FREQ_SAMPLE_NUM=4;\r
+       private static final int MAX_DATA_BITS=MAX_FREQ+MAX_FREQ-1;\r
 \r
        private final int[] _ref_x=new int[108];\r
        private final int[] _ref_y=new int[108];\r
@@ -225,9 +235,12 @@ class PerspectivePixelReader
                for(int i=0;i<110;i++){\r
                        freq_table[i]=0;\r
                }\r
+               final int raster_width=this._raster_size.w;\r
+               final int raster_height=this._raster_size.h;\r
+\r
                final double cpara_0=cpara[0];\r
                final double cpara_3=cpara[3];\r
-               final double cpara_6=cpara[6];\r
+               final double cpara_6=cpara[6];          \r
                \r
                //10-20ピクセル目からタイミングパターンを検出\r
                for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
@@ -235,17 +248,21 @@ class PerspectivePixelReader
                        final double cy0=1+i_y1+i;\r
                        final double cpy0_12=cpara[1]*cy0+cpara[2];\r
                        final double cpy0_45=cpara[4]*cy0+cpara[5];\r
-                       final double cpy0_7=cpara[7]*cy0+1.0;                   \r
-\r
+                       final double cpy0_7=cpara[7]*cy0+1.0;\r
 \r
                        int pt=0;\r
                        for(int i2=0;i2<FRQ_POINTS;i2++)\r
                        {\r
-                               double d;\r
                                final double cx0=1+i2*FRQ_STEP+FRQ_EDGE;                        \r
-                               d=(cpara_6*cx0)+cpy0_7;\r
-                               ref_x[pt]=(int)((cpara_0*cx0+cpy0_12)/d);\r
-                               ref_y[pt]=(int)((cpara_3*cx0+cpy0_45)/d);\r
+                               final double d=(cpara_6*cx0)+cpy0_7;\r
+                               final int x=(int)((cpara_0*cx0+cpy0_12)/d);\r
+                               final int y=(int)((cpara_3*cx0+cpy0_45)/d);\r
+                               if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+                               {\r
+                                       return -1;\r
+                               }\r
+                               ref_x[pt]=x;\r
+                               ref_y[pt]=y;\r
                                pt++;\r
                        }\r
                        \r
@@ -281,23 +298,26 @@ class PerspectivePixelReader
                final int[] ref_y=this._ref_y;\r
                final int[] pixcel_temp=this._pixcel_temp;\r
                //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110\r
-               final int[] freq_count_table=this._freq_count_table;\r
-               final int freq_table[]=this._freq_table;\r
                //初期化\r
+               final int[] freq_count_table=this._freq_count_table;\r
                for(int i=0;i<10;i++){\r
                        freq_count_table[i]=0;\r
                }\r
+               final int freq_table[]=this._freq_table;\r
                for(int i=0;i<110;i++){\r
                        freq_table[i]=0;\r
                }\r
+               final int raster_width=this._raster_size.w;\r
+               final int raster_height=this._raster_size.h;\r
+               \r
+               \r
                final double cpara7=cpara[7];\r
                final double cpara4=cpara[4];\r
                final double cpara1=cpara[1];\r
                //基準点から4ピクセルを参照パターンとして抽出\r
                for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
 \r
-                       int cx0;\r
-                       cx0=1+i+i_x1;\r
+                       int cx0=1+i+i_x1;\r
                        final double cp6_0=cpara[6]*cx0;\r
                        final double cpx0_0=cpara[0]*cx0+cpara[2];\r
                        final double cpx3_0=cpara[3]*cx0+cpara[5];\r
@@ -305,12 +325,17 @@ class PerspectivePixelReader
                        int pt=0;\r
                        for(int i2=0;i2<FRQ_POINTS;i2++)\r
                        {\r
-                               double d;\r
                                int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
                                \r
-                               d=cp6_0+cpara7*cy+1.0;\r
-                               ref_x[pt]=(int)((cpx0_0+cpara1*cy)/d);\r
-                               ref_y[pt]=(int)((cpx3_0+cpara4*cy)/d);\r
+                               final double d=cp6_0+cpara7*cy+1.0;\r
+                               final int x=(int)((cpx0_0+cpara1*cy)/d);\r
+                               final int y=(int)((cpx3_0+cpara4*cy)/d);\r
+                               if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+                               {\r
+                                       return -1;\r
+                               }\r
+                               ref_x[pt]=x;\r
+                               ref_y[pt]=y;                            \r
                                pt++;\r
                        }               \r
                \r
@@ -605,8 +630,8 @@ class PerspectivePixelReader
                }               \r
                \r
                \r
-               int frq_l=getColFrequency(i_th.lt_x,i_th.th_h,i_th.th_l,freq_index1);\r
-               int frq_r=getColFrequency(i_th.rb_x,i_th.th_h,i_th.th_l,freq_index2);\r
+               final int frq_l=getColFrequency(i_th.lt_x,i_th.th_h,i_th.th_l,freq_index1);\r
+               final int frq_r=getColFrequency(i_th.rb_x,i_th.th_h,i_th.th_l,freq_index2);\r
                //周波数はまとも?\r
                if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
                        return -1;\r
@@ -668,7 +693,6 @@ class PerspectivePixelReader
                \r
                final int th=i_th.th;\r
                int p=0;\r
-               int pt2=0;\r
                for(int i=0;i<resolution;i++){\r
                        //1列分のピクセルのインデックス値を計算する。\r
                        double cy0=1+index_y[i*2+0];\r
@@ -699,29 +723,21 @@ class PerspectivePixelReader
                                d=cp6_0+cpy0_7;\r
                                ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
                                ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
-                               this.vertex_x[pt2]=ref_x[pt];\r
-                               this.vertex_y[pt2++]=ref_y[pt];\r
                                pt++;\r
 \r
                                d=cp6_0+cpy1_7;\r
                                ref_x[pt]=(int)((cpx0_0+cpy1_12)/d);\r
                                ref_y[pt]=(int)((cpx3_0+cpy1_45)/d);\r
-                               this.vertex_x[pt2]=ref_x[pt];\r
-                               this.vertex_y[pt2++]=ref_y[pt];\r
                                pt++;\r
 \r
                                d=cp6_1+cpy0_7;\r
                                ref_x[pt]=(int)((cpx0_1+cpy0_12)/d);\r
                                ref_y[pt]=(int)((cpx3_1+cpy0_45)/d);\r
-                               this.vertex_x[pt2]=ref_x[pt];\r
-                               this.vertex_y[pt2++]=ref_y[pt];\r
                                pt++;\r
 \r
                                d=cp6_1+cpy1_7;\r
                                ref_x[pt]=(int)((cpx0_1+cpy1_12)/d);\r
                                ref_y[pt]=(int)((cpx3_1+cpy1_45)/d);\r
-                               this.vertex_x[pt2]=ref_x[pt];\r
-                               this.vertex_y[pt2++]=ref_y[pt];\r
                                pt++;\r
                        }\r
                        //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
@@ -733,7 +749,8 @@ class PerspectivePixelReader
                                                        pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
                                                        pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
                                                        pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
-                               o_bitbuffer.setBitByBitIndex(p,pixel>th?1:0);\r
+                               //暗点を1、明点を0で表現します。\r
+                               o_bitbuffer.setBitByBitIndex(p,pixel>th?0:1);\r
                                p++;\r
                        }\r
                }\r
@@ -751,8 +768,6 @@ class PerspectivePixelReader
                }\r
 */             return true;\r
        }\r
-       int[] vertex_x;\r
-       int[] vertex_y;\r
        public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
        {\r
                if (!this._param_gen.getParam(i_vertex,this._cparam)) {\r
@@ -898,14 +913,14 @@ class MarkerPattEncoder
                        r=((this._bits[2] & 0xf0)>>4)|((this._bits[3]&0x01)<<4);\r
                        b=this._bits[3] & 0x1f;\r
                        l=((this._bits[3] & 0xf0)>>4)|((this._bits[2]&0x01)<<4);\r
-                       timing_pat=0x15;\r
+                       timing_pat=0x0a;\r
                        break;\r
                case 3:\r
                        t=this._bits[4] & 0x7f;\r
                        r=((this._bits[4] & 0xc0)>>6)|((this._bits[5] & 0x1f)<<2);\r
                        b=((this._bits[5] & 0xf0)>>4)|((this._bits[6] & 0x07)<<4);\r
                        l=((this._bits[6] & 0xfc)>>2)|((this._bits[4] & 0x01)<<6);\r
-                       timing_pat=0x55;\r
+                       timing_pat=0x2a;\r
                        break;\r
                default:\r
                        return -3;\r
@@ -933,7 +948,7 @@ class MarkerPattEncoder
         * 成功すればマーカの方位を返却します。失敗すると-1を返します。\r
         */\r
 \r
-       public int encode(NyARIdMarkerData o_out)\r
+       public int encode(NyARIdMarkerPattern o_out)\r
        {\r
                final int d=getDirection();\r
                if(d<0){\r
@@ -960,9 +975,10 @@ class MarkerPattEncoder
                int sr=8-sl;\r
 \r
                int w1;\r
+               o_out[0]=this._bits[0];\r
                //RECT1\r
                w1=this._bits[1];\r
-               this._bits[1]=(w1<<sl)|(w1>>sr);\r
+               o_out[1]=((w1<<sl)|(w1>>sr))& 0xff;\r
                \r
                //RECT2\r
                sl=i_direction*4;\r
@@ -1018,24 +1034,16 @@ class MarkerPattEncoder
  */\r
 public class NyARIdMarkerPickup\r
 {\r
-       PerspectivePixelReader _perspective_reader;\r
+       private PerspectivePixelReader _perspective_reader;\r
+       private final PerspectivePixelReader.TThreshold __pickFromRaster_th=new PerspectivePixelReader.TThreshold();\r
+       private final MarkerPattEncoder __pickFromRaster_encoder=new MarkerPattEncoder();\r
 \r
 \r
        public NyARIdMarkerPickup()\r
        {\r
                this._perspective_reader=new PerspectivePixelReader();\r
                return;\r
-       }       \r
-       \r
-       \r
-\r
-       public int[] vertex_x=new int[225*4];\r
-       public int[] vertex_y=new int[225*4];\r
-       public int[] vertex2_x=new int[400];\r
-       public int[] vertex2_y=new int[400];\r
-\r
-\r
-\r
+       }\r
        /**\r
         * i_imageから、idマーカを読みだします。\r
         * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。\r
@@ -1046,7 +1054,7 @@ public class NyARIdMarkerPickup
         * @return\r
         * @throws NyARException\r
         */\r
-       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square,NyARIdMarkerData o_data,NyARIdMarkerParam o_param)throws NyARException\r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square,NyARIdMarkerPattern o_data,NyARIdMarkerParam o_param)throws NyARException\r
        {\r
                this._perspective_reader.setSourceRaster(image);\r
                \r
@@ -1058,16 +1066,14 @@ public class NyARIdMarkerPickup
                final INyARRgbPixelReader reader=image.getRgbPixelReader();\r
 \r
 \r
-               PerspectivePixelReader.TThreshold th=new PerspectivePixelReader.TThreshold();\r
-               MarkerPattEncoder encoder=new MarkerPattEncoder();\r
+               final PerspectivePixelReader.TThreshold th=this.__pickFromRaster_th;\r
+               final MarkerPattEncoder encoder=this.__pickFromRaster_encoder;\r
                //マーカパラメータを取得\r
                this._perspective_reader.detectThresholdValue(reader,10,10,th);\r
 \r
-       \r
-               this._perspective_reader.vertex_x=this.vertex_x;\r
-               this._perspective_reader.vertex_y=this.vertex_y;\r
-\r
-               this._perspective_reader.readDataBits(th, encoder);\r
+               if(!this._perspective_reader.readDataBits(th, encoder)){\r
+                       return false;\r
+               }\r
                final int d=encoder.encode(o_data);\r
                if(d<0){\r
                        return false;\r
diff --git a/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerData.java b/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerData.java
new file mode 100644 (file)
index 0000000..dab26f0
--- /dev/null
@@ -0,0 +1,19 @@
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+\r
+public interface INyIdMarkerData\r
+{\r
+       /**\r
+        * i_targetのマーカデータと自身のデータが等しいかを返します。\r
+        * @param i_target\r
+        * 比較するマーカオブジェクト\r
+        * @return\r
+        * 等しいかの真偽値\r
+        */\r
+       public boolean isEqual(INyIdMarkerData i_target);\r
+       /**\r
+        * i_sourceからマーカデータをコピーします。\r
+        * @param i_source\r
+        */\r
+       public void copyFrom(INyIdMarkerData i_source);\r
+}\r
diff --git a/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerDataEncoder.java b/src/jp/nyatla/nyartoolkit/nyidmarker/data/INyIdMarkerDataEncoder.java
new file mode 100644 (file)
index 0000000..0da0de1
--- /dev/null
@@ -0,0 +1,10 @@
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyARIdMarkerPattern;\r
+\r
+\r
+public interface INyIdMarkerDataEncoder\r
+{\r
+       public boolean encode(NyARIdMarkerPattern i_data,INyIdMarkerData o_dest);\r
+       public INyIdMarkerData createDataInstance();\r
+}\r
diff --git a/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerDataEncoder_RawBit.java b/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerDataEncoder_RawBit.java
new file mode 100644 (file)
index 0000000..62bea06
--- /dev/null
@@ -0,0 +1,37 @@
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyARIdMarkerPattern;\r
+\r
+\r
+public class NyIdMarkerDataEncoder_RawBit implements INyIdMarkerDataEncoder\r
+{      \r
+       private final static int _DOMAIN_ID=0;\r
+       private final static int _mod_data[]={7,31,127,511,2047,4095};\r
+       public boolean encode(NyARIdMarkerPattern i_data,INyIdMarkerData o_dest)\r
+       {\r
+               final NyIdMarkerData_RawBit dest=(NyIdMarkerData_RawBit)o_dest;\r
+               if(i_data.ctrl_domain!=_DOMAIN_ID){\r
+                       return false;\r
+               }\r
+               //パケット数計算\r
+               final int resolution_len=(i_data.model+1);\r
+               final int packet_length=(resolution_len*resolution_len)/8+1;\r
+               int sum=0;\r
+               for(int i=0;i<packet_length;i++){\r
+                       dest.packet[i]=i_data.data[i];\r
+                       sum+=i_data.data[i];\r
+               }\r
+               //チェックドット値計算\r
+               sum=sum%_mod_data[i_data.model-2];\r
+               //チェックドット比較\r
+               if(i_data.check!=sum){\r
+                       return false;\r
+               }\r
+               dest.length=packet_length;\r
+               return true;\r
+       }\r
+       public INyIdMarkerData createDataInstance()\r
+       {\r
+               return new NyIdMarkerData_RawBit();\r
+       }\r
+}\r
diff --git a/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerData_RawBit.java b/src/jp/nyatla/nyartoolkit/nyidmarker/data/NyIdMarkerData_RawBit.java
new file mode 100644 (file)
index 0000000..90b1433
--- /dev/null
@@ -0,0 +1,27 @@
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+public class NyIdMarkerData_RawBit implements INyIdMarkerData\r
+{\r
+       public int[] packet=new int[22];\r
+       public int length;\r
+       public boolean isEqual(INyIdMarkerData i_target)\r
+       {\r
+               NyIdMarkerData_RawBit s=(NyIdMarkerData_RawBit)i_target;\r
+               if(s.length!=this.length){\r
+                       return false;\r
+               }\r
+               for(int i=s.length-1;i>=0;i--){\r
+                       if(s.packet[i]!=s.packet[i]){\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       public void copyFrom(INyIdMarkerData i_source)\r
+       {\r
+               final NyIdMarkerData_RawBit s=(NyIdMarkerData_RawBit)i_source;\r
+               System.arraycopy(s.packet,0,this.packet,0,s.length);\r
+               this.length=s.length;\r
+               return;\r
+       }\r
+}\r
index acaea76..5228128 100644 (file)
@@ -104,7 +104,7 @@ public abstract class SingleARMarkerProcesser
                this._deviation_data=new NyARMatchPattDeviationColorData(scr_size.w,scr_size.h);\r
 \r
                // 2値画像バッファを作る\r
-               this._bin_raster = new NyARBinRaster(scr_size.w / 2, scr_size.h / 2);\r
+               this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
                return;\r
        }\r
 \r
diff --git a/src/jp/nyatla/nyartoolkit/processor/SingleNyIdMarkerProcesser.java b/src/jp/nyatla/nyartoolkit/processor/SingleNyIdMarkerProcesser.java
new file mode 100644 (file)
index 0000000..ceda32b
--- /dev/null
@@ -0,0 +1,259 @@
+/* \r
+ * Capture Test NyARToolkitCSサンプルプログラム\r
+ * --------------------------------------------------------------------------------\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.processor;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.INyIdMarkerData;\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.INyIdMarkerDataEncoder;\r
+\r
+\r
+public abstract class SingleNyIdMarkerProcesser\r
+{\r
+       /**\r
+        * オーナーが自由に使えるタグ変数です。\r
+        */\r
+       public Object tag;\r
+\r
+       /**\r
+        * ロスト遅延の管理\r
+        */\r
+       private int _lost_delay_count = 0;\r
+       private int _lost_delay = 5;\r
+\r
+       private NyARSquareDetector _square_detect;\r
+       protected NyARTransMat _transmat;\r
+       private double _marker_width=100;\r
+\r
+       private NyARSquareStack _square_list = new NyARSquareStack(100);\r
+       private INyIdMarkerDataEncoder _encoder;\r
+       private boolean _is_active;\r
+       private INyIdMarkerData _data_temp;\r
+       private INyIdMarkerData _data_current;\r
+\r
+       \r
+       private int _base_threshold = 110;\r
+       private int _current_threshold;\r
+       // [AR]検出結果の保存用\r
+       private NyARBinRaster _bin_raster;\r
+\r
+       private NyARRasterFilter_ARToolkitThreshold _tobin_filter = new NyARRasterFilter_ARToolkitThreshold(110);\r
+\r
+       private NyARIdMarkerPickup _id_pickup = new NyARIdMarkerPickup();\r
+\r
+\r
+       protected SingleNyIdMarkerProcesser(NyARParam i_param,INyIdMarkerDataEncoder i_encoder) throws NyARException\r
+       {\r
+               NyARIntSize scr_size = i_param.getScreenSize();\r
+               // 解析オブジェクトを作る\r
+               this._square_detect = new NyARSquareDetector(i_param.getDistortionFactor(), scr_size);\r
+               this._transmat = new NyARTransMat(i_param);\r
+               this._encoder=i_encoder;\r
+\r
+               // 2値画像バッファを作る\r
+               this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
+               //ワーク用のデータオブジェクトを2個作る\r
+               this._is_active=false;\r
+               this._data_temp=i_encoder.createDataInstance();\r
+               this._data_current=i_encoder.createDataInstance();\r
+               return;\r
+       }\r
+\r
+       public void setBaseThreshold(int i_threshold)\r
+       {\r
+               this._base_threshold = i_threshold;\r
+               return;\r
+       }\r
+       public void setMarkerWidth(int i_width)\r
+       {\r
+               this._marker_width=i_width;\r
+               return;\r
+       }\r
+\r
+       public void reset(boolean i_is_force)\r
+       {\r
+               if (this._data_current!=null && i_is_force == false) {\r
+                       // 強制書き換えでなければイベントコール\r
+                       this.onLeaveHandler();\r
+               }\r
+               // カレントマーカをリセット\r
+               this._data_current = null;\r
+               return;\r
+       }\r
+\r
+       public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+       {\r
+               // サイズチェック\r
+               if (!this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h)) {\r
+                       throw new NyARException();\r
+               }\r
+               // ラスタを2値イメージに変換する.\r
+               this._tobin_filter.setThreshold(this._current_threshold);\r
+               this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+               NyARSquareStack square_stack = this._square_list;\r
+               // スクエアコードを探す\r
+               this._square_detect.detectMarker(this._bin_raster, square_stack);\r
+               // 認識処理\r
+               if (!this._is_active) {\r
+                       // マーカ未認識→新規認識\r
+                       detectNewMarker(i_raster, square_stack);\r
+               } else {\r
+                       // マーカ認識依頼→継続認識\r
+                       detectExistMarker(i_raster, square_stack);\r
+               }\r
+               return;\r
+       }\r
+\r
+       \r
+       private final NyARIdMarkerPattern _marker_data=new NyARIdMarkerPattern();\r
+       private final NyARIdMarkerParam _marker_param=new NyARIdMarkerParam();\r
+\r
+       \r
+\r
+       /**新規マーカ検索 現在認識中のマーカがないものとして、最も認識しやすいマーカを1個認識します。\r
+        */\r
+       private void detectNewMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack) throws NyARException\r
+       {\r
+               NyARIdMarkerParam param=this._marker_param;\r
+               NyARIdMarkerPattern patt_data  =this._marker_data;\r
+               int number_of_square = i_stack.getLength();\r
+               int square_index = 0;\r
+               INyIdMarkerData marker_id=null;\r
+               for (int i = 0; i < number_of_square; i++) {\r
+                       // 評価基準になるパターンをイメージから切り出す\r
+                       if (!this._id_pickup.pickFromRaster(i_raster, (NyARSquare) i_stack.getItem(i), patt_data, param)) {\r
+                               continue;\r
+                       }\r
+                       //エンコード\r
+                       if(!this._encoder.encode(patt_data,this._data_temp)){\r
+                               continue;\r
+                       }\r
+                       //認識率が一番高いもの(占有面積が一番大きいもの)を選択する(省略)\r
+                       //id認識が成功したら終了\r
+                       marker_id=this._data_temp;\r
+                       break;\r
+               }\r
+               // 認識状態を更新\r
+               updateStatus((NyARSquare) this._square_list.getItem(square_index),marker_id, param);\r
+       }\r
+\r
+       /**マーカの継続認識 現在認識中のマーカを優先して認識します。 \r
+        * (注)この機能はたぶん今後いろいろ発展するからNewと混ぜないこと。\r
+        */\r
+       private void detectExistMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack) throws NyARException\r
+       {\r
+               NyARIdMarkerParam param=this._marker_param;\r
+               NyARIdMarkerPattern patt_data  =this._marker_data;\r
+               int number_of_square = i_stack.getLength();\r
+               int square_index = 0;\r
+               INyIdMarkerData marker_id=null;\r
+               for (int i = 0; i < number_of_square; i++){\r
+                       //idマーカを認識\r
+                       if (!this._id_pickup.pickFromRaster(i_raster, (NyARSquare) i_stack.getItem(i), patt_data, param)) {\r
+                               continue;\r
+                       }\r
+                       if(!this._encoder.encode(patt_data,this._data_temp)){\r
+                               continue;\r
+                       }\r
+                       //現在認識中のidか確認\r
+                       if(!this._data_current.isEqual((this._data_temp))){\r
+                               continue;\r
+                       }\r
+                       //現在認識中のものであれば、終了\r
+                       marker_id=this._data_temp;\r
+                       break;\r
+               }\r
+               // 認識状態を更新\r
+               updateStatus((NyARSquare) this._square_list.getItem(square_index),marker_id,param);\r
+       }\r
+\r
+       private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+       /**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+        */\r
+       private void updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data,NyARIdMarkerParam i_param)  throws NyARException\r
+       {\r
+               boolean is_id_found=false;\r
+               NyARTransMatResult result = this.__NyARSquare_result;\r
+               if (!this._is_active) {// 未認識中\r
+                       if (i_marker_data==null) {// 未認識から未認識の遷移\r
+                               // なにもしないよーん。\r
+                               this._is_active=false;\r
+                       } else {// 未認識から認識の遷移\r
+                               this._data_current.copyFrom(i_marker_data);\r
+                               // イベント生成\r
+                               // OnEnter\r
+                               this.onEnterHandler(this._data_current);\r
+                               // 変換行列を作成\r
+                               this._transmat.transMat(i_square,i_param.direction, this._marker_width, result);\r
+                               // OnUpdate\r
+                               this.onUpdateHandler(i_square, result);\r
+                               this._lost_delay_count = 0;\r
+                               this._is_active=true;\r
+                               is_id_found=true;\r
+                       }\r
+               } else {// 認識中\r
+                       if (i_marker_data==null) {\r
+                               // 認識から未認識の遷移\r
+                               this._lost_delay_count++;\r
+                               if (this._lost_delay < this._lost_delay_count) {\r
+                                       // OnLeave\r
+                                       this.onLeaveHandler();\r
+                                       this._is_active=false;\r
+                               }\r
+                       } else if(this._data_current.isEqual(i_marker_data)) {\r
+                               //同じidの再認識\r
+                               this._transmat.transMat(i_square, i_param.direction, this._marker_width, result);\r
+                               // OnUpdate\r
+                               this.onUpdateHandler(i_square, result);\r
+                               this._lost_delay_count = 0;\r
+                               is_id_found=true;\r
+                       } else {// 異なるコードの認識→今はサポートしない。\r
+                               throw new  NyARException();\r
+                       }\r
+               }\r
+               //閾値フィードバック\r
+               if(is_id_found){\r
+                       //マーカがあれば、マーカの周辺閾値を反映\r
+                       this._current_threshold=(this._current_threshold+i_param.threshold)/2;\r
+               }else{\r
+                       //マーカがなければ、探索+DualPTailで基準輝度検索(省略)\r
+                       this._current_threshold=(this._current_threshold+this._base_threshold)/2;\r
+               }\r
+               return;\r
+       }       \r
+       //通知ハンドラ\r
+       protected abstract void onEnterHandler(INyIdMarkerData i_code);\r
+       protected abstract void onLeaveHandler();\r
+       protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
index 7442139..e37c6b0 100644 (file)
@@ -133,7 +133,7 @@ public class PattPickupTest extends Frame implements JmfCaptureListener
                                                g2.drawLine(0,this._patt1.getHeight()/2,this._patt1.getWidth(),this._patt1.getHeight()/2);\r
                                        }\r
                                        {// IDマーカ\r
-                                               NyARIdMarkerData data =new NyARIdMarkerData();\r
+                                               NyARIdMarkerPattern data =new NyARIdMarkerPattern();\r
                                                NyARIdMarkerParam param =new NyARIdMarkerParam();\r
                                                \r
                                                // 一番それっぽいパターンを取得\r