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
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
\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
{\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
_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
{\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
--- /dev/null
+/* \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
*/\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
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
* @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
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
out_index++;\r
} \r
}\r
- return;\r
+ return true;\r
}\r
/**\r
* i_freqにあるゼロクロス点の周期が、等間隔か調べます。\r
\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
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
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
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
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
} \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
\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
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
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
}\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
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
* 成功すればマーカの方位を返却します。失敗すると-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
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
*/\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
* @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
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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
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
--- /dev/null
+/* \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
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