Download List

Sponsored link

System Requirements

System requirement is not defined

Released at 2008-05-11 22:54
NyARToolkit for Java - NyARToolkit Core 1.2.0.20080511 (1 files Hide)

Release Notes

・機能追加
1.arTransmatCont相当のHistory関数を追加しました。
detectorクラスを使う時にsetContinueMode関数でフラグを設定することで、arTransmatCont相当の計算機能を有効化できます。
2.複数マーカー同時認識用のdetectorクラスを実装しました。
NyARDetectMarkerクラスを使うことで、複数マーカー×複数Codeの認識が出来る用になりました。同時認識数は100マーカー程度に設定してあります。JOGLのsimpleLite2サンプルで試すことが出来ます。

・API変更
NyARTransMat.getTransformationMatrix()関数の仕様を変更しました。
戻り値ではなく、引数に与えた戻り引数で結果を受け取るようになりました。

・バグフィクス
特定サイズのマーカを検出したときに、例外を発生させてしまうことがあった問題を修正しました。
#b2oxさんに協力して頂きました。感謝!

・その他修正
1.API変更に追従するために、クラスの幾つかを修正しました。
2.体感できない微妙な高速化を行いました。

Changelog

Index: sample/java3d/src/jp/nyatla/nyartoolkit/java3d/utils/J3dNyARRaster_RGB.java
===================================================================
--- sample/java3d/src/jp/nyatla/nyartoolkit/java3d/utils/J3dNyARRaster_RGB.java (revision 196)
+++ sample/java3d/src/jp/nyatla/nyartoolkit/java3d/utils/J3dNyARRaster_RGB.java (revision 200)
@@ -20,7 +20,6 @@

/**
*
- * @author A虎@
* このクラスは、Java3Dと互換性のあるNyARToolkitのラスタイメージを保持します。
*
*/
Index: sample/java3d/src/jp/nyatla/nyartoolkit/java3d/utils/NyARSingleMarkerBehaviorHolder.java
===================================================================
--- sample/java3d/src/jp/nyatla/nyartoolkit/java3d/utils/NyARSingleMarkerBehaviorHolder.java (revision 196)
+++ sample/java3d/src/jp/nyatla/nyartoolkit/java3d/utils/NyARSingleMarkerBehaviorHolder.java (revision 200)
@@ -13,6 +13,7 @@
import javax.vecmath.*;

import jp.nyatla.nyartoolkit.core.NyARParam;
+import jp.nyatla.nyartoolkit.core.NyARTransMatResult;
import jp.nyatla.nyartoolkit.detector.NyARSingleDetectMarker;
import jp.nyatla.nyartoolkit.jmf.*;
import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;
@@ -103,6 +104,7 @@

class NyARBehavior extends Behavior
{
+ private NyARTransMatResult trans_mat_result=new NyARTransMatResult();
private NyARSingleDetectMarker related_nya;
private TransformGroup trgroup;
private Background back_ground;
@@ -163,8 +165,8 @@
if(raster.hasData()){
is_marker_exist=related_nya.detectMarkerLite(raster, 100);
if(is_marker_exist){
- NyARMat nymat=related_nya.getTransmationMatrix();
- double[][] src=nymat.getArray();
+ related_nya.getTransmationMatrix(this.trans_mat_result);
+ double[][] src=this.trans_mat_result.getArray();
Matrix4d matrix=new Matrix4d(
src[0][0],-src[1][0],-src[2][0],0,
-src[0][1], src[1][1], src[2][1],0,
Index: sample/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARDetectMarker.java
===================================================================
--- sample/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARDetectMarker.java (revision 0)
+++ sample/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARDetectMarker.java (revision 200)
@@ -0,0 +1,64 @@
+/**
+ * NyARSingleDetectMarkerにOpenGL向け関数を追加したもの
+ * (c)2008 A虎@nyatla.jp
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/
+ */
+package jp.nyatla.nyartoolkit.jogl.utils;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.NyARCode;
+import jp.nyatla.nyartoolkit.core.NyARParam;
+import jp.nyatla.nyartoolkit.core.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.detector.*;
+
+public class GLNyARDetectMarker extends NyARDetectMarker
+{
+ private NyARTransMatResult trans_mat_result=new NyARTransMatResult();
+ private double view_scale_factor=0.025;//#define VIEW_SCALEFACTOR 0.025 // 1.0 ARToolKit unit becomes 0.025 of my OpenGL units.
+ public GLNyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width,int i_number_of_code) throws NyARException
+ {
+ super(i_param,i_code,i_marker_width,i_number_of_code);
+ }
+ public void setScaleFactor(double i_new_value)
+ {
+ view_scale_factor=i_new_value;
+ }
+ /**
+ * @param i_index
+ * マーカーのインデックス番号を指定します。
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
+ * @param o_result
+ * 結果値を格納する配列を指定してください。double[16]以上が必要です。
+ * @throws NyARException
+ */
+ public void getCameraViewRH(int i_index,double[] o_result) throws NyARException
+ {
+ //座標を計算
+ this.getTransmationMatrix(i_index,this.trans_mat_result);
+ //行列変換
+ double[][] para=this.trans_mat_result.getArray();
+ o_result[0 + 0*4] = para[0][0]; // R1C1
+ o_result[0 + 1*4] = para[0][1]; // R1C2
+ o_result[0 + 2*4] = para[0][2];
+ o_result[0 + 3*4] = para[0][3];
+ o_result[1 + 0*4] = -para[1][0]; // R2
+ o_result[1 + 1*4] = -para[1][1];
+ o_result[1 + 2*4] = -para[1][2];
+ o_result[1 + 3*4] = -para[1][3];
+ o_result[2 + 0*4] = -para[2][0]; // R3
+ o_result[2 + 1*4] = -para[2][1];
+ o_result[2 + 2*4] = -para[2][2];
+ o_result[2 + 3*4] = -para[2][3];
+ o_result[3 + 0*4] = 0.0;
+ o_result[3 + 1*4] = 0.0;
+ o_result[3 + 2*4] = 0.0;
+ o_result[3 + 3*4] = 1.0;
+ if (view_scale_factor != 0.0) {
+ o_result[12] *= view_scale_factor;
+ o_result[13] *= view_scale_factor;
+ o_result[14] *= view_scale_factor;
+ }
+ return;
+ }
+}
Index: sample/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARSingleDetectMarker.java
===================================================================
--- sample/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARSingleDetectMarker.java (revision 196)
+++ sample/jogl/jp/nyatla/nyartoolkit/jogl/utils/GLNyARSingleDetectMarker.java (revision 200)
@@ -8,12 +8,13 @@

import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.nyartoolkit.core.NyARCode;
-import jp.nyatla.nyartoolkit.core.NyARMat;
import jp.nyatla.nyartoolkit.core.NyARParam;
+import jp.nyatla.nyartoolkit.core.NyARTransMatResult;
import jp.nyatla.nyartoolkit.detector.*;

public class GLNyARSingleDetectMarker extends NyARSingleDetectMarker
{
+ private NyARTransMatResult trans_mat_result=new NyARTransMatResult();
private double view_scale_factor=0.025;//#define VIEW_SCALEFACTOR 0.025 // 1.0 ARToolKit unit becomes 0.025 of my OpenGL units.
public GLNyARSingleDetectMarker(NyARParam i_param,NyARCode i_code,double i_marker_width) throws NyARException
{
@@ -26,32 +27,43 @@
// public static void arglCameraViewRH(const double para[3][4], GLdouble m_modelview[16], const double scale)
public double[] getCameraViewRH() throws NyARException
{
+ double[] result=new double[16];
+ getCameraViewRH(result);
+ return result;
+ }
+ /**
+ *
+ * @param o_result
+ * 結果値を格納する配列を指定してください。double[16]以上が必要です。
+ * @throws NyARException
+ */
+ public void getCameraViewRH(double[] o_result) throws NyARException
+ {
//座標を計算
- NyARMat mat=getTransmationMatrix();
+ this.getTransmationMatrix(this.trans_mat_result);
//行列変換
- double[][] para=mat.getArray();
- double[] result=new double[16];
- result[0 + 0*4] = para[0][0]; // R1C1
- result[0 + 1*4] = para[0][1]; // R1C2
- result[0 + 2*4] = para[0][2];
- result[0 + 3*4] = para[0][3];
- result[1 + 0*4] = -para[1][0]; // R2
- result[1 + 1*4] = -para[1][1];
- result[1 + 2*4] = -para[1][2];
- result[1 + 3*4] = -para[1][3];
- result[2 + 0*4] = -para[2][0]; // R3
- result[2 + 1*4] = -para[2][1];
- result[2 + 2*4] = -para[2][2];
- result[2 + 3*4] = -para[2][3];
- result[3 + 0*4] = 0.0;
- result[3 + 1*4] = 0.0;
- result[3 + 2*4] = 0.0;
- result[3 + 3*4] = 1.0;
- if (view_scale_factor != 0.0) {
- result[12] *= view_scale_factor;
- result[13] *= view_scale_factor;
- result[14] *= view_scale_factor;
- }
- return result;
+ double[][] para=this.trans_mat_result.getArray();
+ o_result[0 + 0*4] = para[0][0]; // R1C1
+ o_result[0 + 1*4] = para[0][1]; // R1C2
+ o_result[0 + 2*4] = para[0][2];
+ o_result[0 + 3*4] = para[0][3];
+ o_result[1 + 0*4] = -para[1][0]; // R2
+ o_result[1 + 1*4] = -para[1][1];
+ o_result[1 + 2*4] = -para[1][2];
+ o_result[1 + 3*4] = -para[1][3];
+ o_result[2 + 0*4] = -para[2][0]; // R3
+ o_result[2 + 1*4] = -para[2][1];
+ o_result[2 + 2*4] = -para[2][2];
+ o_result[2 + 3*4] = -para[2][3];
+ o_result[3 + 0*4] = 0.0;
+ o_result[3 + 1*4] = 0.0;
+ o_result[3 + 2*4] = 0.0;
+ o_result[3 + 3*4] = 1.0;
+ if (view_scale_factor != 0.0) {
+ o_result[12] *= view_scale_factor;
+ o_result[13] *= view_scale_factor;
+ o_result[14] *= view_scale_factor;
+ }
+ return;
}
}
Index: sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java
===================================================================
--- sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java (revision 196)
+++ sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java (revision 200)
@@ -1,7 +1,6 @@
/**
* simpleLiteと同じようなテストプログラム
- * マーカーの一致度の最低値をチェックするところを抜いたので、同じマーカーを大量に
- * 検出すると面白いことになります。
+ * 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。
* (c)2008 A虎@nyatla.jp
* airmail(at)ebony.plala.or.jp
* http://nyatla.jp/
@@ -135,6 +134,7 @@
ar_param.loadFromARFile(PARAM_FILE);
ar_param.changeSize(SCREEN_X,SCREEN_Y);
nya=new GLNyARSingleDetectMarker(ar_param,ar_code,80.0);
+ nya.setContinueMode(true);//ここをtrueにすると、transMatContinueモード(History計算)になります。
ar_code.loadFromARFile(CARCODE_FILE);
//NyARToolkit用の支援クラス
glnya=new NyARGLUtil(gl,ar_param);
@@ -177,7 +177,7 @@
//画像チェックしてマーカー探して、背景を書く
boolean is_marker_exist;
synchronized(cap_image){
- is_marker_exist=nya.detectMarkerLite(cap_image,100);
+ is_marker_exist=nya.detectMarkerLite(cap_image,110);
//背景を書く
glnya.drawBackGround(cap_image, 1.0);
}
@@ -196,9 +196,11 @@
// All other lighting and geometry goes here.
drawCube();
}
+ Thread.sleep(1);//タスク実行権限を一旦渡す
}catch(Exception e){
e.printStackTrace();
}
+
}
public void onUpdateBuffer(Buffer i_buffer)
{
Index: sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite2.java
===================================================================
--- sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite2.java (revision 0)
+++ sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite2.java (revision 200)
@@ -0,0 +1,237 @@
+/**
+ * simpleLiteの複数マーカー同時認識バージョン
+ * "Hiro"のマーカーと"人"のマーカーの混在環境で、Hiroのマーカー全てに
+ * 立方体を表示します。
+ * (c)2008 A虎@nyatla.jp
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/
+ */
+package jp.nyatla.nyartoolkit.jogl.sample;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.*;
+
+import javax.media.Buffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLCanvas;
+
+import com.sun.opengl.util.Animator;
+
+import jp.nyatla.nyartoolkit.core.NyARCode;
+
+import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;
+import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;
+import jp.nyatla.nyartoolkit.jogl.utils.*;
+
+
+public class JavaSimpleLite2 implements GLEventListener,JmfCaptureListener
+{
+ private final String CARCODE_FILE1 ="../../Data/patt.hiro";
+ private final String CARCODE_FILE2 ="../../Data/patt.kanji";
+ private final String PARAM_FILE ="../../Data/camera_para.dat";
+
+ private final static int SCREEN_X=640;
+ private final static int SCREEN_Y=480;
+ private Animator animator;
+ private GLNyARRaster_RGB cap_image;
+
+ private JmfCameraCapture capture;
+ private GL gl;
+ private NyARGLUtil glnya;
+
+
+ //NyARToolkit関係
+ private GLNyARDetectMarker nya;
+ private GLNyARParam ar_param;
+ /**
+ * 立方体を書く
+ *
+ */
+ void drawCube()
+ {
+ // Colour cube data.
+ int polyList = 0;
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmのナタデココ
+ int f, i;
+ 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}
+ };
+ 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}
+ };
+ int cube_num_faces = 6;
+ short[][] cube_faces =new short[][]{
+ {3, 2, 1, 0}, {2, 3, 7, 6}, {0, 1, 5, 4}, {3, 0, 4, 7}, {1, 2, 6, 5}, {4, 5, 6, 7}
+ };
+
+ if (polyList==0) {
+ polyList = gl.glGenLists (1);
+ gl.glNewList(polyList, GL.GL_COMPILE);
+ gl.glBegin(GL.GL_QUADS);
+ for (f = 0; f < cube_num_faces; f++)
+ for (i = 0; i < 4; i++) {
+ gl.glColor3f (cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);
+ gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ }
+ gl.glEnd();
+ gl.glColor3f(0.0f, 0.0f, 0.0f);
+ for (f = 0; f < cube_num_faces; f++) {
+ gl.glBegin (GL.GL_LINE_LOOP);
+ for (i = 0; i < 4; i++)
+ gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
+ gl.glEnd ();
+ }
+ gl.glEndList ();
+ }
+
+ gl.glPushMatrix(); // Save world coordinate system.
+ gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.
+ gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.
+ gl.glDisable(GL.GL_LIGHTING); // Just use colours.
+ gl.glCallList(polyList); // Draw the cube.
+ gl.glPopMatrix(); // Restore world coordinate system.
+
+ }
+
+
+
+ public JavaSimpleLite2()
+ {
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");
+
+
+ // 3Dを描画するコンポーネント
+ GLCanvas canvas = new GLCanvas();
+ frame.add(canvas);
+ canvas.addGLEventListener(this);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+
+ frame.setVisible(true);
+ Insets ins=frame.getInsets();
+ frame.setSize(SCREEN_X+ins.left+ins.right,SCREEN_Y+ins.top+ins.bottom);
+ canvas.setBounds(ins.left,ins.top,SCREEN_X,SCREEN_Y);
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ gl = drawable.getGL();
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ //NyARToolkitの準備
+ try{
+ //キャプチャの準備
+ capture=new JmfCameraCapture(SCREEN_X,SCREEN_Y,15f,JmfCameraCapture.PIXEL_FORMAT_RGB);
+ capture.setCaptureListener(this);
+ //NyARToolkitの準備
+ ar_param=new GLNyARParam();
+ ar_param.loadFromARFile(PARAM_FILE);
+ ar_param.changeSize(SCREEN_X,SCREEN_Y);
+
+ //ARコードを2個ロード
+ double[] width=new double[]{80.0,80.0};
+ NyARCode[] ar_codes=new NyARCode[2];
+ ar_codes[0]=new NyARCode(16,16);
+ ar_codes[0].loadFromARFile(CARCODE_FILE1);
+ ar_codes[1]=new NyARCode(16,16);
+ ar_codes[1].loadFromARFile(CARCODE_FILE2);
+ nya=new GLNyARDetectMarker(ar_param,ar_codes,width,2);
+ nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。
+ //NyARToolkit用の支援クラス
+ glnya=new NyARGLUtil(gl,ar_param);
+ //GL対応のRGBラスタオブジェクト
+ cap_image=new GLNyARRaster_RGB(gl,ar_param);
+ //キャプチャ開始
+ capture.start();
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ animator = new Animator(drawable);
+
+ animator.start();
+
+ }
+
+ public void reshape(GLAutoDrawable drawable,
+ int x, int y,
+ int width, int height)
+ {
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ gl.glViewport(0, 0, width, height);
+
+ //視体積の設定
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+ //見る位置
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ }
+
+ public void display(GLAutoDrawable drawable)
+ {
+
+ try{
+ if(!cap_image.hasData()){
+ return;
+ }
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
+ //画像チェックしてマーカー探して、背景を書く
+ int found_markers;
+ synchronized(cap_image){
+ found_markers=nya.detectMarkerLite(cap_image,110);
+ //背景を書く
+ glnya.drawBackGround(cap_image, 1.0);
+ }
+ //あったら立方体を書く
+ double[] matrix=new double[16];
+ for(int i=0;i<found_markers;i++){
+ //1番のマーカーでなければ表示しない。
+ if(nya.getARCodeIndex(i)!=0){
+ continue;
+ }
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。
+ // Projection transformation.
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadMatrixd(ar_param.getCameraFrustumRH(),0);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ // Viewing transformation.
+ gl.glLoadIdentity();
+ nya.getCameraViewRH(i,matrix);
+ gl.glLoadMatrixd(matrix,0);
+
+
+ // All other lighting and geometry goes here.
+ drawCube();
+ }
+ Thread.sleep(1);//タスク実行権限を一旦渡す
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ try{
+ synchronized(cap_image){
+ cap_image.setBuffer(i_buffer, true);
+ }
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ public void displayChanged(GLAutoDrawable drawable,
+ boolean modeChanged,
+ boolean deviceChanged) {}
+
+ public static void main(String[] args) {
+ new JavaSimpleLite2();
+ }
+}
+
Index: sample/jmf/jp/nyatla/nyartoolkit/jmf/sample/NyarToolkitLinkTest.java
===================================================================
--- sample/jmf/jp/nyatla/nyartoolkit/jmf/sample/NyarToolkitLinkTest.java (revision 196)
+++ sample/jmf/jp/nyatla/nyartoolkit/jmf/sample/NyarToolkitLinkTest.java (revision 200)
@@ -30,9 +30,10 @@
private final String CARCODE_FILE ="../../Data/patt.hiro";
private final String PARAM_FILE ="../../Data/camera_para.dat";
private JmfCameraCapture capture;
- NyARSingleDetectMarker nya;
- JmfNyARRaster_RGB raster;
-
+ private NyARSingleDetectMarker nya;
+ private JmfNyARRaster_RGB raster;
+ private NyARTransMatResult trans_mat_result=new NyARTransMatResult();
+
public NyarToolkitLinkTest() throws NyARException,NyARException
{
setTitle("JmfCaptureTest");
@@ -53,7 +54,7 @@
}


-
+
public void onUpdateBuffer(Buffer i_buffer)
{
try{
@@ -71,7 +72,8 @@
boolean is_marker_exist=nya.detectMarkerLite(raster,100);
if(is_marker_exist){
//変換行列を取得
- atm=nya.getTransmationMatrix().getArray();
+ nya.getTransmationMatrix(this.trans_mat_result);
+ atm=this.trans_mat_result.getArray();
}
//情報を画面に書く
g.drawImage(img, 32, 32,this);

Index: src/jp/nyatla/nyartoolkit/sample/RawFileTest.java
===================================================================
--- src/jp/nyatla/nyartoolkit/sample/RawFileTest.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/sample/RawFileTest.java (revision 200)
@@ -37,9 +37,6 @@
/**
* 320x240のBGRA32で記録されたRAWイメージから、1種類のパターンを認識し、
* その変換行列を1000回求め、それにかかったミリ秒時間を表示します。
- *
- *
- * @author R.iizuka
*
*/
public class RawFileTest {
@@ -70,19 +67,19 @@

//1パターンのみを追跡するクラスを作成
NyARSingleDetectMarker ar=new NyARSingleDetectMarker(ap,code,80.0);
+ NyARTransMatResult result_mat=new NyARTransMatResult();
+ ar.setContinueMode(false);
ar.detectMarkerLite(ra,100);
- ar.getTransmationMatrix();
+ ar.getTransmationMatrix(result_mat);

//マーカーを検出
- double[][] tm;
Date d2=new Date();
for(int i=0;i<1000;i++){
//変換行列を取得
ar.detectMarkerLite(ra,100);
- ar.getTransmationMatrix();
+ ar.getTransmationMatrix(result_mat);
}
Date d=new Date();
- tm=null;
System.out.println(d.getTime()-d2.getTime());
}
public static void main(String[] args)
Index: src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O1.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O1.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O1.java (revision 200)
@@ -48,11 +48,28 @@
private int height;
public NyARColorPatt_O1(int i_width,int i_height)
{
- this.width=i_width;
+ this.width =i_width;
this.height=i_height;
this.extpat=new int[i_height][i_width][3];
this.wk_pickFromRaster_ext_pat2=new int[i_height][i_width][3];
}
+// public void setSize(int i_new_width,int i_new_height)
+// {
+// int array_w=this.extpat[0].length;
+// int array_h=this.extpat.length;
+// //十分なサイズのバッファがあるか確認
+// if(array_w>=i_new_width && array_h>=i_new_height){
+// //OK 十分だ→サイズ調整のみ
+// }else{
+// //足りないよ→取り直し
+// this.wk_pickFromRaster_ext_pat2=new int[i_new_height][i_new_width][3];
+// this.extpat=new int[i_new_height][i_new_width][3];
+// }
+// this.width =i_new_width;
+// this.height=i_new_height;
+// return;
+// }
+
public int[][][] getPatArray()
{
return extpat;
@@ -76,14 +93,14 @@
* [3x3]
* @throws NyARException
*/
- private void get_cpara( double world[][], double vertex[][],double[] para) throws NyARException
+ private boolean get_cpara( double world[][], double vertex[][],double[] para) throws NyARException
{
NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );
double[][] a_array=a.getArray();
NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );
double[][] b_array=b.getArray();
double[] a_pt0,a_pt1,world_pti;
-
+
for(int i = 0; i < 4; i++ ) {
a_pt0=a_array[i*2];
a_pt1=a_array[i*2+1];
@@ -109,7 +126,9 @@
b_array[i*2+1][0]=vertex[i][1];//b->m[i*2+1] = vertex[i][1];
}
// JartkException.trap("未チェックのパス");
- a.matrixSelfInv();
+ if(!a.matrixSelfInv()){
+ return false;//逆行列を求められないので失敗
+ }

// JartkException.trap("未チェックのパス");
NyARMat c = wk_get_cpara_c;//次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );
@@ -124,6 +143,7 @@
para[2*3+0] = c_array[2*3+0][0];//para[2][0] = c->m[2*3+0];
para[2*3+1] = c_array[2*3+1][0];//para[2][1] = c->m[2*3+1];
para[2*3+2] = 1.0;//para[2][2] = 1.0;
+ return true;
}

private final double[][] wk_pickFromRaster_local=new double[4][2];
@@ -160,9 +180,11 @@
* Optimize:STEP[769->]
* @param image
* @param i_marker
+ * @return
+ * 切り出しに失敗した
* @throws Exception
*/
- public void pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
{
double d, xw, yw;
int xc, yc;
@@ -195,7 +217,10 @@
world[3][0] = 100.0;
world[3][1] = 100.0 + 10.0;*/
double[] para =wk_pickFromRaster_para; //double para[3][3];
- get_cpara( world, local, para );
+ //パターンの切り出しに失敗することもある。
+ if(!get_cpara( world, local, para )){
+ return false;
+ }
lx1 = (int)((local[0][0] - local[1][0])*(local[0][0] - local[1][0])+ (local[0][1] - local[1][1])*(local[0][1] - local[1][1]));
lx2 = (int)((local[2][0] - local[3][0])*(local[2][0] - local[3][0])+ (local[2][1] - local[3][1])*(local[2][1] - local[3][1]));
ly1 = (int)((local[1][0] - local[2][0])*(local[1][0] - local[2][0])+ (local[1][1] - local[2][1])*(local[1][1] - local[2][1]));
@@ -294,6 +319,6 @@
}
}
/*</Optimize>*/
- return;
+ return true;
}
}
\ No newline at end of file
Index: src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O2.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O2.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O2.java (revision 200)
@@ -53,6 +53,22 @@
this.extpat=new int[i_height][i_width][3];
this.wk_pickFromRaster_ext_pat2=new int[i_height][i_width][3];
}
+// public void setSize(int i_new_width,int i_new_height)
+// {
+// int array_w=this.extpat[0].length;
+// int array_h=this.extpat.length;
+// //十分なサイズのバッファがあるか確認
+// if(array_w>=i_new_width && array_h>=i_new_height){
+// //OK 十分だ→サイズ調整のみ
+// }else{
+// //足りないよ→取り直し
+// this.wk_pickFromRaster_ext_pat2=new int[i_new_height][i_new_width][3];
+// this.extpat=new int[i_new_height][i_new_width][3];
+// }
+// this.width =i_new_width;
+// this.height=i_new_height;
+// return;
+// }
public int[][][] getPatArray()
{
return extpat;
@@ -69,71 +85,64 @@
private final NyARMat wk_get_cpara_b=new NyARMat(8,1);
// private final NyARMat wk_get_cpara_c=new NyARMat(8,1);
/**
- *
* @param world
* @param vertex
- * @param para
- * [3x3]
- * @throws NyARException
- */
- /**
- * @param world
- * @param vertex
* @param o_para
* @throws NyARException
*/
- private void get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException
+ private boolean get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException
{
double world[][]=this.wk_pickFromRaster_world;
- NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );
- double[][] a_array=a.getArray();
- NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );
- double[][] b_array=b.getArray();
- double[] a_pt0,a_pt1,world_pti;
-
- for(int i = 0; i < 4; i++ ) {
- a_pt0=a_array[i*2];
- a_pt1=a_array[i*2+1];
- world_pti=world[i];
-
- a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];
- a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];
- a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;
- a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;
- a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;
- a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;
- a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6] = -world[i][0] * vertex[i][0];
- a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7] = -world[i][1] * vertex[i][0];
- a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;
- a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;
- a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;
- a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];
- a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];
- a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;
- a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];
- a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];
- b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];
- b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];
- }
-// JartkException.trap("未チェックのパス");
- a.matrixSelfInv();
-
-// JartkException.trap("未チェックのパス");
-// NyARMat c = wk_get_cpara_c;//次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );
-// double[][] c_array=c.getArray();
+ NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );
+ double[][] a_array=a.getArray();
+ NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );
+ double[][] b_array=b.getArray();
+ double[] a_pt0,a_pt1,world_pti;

- o_para.matrixMul(a, b);
-// para[0*3+0] = c_array[0*3+0][0];//para[i][0] = c->m[i*3+0];
-// para[0*3+1] = c_array[0*3+1][0];//para[i][1] = c->m[i*3+1];
-// para[0*3+2] = c_array[0*3+2][0];//para[i][2] = c->m[i*3+2];
-// para[1*3+0] = c_array[1*3+0][0];//para[i][0] = c->m[i*3+0];
-// para[1*3+1] = c_array[1*3+1][0];//para[i][1] = c->m[i*3+1];
-// para[i*3+2] = c_array[1*3+2][0];//para[i][2] = c->m[i*3+2];
-// para[2*3+0] = c_array[2*3+0][0];//para[2][0] = c->m[2*3+0];
-// para[2*3+1] = c_array[2*3+1][0];//para[2][1] = c->m[2*3+1];
-// para[2*3+2] = 1.0;//para[2][2] = 1.0;
-
+ for(int i = 0; i < 4; i++ ) {
+ a_pt0=a_array[i*2];
+ a_pt1=a_array[i*2+1];
+ world_pti=world[i];

+ a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];
+ a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];
+ a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;
+ a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;
+ a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;
+ a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;
+ a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6] = -world[i][0] * vertex[i][0];
+ a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7] = -world[i][1] * vertex[i][0];
+ a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;
+ a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;
+ a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;
+ a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];
+ a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];
+ a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;
+ a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];
+ a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];
+ b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];
+ b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];
+ }
+// JartkException.trap("未チェックのパス");
+ if(!a.matrixSelfInv()){
+ return false;
+ }
+
+// JartkException.trap("未チェックのパス");
+// NyARMat c = wk_get_cpara_c;//次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );
+// double[][] c_array=c.getArray();
+
+ o_para.matrixMul(a, b);
+// para[0*3+0] = c_array[0*3+0][0];//para[i][0] = c->m[i*3+0];
+// para[0*3+1] = c_array[0*3+1][0];//para[i][1] = c->m[i*3+1];
+// para[0*3+2] = c_array[0*3+2][0];//para[i][2] = c->m[i*3+2];
+// para[1*3+0] = c_array[1*3+0][0];//para[i][0] = c->m[i*3+0];
+// para[1*3+1] = c_array[1*3+1][0];//para[i][1] = c->m[i*3+1];
+// para[i*3+2] = c_array[1*3+2][0];//para[i][2] = c->m[i*3+2];
+// para[2*3+0] = c_array[2*3+0][0];//para[2][0] = c->m[2*3+0];
+// para[2*3+1] = c_array[2*3+1][0];//para[2][1] = c->m[2*3+1];
+// para[2*3+2] = 1.0;//para[2][2] = 1.0;
+ return true;
}

// private final double[] wk_pickFromRaster_para=new double[9];//[3][3];
@@ -173,7 +182,7 @@
* @param i_marker
* @throws Exception
*/
- public void pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
{
NyARMat cpara=this.wk_pickFromRaster_cpara;
//localの計算
@@ -232,7 +241,9 @@
}

//cparaの計算
- get_cpara(local_0,local_1,cpara);
+ if(!get_cpara(local_0,local_1,cpara)){
+ return false;
+ }

int img_x=image.getWidth();
int img_y=image.getHeight();
@@ -307,6 +318,6 @@
extpat_j_i[2]=(ext_pat2_j_i[2] / xdiv_x_ydiv);//ext_pat[j][i][2] = (byte)(ext_pat2[j][i][2] / (xdiv*ydiv));
}
}
- return;
+ return true;
}
}
\ No newline at end of file
Index: src/jp/nyatla/nyartoolkit/core/NyARColorPatt.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARColorPatt.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARColorPatt.java (revision 200)
@@ -36,11 +36,41 @@

public interface NyARColorPatt
{
+// 消すかも。
+// /**
+// * カラーパターンのサイズを変更します。
+// * 変更を行うと、既にgetPatArrayで参照中の配列内容は不定になり、インスタンスのパラメータは初期状態に戻ります。
+// * @param i_new_width
+// * 新しいパターン幅
+// * @param i_new_height
+// * 新しいパターン高
+// */
+// public void setSize(int i_new_width,int i_new_height);
+ /**
+ * カラーパターンの幅をピクセル値で返します。
+ * @return
+ */
public int getWidth();
+ /**
+ * カラーパターンの高さをピクセル値で返します。
+ * @return
+ */
public int getHeight();
+ /**
+ * カメラパターンを格納した配列への参照値を返します。
+ * 配列は最低でも[height][wight][3]のサイズを持ちますが、
+ * 配列のlengthとwidth,heightの数は一致しないことがあります。
+ * setSize関数を実行すると、以前に呼び出されたgetPatArrayが返した値は不定になります。
+ * @return
+ */
public int[][][] getPatArray();
- public void pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException;
-}
-
-
-
+ /**
+ * ラスタイメージからi_marker部分のカラーパターンを抽出して、保持します。
+ * @param image
+ * @param i_marker
+ * @return
+ * ラスターの取得に成功するとTRUE/失敗するとFALSE
+ * @throws NyARException
+ */
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException;
+}
\ No newline at end of file
Index: src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O3.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O3.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARColorPatt_O3.java (revision 200)
@@ -54,6 +54,21 @@
this.height=i_height;
this.extpat=new int[i_height][i_width][3];
}
+// public void setSize(int i_new_width,int i_new_height)
+// {
+// int array_w=this.extpat[0].length;
+// int array_h=this.extpat.length;
+// //十分なサイズのバッファがあるか確認
+// if(array_w>=i_new_width && array_h>=i_new_height){
+// //OK 十分だ→サイズ調整のみ
+// }else{
+// //足りないよ→取り直し
+// this.extpat=new int[i_new_height][i_new_width][3];
+// }
+// this.width =i_new_width;
+// this.height=i_new_height;
+// return;
+// }
public int[][][] getPatArray()
{
return extpat;
@@ -70,59 +85,50 @@
private final NyARMat wk_get_cpara_b=new NyARMat(8,1);

/**
- *
* @param world
* @param vertex
- * @param para
- * [3x3]
- * @throws NyARException
- */
- /**
- * @param world
- * @param vertex
* @param o_para
* @throws NyARException
*/
- private void get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException
+ private boolean get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException
{
double world[][]=this.wk_pickFromRaster_world;
- NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );
- double[][] a_array=a.getArray();
- NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );
- double[][] b_array=b.getArray();
- double[] a_pt0,a_pt1,world_pti;
-
- for(int i = 0; i < 4; i++ ) {
- a_pt0=a_array[i*2];
- a_pt1=a_array[i*2+1];
- world_pti=world[i];
-
- a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];
- a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];
- a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;
- a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;
- a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;
- a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;
- a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6] = -world[i][0] * vertex[i][0];
- a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7] = -world[i][1] * vertex[i][0];
- a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;
- a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;
- a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;
- a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];
- a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];
- a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;
- a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];
- a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];
- b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];
- b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];
- }
- a.matrixSelfInv();
-
+ NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );
+ double[][] a_array=a.getArray();
+ NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );
+ double[][] b_array=b.getArray();
+ double[] a_pt0,a_pt1,world_pti;

- o_para.matrixMul(a, b);
+ for(int i = 0; i < 4; i++ ) {
+ a_pt0=a_array[i*2];
+ a_pt1=a_array[i*2+1];
+ world_pti=world[i];

-
+ a_pt0[0]=world_pti[0];//a->m[i*16+0] = world[i][0];
+ a_pt0[1]=world_pti[1];//a->m[i*16+1] = world[i][1];
+ a_pt0[2]=1.0;//a->m[i*16+2] = 1.0;
+ a_pt0[3]=0.0;//a->m[i*16+3] = 0.0;
+ a_pt0[4]=0.0;//a->m[i*16+4] = 0.0;
+ a_pt0[5]=0.0;//a->m[i*16+5] = 0.0;
+ a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6] = -world[i][0] * vertex[i][0];
+ a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7] = -world[i][1] * vertex[i][0];
+ a_pt1[0]=0.0;//a->m[i*16+8] = 0.0;
+ a_pt1[1]=0.0;//a->m[i*16+9] = 0.0;
+ a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;
+ a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];
+ a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];
+ a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;
+ a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];
+ a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];
+ b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];
+ b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];
+ }
+ if(!a.matrixSelfInv()){
+ return false;
+ }

+ o_para.matrixMul(a, b);
+ return true;
}

// private final double[] wk_pickFromRaster_para=new double[9];//[3][3];
@@ -160,7 +166,7 @@
* @param i_marker
* @throws Exception
*/
- public void pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
+ public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
{
NyARMat cpara=this.wk_pickFromRaster_cpara;
//localの計算
@@ -219,10 +225,12 @@
}

//cparaの計算
- get_cpara(local_0,local_1,cpara);
+ if(!get_cpara(local_0,local_1,cpara)){
+ return false;
+ }
updateExtpat(image,cpara,xdiv2,ydiv2);

- return;
+ return true;
}
//かなり大きいワークバッファを取るな…。
private double[] wk_updateExtpat_para00_xw;
Index: src/jp/nyatla/nyartoolkit/core/NyARTransRot.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARTransRot.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARTransRot.java (revision 200)
@@ -15,12 +15,12 @@
* @throws NyARException
*/
public double modifyMatrix(double trans[],double vertex[][], double pos2d[][]) throws NyARException;
- public void initRot(NyARSquare marker_info,int i_direction) throws NyARException;
+ public void initRot(NyARSquare marker_info,int i_direction) throws NyARException;
+ public void initRotByPrevResult(NyARTransMatResult i_prev_result);
}

/**
* NyARTransRot派生クラスで共通に使いそうな関数類をまとめたもの。
- * @author atla
*
*/
abstract class NyARTransRot_OptimizeCommon implements NyARTransRot
@@ -28,6 +28,24 @@
protected final int number_of_vertex;
protected final double[] array=new double[9];
protected final NyARParam cparam;
+ public final void initRotByPrevResult(NyARTransMatResult i_prev_result)
+ {
+ double[][] prev_array=i_prev_result.getArray();
+ double[] pt;
+ final double[] L_rot=this.array;
+ pt=prev_array[0];
+ L_rot[0*3+0]=pt[0];
+ L_rot[0*3+1]=pt[1];
+ L_rot[0*3+2]=pt[2];
+ pt=prev_array[1];
+ L_rot[1*3+0]=pt[0];
+ L_rot[1*3+1]=pt[1];
+ L_rot[1*3+2]=pt[2];
+ pt=prev_array[2];
+ L_rot[2*3+0]=pt[0];
+ L_rot[2*3+1]=pt[1];
+ L_rot[2*3+2]=pt[2];
+ }
public final double[] getArray()
{
return this.array;
@@ -361,18 +379,20 @@
sinc = Math.sin(c);
cosc = Math.cos(c);
//Optimize
- double CACA,SASA,SACA,SASB,CASB;
- CACA=cosa*cosa;
- SASA=sina*sina;
- SACA=sina*cosa;
- SASB=sina*sinb;
- CASB=cosa*sinb;
+ double CACA,SASA,SACA,SASB,CASB,SACACB;
+ CACA =cosa*cosa;
+ SASA =sina*sina;
+ SACA =sina*cosa;
+ SASB =sina*sinb;
+ CASB =cosa*sinb;
+ SACACB=SACA*cosb;
+

- o_rot[0] = CACA*cosb*cosc+SASA*cosc+SACA*cosb*sinc-SACA*sinc;
- o_rot[1] = -CACA*cosb*sinc-SASA*sinc+SACA*cosb*cosc-SACA*cosc;
+ o_rot[0] = CACA*cosb*cosc+SASA*cosc+SACACB*sinc-SACA*sinc;
+ o_rot[1] = -CACA*cosb*sinc-SASA*sinc+SACACB*cosc-SACA*cosc;
o_rot[2] = CASB;
- o_rot[3] = SACA*cosb*cosc-SACA*cosc+SASA*cosb*sinc+CACA*sinc;
- o_rot[4] = -SACA*cosb*sinc+SACA*sinc+SASA*cosb*cosc+CACA*cosc;
+ o_rot[3] = SACACB*cosc-SACA*cosc+SASA*cosb*sinc+CACA*sinc;
+ o_rot[4] = -SACACB*sinc+SACA*sinc+SASA*cosb*cosc+CACA*cosc;
o_rot[5] = SASB;
o_rot[6] = -CASB*cosc-SASB*sinc;
o_rot[7] = CASB*sinc-SASB*cosc;
Index: src/jp/nyatla/nyartoolkit/core/NyARMat.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARMat.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARMat.java (revision 200)
@@ -50,8 +50,16 @@
* 返された配列のサイズを行列の大きさとして使わないこと!
*
*/
- private double[][] m;
+ protected double[][] m;
private int clm,row;
+ /**
+ * デフォルトコンストラクタは機能しません。
+ * @throws NyARException
+ */
+ protected NyARMat() throws NyARException
+ {
+ throw new NyARException();
+ }
public NyARMat(int i_row,int i_clm)
{
m=new double[i_row][i_clm];
@@ -97,6 +105,25 @@
}
}
}
+ /**
+ * i_copy_fromの内容を自分自身にコピーします。
+ * 高さ・幅は同一で無いと失敗します。
+ * @param i_copy_from
+ */
+ public void copyFrom(NyARMat i_copy_from)throws NyARException
+ {
+ //サイズ確認
+ if(this.row!=i_copy_from.row ||this.clm!=i_copy_from.clm)
+ {
+ throw new NyARException();
+ }
+ //値コピー
+ for(int r=this.row-1;r>=0;r--){
+ for(int c=this.clm-1;c>=0;c--){
+ this.m[r][c]=i_copy_from.m[r][c];
+ }
+ }
+ }

public double[][] getArray()
{
@@ -132,15 +159,18 @@
}
}
private int[] wk_nos_matrixSelfInv=new int[50];
- private final static double matrixSelfInv_epsl=1.0e-10;
+// private final static double matrixSelfInv_epsl=1.0e-10;
/**
* i_targetを逆行列に変換する。arMatrixSelfInv()と、arMatrixSelfInv_minv()関数を合成してあります。
* OPTIMIZE STEP[485->422]
* @param i_target
* 逆行列にする行列
+ * @return
+ * 逆行列があればTRUE/無ければFALSE
+ *
* @throws NyARException
*/
- public void matrixSelfInv() throws NyARException
+ public boolean matrixSelfInv() throws NyARException
{
double[][] ap=this.m;
int dimen=this.row;
@@ -157,7 +187,7 @@
throw new NyARException();
case 1:
ap[0][0]=1.0/ap[0][0];//*ap = 1.0 / (*ap);
- return;/* 1 dimension */
+ return true;/* 1 dimension */
}

for(int n = 0; n < dimen ; n++){
@@ -180,8 +210,10 @@
ip = i;
}
}
- if (p <= matrixSelfInv_epsl){
- return;
+// if (p <= matrixSelfInv_epsl){
+ if(p==0.0){
+ return false;
+// throw new NyARException();
}

nwork = nos[ip];
@@ -227,7 +259,7 @@
ap_i[n]=work;//*wbp = work;
}
}
- return;
+ return true;
}
/**
* sourceの転置行列をdestに得る。arMatrixTrans()の代替品
Index: src/jp/nyatla/nyartoolkit/core/NyARTransMatResult.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARTransMatResult.java (revision 0)
+++ src/jp/nyatla/nyartoolkit/core/NyARTransMatResult.java (revision 200)
@@ -0,0 +1,93 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.core;
+
+import jp.nyatla.nyartoolkit.*;
+/**
+ * NyARTransMat戻り値専用のNyARMat
+ *
+ */
+public class NyARTransMatResult extends NyARMat
+{
+ private boolean has_value=false;
+ public NyARTransMatResult()
+ {
+ super(3,4);
+ }
+ /**
+ * この関数は使えません。
+ * @param i_row
+ * @param i_clm
+ * @throws NyARException
+ */
+ public NyARTransMatResult(int i_row,int i_clm) throws NyARException
+ {
+ super();//ここで例外発生
+ }
+ /**
+ * パラメータで変換行列を更新します。
+ * @param i_rot
+ * @param i_off
+ * @param i_trans
+ */
+ public void updateMatrixValue(NyARTransRot i_rot,double[] i_off,double[] i_trans)
+ {
+ double[] pa;
+ double[] rot=i_rot.getArray();
+
+ pa=this.m[0];
+ pa[0] = rot[0*3+0];
+ pa[1] = rot[0*3+1];
+ pa[2] = rot[0*3+2];
+ pa[3] = rot[0*3+0]*i_off[0] + rot[0*3+1]*i_off[1] + rot[0*3+2]*i_off[2] + i_trans[0];
+
+ pa=this.m[1];
+ pa[0] = rot[1*3+0];
+ pa[1] = rot[1*3+1];
+ pa[2] = rot[1*3+2];
+ pa[3] = rot[1*3+0]*i_off[0] + rot[1*3+1]*i_off[1] + rot[1*3+2]*i_off[2] + i_trans[1];
+
+ pa=this.m[2];
+ pa[0] = rot[2*3+0];
+ pa[1] = rot[2*3+1];
+ pa[2] = rot[2*3+2];
+ pa[3] = rot[2*3+0]*i_off[0] + rot[2*3+1]*i_off[1] + rot[2*3+2]*i_off[2] + i_trans[2];
+
+
+ this.has_value=true;
+ return;
+ }
+ public void copyFrom(NyARTransMatResult i_from) throws NyARException
+ {
+ super.copyFrom(i_from);
+ this.has_value=i_from.has_value;
+ }
+ public boolean hasValue()
+ {
+ return this.has_value;
+ }
+}
Index: src/jp/nyatla/nyartoolkit/core/NyARTransMat_O1.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARTransMat_O1.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARTransMat_O1.java (revision 200)
@@ -41,12 +41,13 @@

private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT=5;//#define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5
private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR=1.0;//#define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0
+ private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR=1.0;
private final static int P_MAX=10;//頂点の数(4で十分だけどなんとなく10)//#define P_MAX 500
private final static int NUMBER_OF_VERTEX=4;//処理対象の頂点数
private final NyARTransRot transrot;
private final double[] center={0.0,0.0};
private final NyARParam param;
- private final NyARMat result_mat=new NyARMat(3,4);
+// private final NyARMat result_mat=new NyARMat(3,4);
public NyARTransMat_O1(NyARParam i_param)throws NyARException
{
param=i_param;
@@ -58,10 +59,10 @@
center[0]=i_x;
center[1]=i_x;
}
- public NyARMat getTransformationMatrix()
- {
- return result_mat;
- }
+// public NyARMat getTransformationMatrix()
+// {
+// return result_mat;
+// }

private final double[][] wk_transMat_pos3d=new double[P_MAX][3];//pos3d[P_MAX][3];
private final double[][] wk_transMat_ppos2d=new double[4][2];
@@ -74,11 +75,15 @@
* @param square
* 計算対象のNyARSquareオブジェクト
* @param i_direction
- * @param width
+ * マーカーの方向
+ * @param i_width
+ * マーカーのサイズ(mm)
+ * @param o_result_conv
+ * 変換行列を受け取るオブジェクトを指定します。
* @return
* @throws NyARException
*/
- public double transMat( NyARSquare square,int i_direction, double width)throws NyARException
+ public double transMat(NyARSquare square,int i_direction,double i_width,NyARTransMatResult o_result_conv)throws NyARException
{
double[][] ppos2d=wk_transMat_ppos2d;
double[][] ppos3d=wk_transMat_ppos3d;
@@ -100,14 +105,14 @@
ppos2d[2][1] = square.sqvertex[(6-dir)%4][1];
ppos2d[3][0] = square.sqvertex[(7-dir)%4][0];
ppos2d[3][1] = square.sqvertex[(7-dir)%4][1];
- ppos3d[0][0] = center[0] - width/2.0;
- ppos3d[0][1] = center[1] + width/2.0;
- ppos3d[1][0] = center[0] + width/2.0;
- ppos3d[1][1] = center[1] + width/2.0;
- ppos3d[2][0] = center[0] + width/2.0;
- ppos3d[2][1] = center[1] - width/2.0;
- ppos3d[3][0] = center[0] - width/2.0;
- ppos3d[3][1] = center[1] - width/2.0;
+ ppos3d[0][0] = center[0] - i_width/2.0;
+ ppos3d[0][1] = center[1] + i_width/2.0;
+ ppos3d[1][0] = center[0] + i_width/2.0;
+ ppos3d[1][1] = center[1] + i_width/2.0;
+ ppos3d[2][0] = center[0] + i_width/2.0;
+ ppos3d[2][1] = center[1] - i_width/2.0;
+ ppos3d[3][0] = center[0] - i_width/2.0;
+ ppos3d[3][1] = center[1] - i_width/2.0;

//arGetTransMat3の前段処理(pos3dとoffを初期化)
arGetTransMat3_initPos3d(ppos3d,pos3d,off);
@@ -115,13 +120,98 @@


for(int i=0;i<AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++ ) {
- err = arGetTransMat3(ppos2d, pos3d,off);
+ err = arGetTransMat3(ppos2d, pos3d,off,o_result_conv);
if( err < AR_GET_TRANS_MAT_MAX_FIT_ERROR ){
break;
}
}
+
return err;
}
+ /**
+ * transMatContinue用のワーク
+ */
+ private final NyARTransMatResult wk_transMatContinue_result=new NyARTransMatResult();
+ /**
+ * double arGetTransMatCont( ARMarkerInfo *marker_info, double prev_conv[3][4],double center[2], double width, double conv[3][4] )
+ *
+ * @param i_square
+ * @param i_direction
+ * マーカーの方位を指定する。
+ * @param i_width
+ * @param io_result_conv
+ * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。
+ * 履歴を持たない場合は、transMatと同じ処理を行う。
+ * @return
+ * @throws NyARException
+ */
+ public double transMatContinue(NyARSquare i_square,int i_direction, double i_width,NyARTransMatResult io_result_conv)throws NyARException
+ {
+ //io_result_convが初期値なら、transMatで計算する。
+ if(!io_result_conv.hasValue()){
+ return this.transMat(i_square, i_direction, i_width, io_result_conv);
+ }
+
+
+
+ double err1,err2;
+ int i,dir;
+ double[][] ppos2d=wk_transMat_ppos2d;
+ double[][] ppos3d=wk_transMat_ppos3d;
+ double[] off =wk_transMat_off;
+ double[][] pos3d=wk_transMat_pos3d;
+
+ //arGetTransMatContSub計算部分
+ transrot.initRotByPrevResult(io_result_conv);
+
+ dir = i_direction;
+ ppos2d[0][0] = i_square.sqvertex[(4-dir)%4][0];
+ ppos2d[0][1] = i_square.sqvertex[(4-dir)%4][1];
+ ppos2d[1][0] = i_square.sqvertex[(5-dir)%4][0];
+ ppos2d[1][1] = i_square.sqvertex[(5-dir)%4][1];
+ ppos2d[2][0] = i_square.sqvertex[(6-dir)%4][0];
+ ppos2d[2][1] = i_square.sqvertex[(6-dir)%4][1];
+ ppos2d[3][0] = i_square.sqvertex[(7-dir)%4][0];
+ ppos2d[3][1] = i_square.sqvertex[(7-dir)%4][1];
+ ppos3d[0][0] = center[0] - i_width/2.0;
+ ppos3d[0][1] = center[1] + i_width/2.0;
+ ppos3d[1][0] = center[0] + i_width/2.0;
+ ppos3d[1][1] = center[1] + i_width/2.0;
+ ppos3d[2][0] = center[0] + i_width/2.0;
+ ppos3d[2][1] = center[1] - i_width/2.0;
+ ppos3d[3][0] = center[0] - i_width/2.0;
+ ppos3d[3][1] = center[1] - i_width/2.0;
+
+ //arGetTransMat3の前段処理(pos3dとoffを初期化)
+ arGetTransMat3_initPos3d(ppos3d,pos3d,off);
+
+ err1=err2=-1;
+ for( i = 0; i < AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++ ) {
+ err1 = arGetTransMat3(ppos2d, pos3d,off,io_result_conv);
+ if( err1 < AR_GET_TRANS_MAT_MAX_FIT_ERROR ){
+ //十分な精度を達成できたらブレーク
+ break;
+ }
+ }
+
+ //エラー値が許容範囲でなければTransMatをやり直し
+ if(err1>AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR ) {
+ NyARTransMatResult result2=this.wk_transMatContinue_result;
+ //transMatを実行
+ transrot.initRot(i_square,i_direction);
+ err2 = transMat(i_square,i_direction,i_width,result2);
+ //transmMatここまで
+ if(err2<err1){
+ io_result_conv.copyFrom(result2);
+ err1 = err2;
+ }
+ }
+ return err1;
+ }
+
+
+
+
private final double[] wk_arGetTransMat3_initPos3d_pmax=new double[3];
private final double[] wk_arGetTransMat3_initPos3d_pmin=new double[3];
/**
@@ -155,6 +245,10 @@
if( i_ppos3d[i][1] < pmin[1] ){
pmin[1] = i_ppos3d[i][1];
}
+ /* オリジナルでもコメントアウト
+ if( ppos3d[i][2] > pmax[2] ) pmax[2] = ppos3d[i][2];
+ if( ppos3d[i][2] < pmin[2] ) pmin[2] = ppos3d[i][2];
+ */
}
o_off[0] = -(pmax[0] + pmin[0]) / 2.0;
o_off[1] = -(pmax[1] + pmin[1]) / 2.0;
@@ -186,14 +280,22 @@
private final double arGetTransMat3(
double ppos2d[][],
final double i_pos3d[][],
- final double i_off[])throws NyARException{
+ final double i_off[],
+ NyARTransMatResult o_result_conv)throws NyARException{
+
+ double ret;
+ ret = arGetTransMatSub(ppos2d,i_pos3d,i_off,o_result_conv);

- double ret;
- ret = arGetTransMatSub(ppos2d, i_pos3d);
- double[][] conv=result_mat.getArray();
- conv[0][3] = conv[0][0]*i_off[0] + conv[0][1]*i_off[1] + conv[0][2]*i_off[2] + conv[0][3];
- conv[1][3] = conv[1][0]*i_off[0] + conv[1][1]*i_off[1] + conv[1][2]*i_off[2] + conv[1][3];
- conv[2][3] = conv[2][0]*i_off[0] + conv[2][1]*i_off[1] + conv[2][2]*i_off[2] + conv[2][3];
+// double[][] conv=o_result_conv.getArray();
+// double[] rot=transrot.getArray();
+// for(int i=0;i<3;i++){
+// conv[i][0] = rot[i*3+0];
+// conv[i][1] = rot[i*3+1];
+// conv[i][2] = rot[i*3+2];
+// }
+// conv[0][3] = conv[0][0]*i_off[0] + conv[0][1]*i_off[1] + conv[0][2]*i_off[2] + conv[0][3];
+// conv[1][3] = conv[1][0]*i_off[0] + conv[1][1]*i_off[1] + conv[1][2]*i_off[2] + conv[1][3];
+// conv[2][3] = conv[2][0]*i_off[0] + conv[2][1]*i_off[1] + conv[2][2]*i_off[2] + conv[2][3];
return ret;
}
private final NyARMat wk_arGetTransMatSub_mat_a=new NyARMat(NUMBER_OF_VERTEX*2,3);
@@ -211,14 +313,12 @@
/**
* static double arGetTransMatSub( double rot[3][3], double ppos2d[][2],double pos3d[][3], int num, double conv[3][4],double *dist_factor, double cpara[3][4] )
* Optimize:2008.04.20:STEP[1033→1004]
- * @param rot
- * @param ppos2d
- * @param pos3d
- * @param num
+ * @param i_ppos2d
+ * @param i_pos3d
* @return
* @throws NyARException
*/
- private final double arGetTransMatSub(double i_ppos2d[][],double i_pos3d[][]) throws NyARException
+ private final double arGetTransMatSub(double i_ppos2d[][],double i_pos3d[][],double[] i_off,NyARTransMatResult o_result_conv) throws NyARException
{
double[][] pos2d=wk_arGetTransMatSub_pos2d;
double cpara[]=param.get34Array();
@@ -314,30 +414,33 @@
c_array[x2][0] =wz * po2d_pt[0]- cpara[0*4+0]*wx - cpara[0*4+1]*wy - cpara[0*4+2]*wz;//mat_c->m[j*2+0] = wz * pos2d[j][0]- cpara[0][0]*wx - cpara[0][1]*wy - cpara[0][2]*wz;
c_array[x2+1][0]=wz * po2d_pt[1]- cpara[1*4+1]*wy - cpara[1*4+2]*wz;//mat_c->m[j*2+1] = wz * pos2d[j][1]- cpara[1][1]*wy - cpara[1][2]*wz;
}
-// JartkException.trap("未チェックのパス");{
+
mat_d.matrixMul(mat_b, mat_a );
mat_e.matrixMul(mat_b, mat_c );
mat_d.matrixSelfInv();
mat_f.matrixMul(mat_d, mat_e );
-// }
+
trans[0] = f_array[0][0];//trans[0] = mat_f->m[0];
trans[1] = f_array[1][0];
trans[2] = f_array[2][0];//trans[2] = mat_f->m[2];


ret = transrot.modifyMatrix(trans, i_pos3d, pos2d);
- double[][] conv=result_mat.getArray();
- for( i = 2; i >=0; i-- ) {//<Optimize/>for( j = 0; j < 3; j++ ) {
- //<Optimize>
- //for( i = 0; i < 3; i++ ){
- // conv[j][i] = rot[j][i];
- //}
- conv[i][0] = rot[i*3+0];
- conv[i][1] = rot[i*3+1];
- conv[i][2] = rot[i*3+2];
- //</Optimize>
- conv[i][3] = trans[i];
- }
+ //変換行列を保存
+ o_result_conv.updateMatrixValue(this.transrot,i_off,trans);
+
+// double[][] conv=o_result_conv.getArray();
+// for( i = 2; i >=0; i-- ) {//<Optimize/>for( j = 0; j < 3; j++ ) {
+// //<Optimize>
+// //for( i = 0; i < 3; i++ ){
+// // conv[j][i] = rot[j][i];
+// //}
+// conv[i][0] = rot[i*3+0];
+// conv[i][1] = rot[i*3+1];
+// conv[i][2] = rot[i*3+2];
+// //</Optimize>
+// conv[i][3] = trans[i];
+// }
return ret;
}
}
Index: src/jp/nyatla/nyartoolkit/core/NyARTransMat.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARTransMat.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARTransMat.java (revision 200)
@@ -33,17 +33,18 @@



-import jp.nyatla.nyartoolkit.NyARException;

+import jp.nyatla.nyartoolkit.*;

+
/**
- * This class calculates ARMatrix from square information and holds it.
+ * This class calculates ARMatrix from square information.
* --
- * 変換行列を計算して、結果を保持するクラス。
+ * 変換行列を計算するクラス。
*
*/
public interface NyARTransMat{
public void setCenter(double i_x,double i_y);
- public NyARMat getTransformationMatrix();
- public double transMat( NyARSquare square,int i_direction, double width)throws NyARException;
+ public double transMat(NyARSquare i_square,int i_direction, double i_width,NyARTransMatResult o_result)throws NyARException;
+ public double transMatContinue(NyARSquare i_square,int i_direction, double i_width,NyARTransMatResult io_result_conv)throws NyARException;
}
Index: src/jp/nyatla/nyartoolkit/core/NyARTransMat_O2.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARTransMat_O2.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARTransMat_O2.java (revision 200)
@@ -38,19 +38,23 @@



+
+
/**
* This class calculates ARMatrix from square information and holds it.
* --
* 変換行列を計算して、結果を保持するクラス。
*
*/
-public class NyARTransMat_O2 implements NyARTransMat{
+public class NyARTransMat_O2 implements NyARTransMat
+{
private final static int AR_FITTING_TO_IDEAL=0;//#define AR_FITTING_TO_IDEAL 0
private final static int AR_FITTING_TO_INPUT=1;//#define AR_FITTING_TO_INPUT 1
private final static int arFittingMode =AR_FITTING_TO_INPUT;

private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT=5;//#define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5
private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR=1.0;//#define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0
+ private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR=1.0;
private final static int P_MAX=10;//頂点の数(4で十分だけどなんとなく10)//#define P_MAX 500
private final static int NUMBER_OF_VERTEX=4;//処理対象の頂点数
private final NyARTransRot transrot;
@@ -73,16 +77,46 @@
return result_mat;
}

+ /**
+ * transMat関数の初期化関数を分離したものです。
+ * @param square
+ * @param i_direction
+ * @param i_width
+ * @param o_ppos2d
+ * @param o_ppos3d
+ */
+ private final void init_transMat_ppos(NyARSquare square,int i_direction,double i_width,double[][] o_ppos2d,double[][] o_ppos3d)
+ {
+ o_ppos2d[0][0] = square.sqvertex[(4-i_direction)%4][0];
+ o_ppos2d[0][1] = square.sqvertex[(4-i_direction)%4][1];
+ o_ppos2d[1][0] = square.sqvertex[(5-i_direction)%4][0];
+ o_ppos2d[1][1] = square.sqvertex[(5-i_direction)%4][1];
+ o_ppos2d[2][0] = square.sqvertex[(6-i_direction)%4][0];
+ o_ppos2d[2][1] = square.sqvertex[(6-i_direction)%4][1];
+ o_ppos2d[3][0] = square.sqvertex[(7-i_direction)%4][0];
+ o_ppos2d[3][1] = square.sqvertex[(7-i_direction)%4][1];
+
+ double c0,c1,w_2;
+ c0=center[0];
+ c1=center[1];
+ w_2 =i_width/2.0;
+
+ o_ppos3d[0][0] = c0 - w_2;//center[0] - w/2.0;
+ o_ppos3d[0][1] = c1 + w_2;//center[1] + w/2.0;
+ o_ppos3d[1][0] = c0 + w_2;//center[0] + w/2.0;
+ o_ppos3d[1][1] = c1 + w_2;//center[1] + w/2.0;
+ o_ppos3d[2][0] = c0 + w_2;//center[0] + w/2.0;
+ o_ppos3d[2][1] = c1 - w_2;//center[1] - w/2.0;
+ o_ppos3d[3][0] = c0 - w_2;//center[0] - w/2.0;
+ o_ppos3d[3][1] = c1 - w_2;//center[1] - w/2.0;
+ return;
+ }
+
private final double[][] wk_transMat_pos3d=new double[P_MAX][3];//pos3d[P_MAX][3];
private final double[][] wk_transMat_ppos2d=new double[4][2];
private final double[][] wk_transMat_ppos3d=new double[4][2];
private final double[] wk_transMat_off=new double[3];
private final double[][] wk_transMat_pos2d=new double[P_MAX][2];//pos2d[P_MAX][2];
-
-
- private final DoubleValue wk_arGetTransMatSub_a1=new DoubleValue();
- private final DoubleValue wk_arGetTransMatSub_a2=new DoubleValue();
- private final NyARMat wk_transMat_mat_a=new NyARMat(NUMBER_OF_VERTEX*2,3);
private final NyARMat wk_transMat_mat_b=new NyARMat(3,NUMBER_OF_VERTEX*2);
private final NyARMat wk_transMat_mat_d=new NyARMat( 3, 3 );
private final double[] wk_transMat_mat_trans=new double[3];
@@ -98,107 +132,118 @@
* @return
* @throws NyARException
*/
- public double transMat( NyARSquare square,int i_direction, double width)throws NyARException
+ public double transMat(NyARSquare square,int i_direction, double width,NyARTransMatResult o_result_conv)throws NyARException
{
double[][] ppos2d=wk_transMat_ppos2d;
double[][] ppos3d=wk_transMat_ppos3d;
- double[] off=wk_transMat_off;
- double[][] pos3d=wk_transMat_pos3d;
-
-
- ppos2d[0][0] = square.sqvertex[(4-i_direction)%4][0];
- ppos2d[0][1] = square.sqvertex[(4-i_direction)%4][1];
- ppos2d[1][0] = square.sqvertex[(5-i_direction)%4][0];
- ppos2d[1][1] = square.sqvertex[(5-i_direction)%4][1];
- ppos2d[2][0] = square.sqvertex[(6-i_direction)%4][0];
- ppos2d[2][1] = square.sqvertex[(6-i_direction)%4][1];
- ppos2d[3][0] = square.sqvertex[(7-i_direction)%4][0];
- ppos2d[3][1] = square.sqvertex[(7-i_direction)%4][1];
- ppos3d[0][0] = center[0] - width/2.0;
- ppos3d[0][1] = center[1] + width/2.0;
- ppos3d[1][0] = center[0] + width/2.0;
- ppos3d[1][1] = center[1] + width/2.0;
- ppos3d[2][0] = center[0] + width/2.0;
- ppos3d[2][1] = center[1] - width/2.0;
- ppos3d[3][0] = center[0] - width/2.0;
- ppos3d[3][1] = center[1] - width/2.0;
-
+ double[] off =wk_transMat_off;
+ double[][] pos3d =wk_transMat_pos3d;
+
+ //rotationの初期化
transrot.initRot(square,i_direction);

+ //ppos2dとppos3dの初期化
+ init_transMat_ppos(square,i_direction,width,ppos2d,ppos3d);
+
//arGetTransMat3の前段処理(pos3dとoffを初期化)
- arGetTransMat3_initPos3d(ppos3d,pos3d,off);
-
-
- //arGetTransMatSubにあった処理。毎回おなじっぽい。pos2dに変換座標を格納する。
double[][] pos2d=this.wk_transMat_pos2d;
- DoubleValue a1=this.wk_arGetTransMatSub_a1;
- DoubleValue a2=this.wk_arGetTransMatSub_a2;
- if(arFittingMode == AR_FITTING_TO_INPUT ){
- for(int i = 0; i < NUMBER_OF_VERTEX; i++ ) {
- param.ideal2Observ(ppos2d[i][0], ppos2d[i][1],a1,a2);//arParamIdeal2Observ(dist_factor, ppos2d[i][0], ppos2d[i][1],&pos2d[i][0], &pos2d[i][1]);
- pos2d[i][0]=a1.value;
- pos2d[i][1]=a2.value;
- }
- }else{
- for(int i = 0; i < NUMBER_OF_VERTEX; i++ ){
- pos2d[i][0] = ppos2d[i][0];
- pos2d[i][1] = ppos2d[i][1];
- }
- }
-
- //変換マトリクスdとbの準備(arGetTransMatSubの一部)
- final double cpara[]=param.get34Array();
- final NyARMat mat_a =this.wk_transMat_mat_a;
- final double[][] a_array=mat_a.getArray();
-
final NyARMat mat_b =this.wk_transMat_mat_b;
- final double[][] b_array=mat_b.getArray();
-
- int x2;
- for(int i = 0; i < NUMBER_OF_VERTEX; i++ ) {
- x2=i*2;
- //</Optimize>
- a_array[x2 ][0]=b_array[0][x2]=cpara[0*4+0];//mat_a->m[j*6+0] = mat_b->m[num*0+j*2] = cpara[0][0];
- a_array[x2 ][1]=b_array[1][x2]=cpara[0*4+1];//mat_a->m[j*6+1] = mat_b->m[num*2+j*2] = cpara[0][1];
- a_array[x2 ][2]=b_array[2][x2]=cpara[0*4+2]-pos2d[i][0];//mat_a->m[j*6+2] = mat_b->m[num*4+j*2] = cpara[0][2] - pos2d[j][0];
- a_array[x2+1][0]=b_array[0][x2+1]=0.0;//mat_a->m[j*6+3] = mat_b->m[num*0+j*2+1] = 0.0;
- a_array[x2+1][1]=b_array[1][x2+1]=cpara[1*4+1];//mat_a->m[j*6+4] = mat_b->m[num*2+j*2+1] = cpara[1][1];
- a_array[x2+1][2]=b_array[2][x2+1]=cpara[1*4+2] - pos2d[i][1];//mat_a->m[j*6+5] = mat_b->m[num*4+j*2+1] = cpara[1][2] - pos2d[j][1];
- }
final NyARMat mat_d =this.wk_transMat_mat_d;
- mat_d.matrixMul(mat_b,mat_a);
- mat_d.matrixSelfInv();

+ arGetTransMat3_initTransMat(ppos3d,ppos2d,pos2d,pos3d,off,mat_b,mat_d);
+
double err=-1;
- double[] rot=transrot.getArray();
- double[][] conv=result_mat.getArray();
double[] trans=this.wk_transMat_mat_trans;
for(int i=0;i<AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++ ){
//<arGetTransMat3>
err = arGetTransMatSub(pos2d, pos3d,mat_b,mat_d,trans);
- conv[0][0] = rot[0*3+0];
- conv[0][1] = rot[0*3+1];
- conv[0][2] = rot[0*3+2];
- conv[1][0] = rot[1*3+0];
- conv[1][1] = rot[1*3+1];
- conv[1][2] = rot[1*3+2];
- conv[2][0] = rot[2*3+0];
- conv[2][1] = rot[2*3+1];
- conv[2][2] = rot[2*3+2];
- conv[0][3] = rot[0*3+0]*off[0] + rot[0*3+1]*off[1] + rot[0*3+2]*off[2] + trans[0];
- conv[1][3] = rot[1*3+0]*off[0] + rot[1*3+1]*off[1] + rot[1*3+2]*off[2] + trans[1];
- conv[2][3] = rot[2*3+0]*off[0] + rot[2*3+1]*off[1] + rot[2*3+2]*off[2] + trans[2];
-
- //</arGetTransMat3>
+// //</arGetTransMat3>
if( err < AR_GET_TRANS_MAT_MAX_FIT_ERROR ){
break;
}
}
+ //マトリクスの保存
+ o_result_conv.updateMatrixValue(this.transrot,off,trans);
return err;
}
- private final double[] wk_arGetTransMat3_initPos3d_pmax=new double[3];
- private final double[] wk_arGetTransMat3_initPos3d_pmin=new double[3];
+ private final NyARTransMatResult wk_transMatContinue_result=new NyARTransMatResult();
+
/**
+ * double arGetTransMatCont( ARMarkerInfo *marker_info, double prev_conv[3][4],double center[2], double width, double conv[3][4] )
+ *
+ * @param i_square
+ * @param i_direction
+ * マーカーの方位を指定する。
+ * @param i_width
+ * @param io_result_conv
+ * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。
+ * 履歴を持たない場合は、transMatと同じ処理を行う。
+ * @return
+ * @throws NyARException
+ */
+ public double transMatContinue(NyARSquare i_square,int i_direction, double i_width,NyARTransMatResult io_result_conv)throws NyARException
+ {
+ //io_result_convが初期値なら、transMatで計算する。
+ if(!io_result_conv.hasValue()){
+ return this.transMat(i_square, i_direction, i_width, io_result_conv);
+ }
+
+ double[][] ppos2d=wk_transMat_ppos2d;
+ double[][] ppos3d=wk_transMat_ppos3d;
+ double[] off =wk_transMat_off;
+ double[][] pos3d =wk_transMat_pos3d;
+
+ // arGetTransMatContSub計算部分
+ transrot.initRotByPrevResult(io_result_conv);
+
+ //ppos2dとppos3dの初期化
+ init_transMat_ppos(i_square,i_direction,i_width,ppos2d,ppos3d);
+
+ //arGetTransMat3の前段処理(pos3dとoffを初期化)
+ double[][] pos2d=this.wk_transMat_pos2d;
+ final NyARMat mat_b =this.wk_transMat_mat_b;
+ final NyARMat mat_d =this.wk_transMat_mat_d;
+
+ //transMatに必要な初期値を計算
+ arGetTransMat3_initTransMat(ppos3d,ppos2d,pos2d,pos3d,off,mat_b,mat_d);
+
+ double err1,err2;
+ int i;
+
+ err1=err2=-1;
+ double[] trans=this.wk_transMat_mat_trans;
+ for( i = 0; i < AR_GET_TRANS_MAT_MAX_LOOP_COUNT; i++ ){
+ err1 = arGetTransMatSub(pos2d, pos3d,mat_b,mat_d,trans);
+ if( err1 < AR_GET_TRANS_MAT_MAX_FIT_ERROR ){
+ //十分な精度を達成できたらブレーク
+ break;
+ }
+ }
+ //値を保存
+ io_result_conv.updateMatrixValue(this.transrot,off,trans);
+
+ //エラー値が許容範囲でなければTransMatをやり直し
+ if(err1>AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {
+ NyARTransMatResult result2=this.wk_transMatContinue_result;
+ //transMatを実行(初期化値は共用)
+ transrot.initRot(i_square,i_direction);
+ err2 = transMat(i_square,i_direction,i_width,result2);
+ //transmMatここまで
+ if(err2<err1){
+ //良い値が取れたら、差換え
+ io_result_conv.copyFrom(result2);
+ err1 = err2;
+ }
+ }
+ return err1;
+ }
+
+
+
+
+ private final NyARMat wk_arGetTransMat3_mat_a=new NyARMat(NUMBER_OF_VERTEX*2,3);
+
+ /**
* arGetTransMat3関数の前処理部分。i_ppos3dから、o_pos3dとoffを計算する。
* 計算結果から再帰的に変更される可能性が無いので、切り離し。
* @param i_ppos3d
@@ -209,30 +254,33 @@
* [3]
* @throws NyARException
*/
- private final void arGetTransMat3_initPos3d(double i_ppos3d[][],double[][] o_pos3d,double[] o_off)throws NyARException
+ private final void arGetTransMat3_initTransMat(double[][] i_ppos3d,double[][] i_ppos2d,double[][] o_pos2d,double[][] o_pos3d,double[] o_off,NyARMat o_mat_b,NyARMat o_mat_d)throws NyARException
{
- final double[] pmax=wk_arGetTransMat3_initPos3d_pmax;//new double[3];
- final double[] pmin=wk_arGetTransMat3_initPos3d_pmin;//new double[3];//double off[3], pmax[3], pmin[3];
+ double pmax0,pmax1,pmax2,pmin0,pmin1,pmin2;
int i;
- pmax[0]=pmax[1]=pmax[2] = -10000000000.0;
- pmin[0]=pmin[1]=pmin[2] = 10000000000.0;
+ pmax0=pmax1=pmax2 = -10000000000.0;
+ pmin0=pmin1=pmin2 = 10000000000.0;
for(i = 0; i < NUMBER_OF_VERTEX; i++ ) {
- if( i_ppos3d[i][0] > pmax[0] ){
- pmax[0] = i_ppos3d[i][0];
+ if( i_ppos3d[i][0] > pmax0 ){
+ pmax0 = i_ppos3d[i][0];
}
- if( i_ppos3d[i][0] < pmin[0] ){
- pmin[0] = i_ppos3d[i][0];
+ if( i_ppos3d[i][0] < pmin0 ){
+ pmin0 = i_ppos3d[i][0];
}
- if( i_ppos3d[i][1] > pmax[1] ){
- pmax[1] = i_ppos3d[i][1];
+ if( i_ppos3d[i][1] > pmax1 ){
+ pmax1 = i_ppos3d[i][1];
}
- if( i_ppos3d[i][1] < pmin[1] ){
- pmin[1] = i_ppos3d[i][1];
+ if( i_ppos3d[i][1] < pmin1 ){
+ pmin1 = i_ppos3d[i][1];
}
+ /* オリジナルでもコメントアウト
+ if( ppos3d[i][2] > pmax[2] ) pmax[2] = ppos3d[i][2];
+ if( ppos3d[i][2] < pmin[2] ) pmin[2] = ppos3d[i][2];
+ */
}
- o_off[0] = -(pmax[0] + pmin[0]) / 2.0;
- o_off[1] = -(pmax[1] + pmin[1]) / 2.0;
- o_off[2] = -(pmax[2] + pmin[2]) / 2.0;
+ o_off[0] = -(pmax0 + pmin0) / 2.0;
+ o_off[1] = -(pmax1 + pmin1) / 2.0;
+ o_off[2] = -(pmax2 + pmin2) / 2.0;


double[] o_pos3d_pt;
@@ -244,6 +292,42 @@
o_pos3d_pt[1] = i_pos_pd_pt[1] + o_off[1];
o_pos3d_pt[2] = 0.0;
}
+ //ココから先でarGetTransMatSubの初期化処理
+ //arGetTransMatSubにあった処理。毎回おなじっぽい。pos2dに変換座標を格納する。
+
+ if(arFittingMode == AR_FITTING_TO_INPUT ){
+ //arParamIdeal2Observをバッチ処理
+ param.ideal2ObservBatch(i_ppos2d,o_pos2d,NUMBER_OF_VERTEX);
+ }else{
+ for(i = 0; i < NUMBER_OF_VERTEX; i++ ){
+ o_pos2d[i][0] = i_ppos2d[i][0];
+ o_pos2d[i][1] = i_ppos2d[i][1];
+ }
+ }
+
+ //変換マトリクスdとbの準備(arGetTransMatSubの一部)
+ final double cpara[]=param.get34Array();
+ final NyARMat mat_a =this.wk_arGetTransMat3_mat_a;
+ final double[][] a_array=mat_a.getArray();
+
+ //mat_bの設定
+ final double[][] b_array=o_mat_b.getArray();
+
+ int x2;
+ for(i = 0; i < NUMBER_OF_VERTEX; i++ ) {
+ x2=i*2;
+ //</Optimize>
+ a_array[x2 ][0]=b_array[0][x2]=cpara[0*4+0];//mat_a->m[j*6+0] = mat_b->m[num*0+j*2] = cpara[0][0];
+ a_array[x2 ][1]=b_array[1][x2]=cpara[0*4+1];//mat_a->m[j*6+1] = mat_b->m[num*2+j*2] = cpara[0][1];
+ a_array[x2 ][2]=b_array[2][x2]=cpara[0*4+2]-o_pos2d[i][0];//mat_a->m[j*6+2] = mat_b->m[num*4+j*2] = cpara[0][2] - pos2d[j][0];
+ a_array[x2+1][0]=b_array[0][x2+1]=0.0;//mat_a->m[j*6+3] = mat_b->m[num*0+j*2+1] = 0.0;
+ a_array[x2+1][1]=b_array[1][x2+1]=cpara[1*4+1];//mat_a->m[j*6+4] = mat_b->m[num*2+j*2+1] = cpara[1][1];
+ a_array[x2+1][2]=b_array[2][x2+1]=cpara[1*4+2]-o_pos2d[i][1];//mat_a->m[j*6+5] = mat_b->m[num*4+j*2+1] = cpara[1][2] - pos2d[j][1];
+ }
+
+ //mat_d
+ o_mat_d.matrixMul(o_mat_b,mat_a);
+ o_mat_d.matrixSelfInv();
}

private final NyARMat wk_arGetTransMatSub_mat_c=new NyARMat(NUMBER_OF_VERTEX*2,1);
@@ -313,19 +397,6 @@
o_trans[1] = f_array[1][0];
o_trans[2] = f_array[2][0];//trans[2] = mat_f->m[2];
ret = transrot.modifyMatrix(o_trans, i_pos3d, i_ppos2d);
-
-// double[][] conv=result_mat.getArray();
-// for( i = 2; i >=0; i-- ) {//<Optimize/>for( j = 0; j < 3; j++ ) {
-// //<Optimize>
-// //for( i = 0; i < 3; i++ ){
-// // conv[j][i] = rot[j][i];
-// //}
-// conv[i][0] = rot[i*3+0];
-// conv[i][1] = rot[i*3+1];
-// conv[i][2] = rot[i*3+2];
-// //</Optimize>
-// conv[i][3] = trans[i];
-// }
return ret;
}
}
Index: src/jp/nyatla/nyartoolkit/core/NyARParam.java
===================================================================
--- src/jp/nyatla/nyartoolkit/core/NyARParam.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/core/NyARParam.java (revision 200)
@@ -272,6 +272,41 @@
}
}
/**
+ * ideal2Observをまとめて実行します。
+ * @param i_in
+ * double[][2]
+ * @param o_out
+ * double[][2]
+ */
+ public void ideal2ObservBatch(double[][] i_in,double[][] o_out,int i_size)
+ {
+
+ double x, y, d;
+ final double d0,d1,d3,d2_w;
+ final double df[]=this.dist_factor;
+ d0=df[0];
+ d1=df[1];
+ d3=df[3];
+ d2_w=df[2]/100000000.0;
+ for(int i=0;i<i_size;i++){
+ x = (i_in[i][0] - d0) * d3;
+ y = (i_in[i][1] - d1) * d3;
+ if( x == 0.0 && y == 0.0 ) {
+ o_out[i][0]=d0;
+ o_out[i][1]=d1;
+ }else{
+ d = 1.0 - d2_w * (x*x+y*y);
+ o_out[i][0]=x * d + d0;
+ o_out[i][1]=y * d + d1;
+ }
+ }
+ return;
+ }
+
+
+
+
+ /**
* int arParamObserv2Ideal( const double dist_factor[4], const double ox, const double oy,double *ix, double *iy );
*
* @param ox
@@ -322,7 +357,7 @@
* @param i_x_coord
* @param i_y_coord
* @param i_start
- * 開始点
+ * coord開始点
* @param i_num
* 計算数
* @param o_ideal
Index: src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java
===================================================================
--- src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java (revision 0)
+++ src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java (revision 200)
@@ -0,0 +1,278 @@
+/*
+ * PROJECT: NyARToolkit
+ * --------------------------------------------------------------------------------
+ * This work is based on the original ARToolKit developed by
+ * Hirokazu Kato
+ * Mark Billinghurst
+ * HITLab, University of Washington, Seattle
+ * http://www.hitl.washington.edu/artoolkit/
+ *
+ * The NyARToolkit is Java version ARToolkit class library.
+ * Copyright (C)2008 R.Iizuka
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this framework; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For further information please contact.
+ * http://nyatla.jp/nyatoolkit/
+ * <airmail(at)ebony.plala.or.jp>
+ *
+ */
+package jp.nyatla.nyartoolkit.detector;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.match.NyARMatchPatt_Color_WITHOUT_PCA;
+import jp.nyatla.nyartoolkit.core.raster.*;
+
+
+
+class NyARDetectMarkerResult
+{
+ public int arcode_id;
+ public int direction;
+ public double confidence;
+ public NyARSquare ref_square;
+}
+class NyARDetectMarkerResultHolder
+{
+ public NyARDetectMarkerResult[] result_array=new NyARDetectMarkerResult[1];
+ /**
+ * result_holderを最大i_reserve_size個の要素を格納できるように予約します。
+ * @param i_reserve_size
+ */
+ public void reservHolder(int i_reserve_size)
+ {
+ if(i_reserve_size>=result_array.length){
+ int new_size=i_reserve_size+5;
+ result_array=new NyARDetectMarkerResult[new_size];
+ for(int i=0;i<new_size;i++){
+ result_array[i]=new NyARDetectMarkerResult();
+ }
+ }
+ }
+}
+/**
+ * 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから
+ * 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。
+ *
+ */
+public class NyARDetectMarker{
+ private static final int AR_SQUARE_MAX=300;
+ private boolean is_continue=false;
+ private NyARMatchPatt_Color_WITHOUT_PCA match_patt;
+ private NyARDetectSquare square;
+ private final NyARSquareList square_list=new NyARSquareList(AR_SQUARE_MAX);
+ private NyARCode[] codes;
+ protected NyARTransMat transmat;
+ private double[] marker_width;
+ private int number_of_code;
+ //検出結果の保存用
+ private NyARColorPatt patt;
+
+ private NyARDetectMarkerResultHolder result_holder=new NyARDetectMarkerResultHolder();
+
+ /**
+ * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。
+ * @param i_param
+ * カメラパラメータを指定します。
+ * @param i_code
+ * 検出するマーカーのARCode配列を指定します。配列要素のインデックス番号が、そのままgetARCodeIndex関数で
+ * 得られるARCodeインデックスになります。
+ * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。
+ * 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。
+ * @param i_marker_width
+ * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。
+ * 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。
+ * @param i_number_of_code
+ * i_codeに含まれる、ARCodeの数を指定します。
+ * @throws NyARException
+ */
+ public NyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width,int i_number_of_code) throws NyARException
+ {
+ //解析オブジェクトを作る
+ this.square=new NyARDetectSquare(i_param);
+ this.transmat=new NyARTransMat_O2(i_param);
+ //比較コードを保存
+ this.codes=i_code;
+ //比較コードの解像度は全部同じかな?(違うとパターンを複数種つくらないといけないから)
+ int cw=i_code[0].getWidth();
+ int ch=i_code[0].getHeight();
+ for(int i=1;i<i_number_of_code;i++){
+ if(cw!=i_code[i].getWidth() || ch!=i_code[i].getHeight()){
+ //違う解像度のが混ざっている。
+ throw new NyARException();
+ }
+ }
+ //評価パターンのホルダを作る
+ this.patt=new NyARColorPatt_O3(cw,ch);
+ this.number_of_code=i_number_of_code;
+
+ this.marker_width=i_marker_width;
+ //評価器を作る。
+ this.match_patt=new NyARMatchPatt_Color_WITHOUT_PCA();
+ }
+ /**
+ * i_imageにマーカー検出処理を実行し、結果を記録します。
+ * @param i_image
+ * マーカーを検出するイメージを指定します。
+ * @param i_thresh
+ * 検出閾値を指定します。0〜255の範囲で指定してください。
+ * 通常は100〜130くらいを指定します。
+ * @return
+ * 見つかったマーカーの数を返します。
+ * マーカーが見つからない場合は0を返します。
+ * @throws NyARException
+ */
+ public int detectMarkerLite(NyARRaster i_image,int i_thresh) throws NyARException
+ {
+ NyARSquareList l_square_list=this.square_list;
+ //スクエアコードを探す
+ square.detectSquare(i_image, i_thresh,l_square_list);
+
+ final int number_of_square=l_square_list.getSquareNum();
+ //コードは見つかった?
+ if(number_of_square<1){
+ //ないや。おしまい。
+ return 0;
+ }
+ //保持リストのサイズを調整
+ this.result_holder.reservHolder(number_of_square);
+
+ //1スクエア毎に、一致するコードを決定していく
+ for(int i=0;i<number_of_square;i++)
+ {
+ NyARSquare square=l_square_list.getSquare(i);
+ //評価基準になるパターンをイメージから切り出す
+ if(!this.patt.pickFromRaster(i_image,square)){
+ //イメージの切り出しは失敗することもある。
+ continue;
+ }
+ //パターンを評価器にセット
+ if(!this.match_patt.setPatt(this.patt)){
+ //計算に失敗した。
+ throw new NyARException();
+ }
+ //コードと順番に比較していく
+ int code_index=0;
+ match_patt.evaluate(codes[0]);
+ double confidence=match_patt.getConfidence();
+ int direction=match_patt.getDirection();
+ for(int i2=1;i2<this.number_of_code;i2++)
+ {
+ //コードと比較する
+ match_patt.evaluate(codes[i2]);
+ double c2=match_patt.getConfidence();
+ if(confidence>c2){
+ continue;
+ }
+ //より一致するARCodeの情報を保存
+ code_index =i2;
+ direction =match_patt.getDirection();
+ confidence =c2;
+ }
+ //i番目のパターン情報を保存する。
+ final NyARDetectMarkerResult result=this.result_holder.result_array[i];
+ result.arcode_id =code_index;
+ result.confidence=confidence;
+ result.direction =direction;
+ result.ref_square=square;
+ }
+ return number_of_square;
+ }
+ /**
+ * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。
+ * @param i_index
+ * マーカーのインデックス番号を指定します。
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
+ * @param o_result
+ * 結果値を受け取るオブジェクトを指定してください。
+ * @throws NyARException
+ */
+ public void getTransmationMatrix(int i_index,NyARTransMatResult o_result) throws NyARException
+ {
+ final NyARDetectMarkerResult result=this.result_holder.result_array[i_index];
+ //一番一致したマーカーの位置とかその辺を計算
+ if(is_continue){
+ transmat.transMatContinue(result.ref_square,result.direction,marker_width[result.arcode_id],o_result);
+ }else{
+ transmat.transMat(result.ref_square,result.direction,marker_width[result.arcode_id],o_result);
+ }
+ return;
+ }
+ /**
+ * i_indexのマーカーの一致度を返します。
+ * @param i_index
+ * マーカーのインデックス番号を指定します。
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
+ * @return
+ * マーカーの一致度を返します。0〜1までの値をとります。
+ * 一致度が低い場合には、誤認識の可能性が高くなります。
+ * @throws NyARException
+ */
+ public double getConfidence(int i_index)
+ {
+ return this.result_holder.result_array[i_index].confidence;
+ }
+ /**
+ * i_indexのマーカーの方位を返します。
+ * @param i_index
+ * マーカーのインデックス番号を指定します。
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
+ * @return
+ * 0,1,2,3の何れかを返します。
+ */
+ public int getDirection(int i_index)
+ {
+ return this.result_holder.result_array[i_index].direction;
+ }
+ /**
+ * i_indexのマーカーのARCodeインデックスを返します。
+ * @param i_index
+ * マーカーのインデックス番号を指定します。
+ * 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
+ * @return
+ */
+ public int getARCodeIndex(int i_index)
+ {
+ return this.result_holder.result_array[i_index].arcode_id;
+ }
+ /**
+ * getTransmationMatrixの計算モードを設定します。
+ * @param i_is_continue
+ * TRUEなら、transMatContinueを使用します。
+ * FALSEなら、transMatを使用します。
+ */
+ public void setContinueMode(boolean i_is_continue)
+ {
+ this.is_continue=i_is_continue;
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: src/jp/nyatla/nyartoolkit/detector/NyARSingleDetectMarker.java
===================================================================
--- src/jp/nyatla/nyartoolkit/detector/NyARSingleDetectMarker.java (revision 196)
+++ src/jp/nyatla/nyartoolkit/detector/NyARSingleDetectMarker.java (revision 200)
@@ -36,11 +36,12 @@
import jp.nyatla.nyartoolkit.core.match.NyARMatchPatt_Color_WITHOUT_PCA;
import jp.nyatla.nyartoolkit.core.raster.*;
/**
- * 1個のマーカーに対する変換行列を計算するクラスです。
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。
*
*/
public class NyARSingleDetectMarker{
private static final int AR_SQUARE_MAX=100;
+ private boolean is_continue=false;
private NyARMatchPatt_Color_WITHOUT_PCA match_patt;
private NyARDetectSquare square;
private final NyARSquareList square_list=new NyARSquareList(AR_SQUARE_MAX);
@@ -52,6 +53,16 @@
private double detected_confidence;
private NyARSquare detected_square;
private NyARColorPatt patt;
+ /**
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。
+ * @param i_param
+ * カメラパラメータを指定します。
+ * @param i_code
+ * 検出するARCodeを指定します。
+ * @param i_marker_width
+ * ARコードの物理サイズを、ミリメートルで指定します。
+ * @throws NyARException
+ */
public NyARSingleDetectMarker(NyARParam i_param,NyARCode i_code,double i_marker_width) throws NyARException
{
//解析オブジェクトを作る
@@ -66,9 +77,12 @@
this.match_patt=new NyARMatchPatt_Color_WITHOUT_PCA();
}
/**
- * i_imageにマーカー検出処理を実行して、結果を保持します。
- * @param dataPtr
- * @param thresh
+ * i_imageにマーカー検出処理を実行し、結果を記録します。
+ * @param i_image
+ * マーカーを検出するイメージを指定します。
+ * @param i_thresh
+ * 検出閾値を指定します。0〜255の範囲で指定してください。
+ * 通常は100〜130くらいを指定します。
* @return
* マーカーが検出できたかを真偽値で返します。
* @throws NyARException
@@ -86,10 +100,11 @@
return false;
}

- //コードの一致度を調べる準備
-// NyARSquare[] squares=square.getSquareArray();
//評価基準になるパターンをイメージから切り出す
- patt.pickFromRaster(i_image,l_square_list.getSquare(0));
+ if(!patt.pickFromRaster(i_image,l_square_list.getSquare(0))){
+ //パターンの切り出しに失敗
+ return false;
+ }
//パターンを評価器にセット
if(!this.match_patt.setPatt(patt)){
//計算に失敗した。
@@ -123,43 +138,53 @@
return true;
}
/**
- * 変換行列を返します。直前に実行したdetectMarkerLiteが成功していないと使えません。
- * @param i_marker_width
- * マーカーの大きさを指定します。
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。
+ * @param o_result
+ * 変換行列を受け取るオブジェクトを指定します。
+ * @throws NyARException
+ */
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException
+ {
+ //一番一致したマーカーの位置とかその辺を計算
+ if(is_continue){
+ transmat.transMatContinue(detected_square,detected_direction,marker_width,o_result);
+ }else{
+ transmat.transMat(detected_square,detected_direction,marker_width,o_result);
+ }
+ return;
+ }
+ /**
+ * 検出したマーカーの一致度を返します。
* @return
- * double[3][4]の変換行列を返します。
+ * マーカーの一致度を返します。0〜1までの値をとります。
+ * 一致度が低い場合には、誤認識の可能性が高くなります。
* @throws NyARException
*/
- public NyARMat getTransmationMatrix() throws NyARException
- {
- //一番一致したマーカーの位置とかその辺を計算
- transmat.transMat(detected_square,detected_direction,marker_width);
- return transmat.getTransformationMatrix();
- }
public double getConfidence()
{
return detected_confidence;
}
+ /**
+ * 検出したマーカーの方位を返します。
+ * @return
+ * 0,1,2,3の何れかを返します。
+ */
public int getDirection()
{
return detected_direction;
}
-
-
-
-
-
-
-
-// public static class arUtil_c{
-// public static final int arFittingMode =Config.DEFAULT_FITTING_MODE;
-// private static final int arImageProcMode =Config.DEFAULT_IMAGE_PROC_MODE;
-// public static final int arTemplateMatchingMode =Config.DEFAULT_TEMPLATE_MATCHING_MODE;
-// public static final int arMatchingPCAMode =Config.DEFAULT_MATCHING_PCA_MODE;
- /*int arInitCparam( ARParam *param )*/
-
-
-
+ /**
+ * getTransmationMatrixの計算モードを設定します。
+ * 初期値はTRUEです。
+ * @param i_is_continue
+ * TRUEなら、transMatCont互換の計算をします。
+ * FALSEなら、transMat互換の計算をします。
+ */
+ public void setContinueMode(boolean i_is_continue)
+ {
+ this.is_continue=i_is_continue;
+ }
}


Index: src/jp/nyatla/util/DoublePointer.java
===================================================================
--- src/jp/nyatla/util/DoublePointer.java (revision 196)
+++ src/jp/nyatla/util/DoublePointer.java (revision 200)
@@ -2,7 +2,6 @@
/**
* double型ポインタのエミュレートクラス
* 対象のdouble配列を基点を基準に参照する。
- * @author atla
*
*/
public class DoublePointer
Index: Data/patt.kanji
===================================================================
--- Data/patt.kanji (revision 0)
+++ Data/patt.kanji (revision 200)
@@ -0,0 +1,196 @@
+ 214 225 240 225 214 240 216 204 214 227 181 192 198 192 181 192
+ 240 240 240 240 240 240 225 232 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 75 128 220 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 106 53 240 240 240 240 240 240 240 237
+ 240 240 240 240 240 238 118 31 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 74 49 207 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 53 54 177 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 64 31 130 240 240 240 240 240 240 219
+ 240 240 240 240 240 180 37 57 78 228 240 240 240 240 240 240
+ 240 240 240 240 240 118 62 157 36 185 240 240 240 240 240 231
+ 240 240 240 240 240 82 65 225 67 80 230 240 240 240 240 217
+ 240 240 240 225 53 76 225 240 156 62 158 240 240 240 240 226
+ 240 240 199 61 9 111 235 240 240 104 58 174 228 240 240 240
+ 240 142 64 26 92 227 240 240 240 229 93 64 170 226 238 216
+ 90 26 12 156 240 240 240 240 240 240 204 95 30 117 192 200
+ 156 16 195 233 235 240 236 240 238 239 240 186 93 53 120 237
+ 214 226 240 225 212 240 216 204 212 226 181 192 198 192 185 194
+ 240 240 240 240 240 240 227 232 240 240 240 240 240 240 240 238
+ 240 240 240 240 240 240 95 138 225 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 108 59 240 240 240 240 240 240 240 237
+ 240 240 240 240 240 238 118 31 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 83 47 207 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 56 49 177 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 73 41 130 240 240 240 240 240 240 222
+ 240 240 240 240 240 185 46 49 86 230 240 240 240 240 240 240
+ 240 240 240 240 240 118 58 165 45 192 240 240 240 240 240 234
+ 240 240 240 240 240 91 63 222 74 82 240 240 240 240 240 222
+ 240 240 240 226 66 86 225 240 158 63 162 240 240 240 240 228
+ 240 240 202 76 11 103 235 240 234 91 49 174 228 240 240 240
+ 240 142 68 16 91 226 240 240 240 228 96 74 178 233 239 222
+ 90 26 4 150 240 240 240 240 240 240 213 109 46 133 204 213
+ 156 14 195 234 236 240 237 240 239 240 240 192 106 57 125 238
+ 214 226 240 225 212 240 216 204 214 227 181 192 198 192 184 192
+ 240 240 240 240 240 240 226 232 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 85 134 220 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 107 58 240 240 240 240 240 240 240 237
+ 240 240 240 240 240 238 118 32 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 87 60 210 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 58 58 178 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 73 31 130 240 240 240 240 240 240 219
+ 240 240 240 240 240 185 46 59 86 228 240 240 240 240 240 240
+ 240 240 240 240 240 118 62 168 41 186 240 240 240 240 240 231
+ 240 240 240 240 240 90 65 225 60 92 235 240 240 240 240 219
+ 240 240 240 225 53 82 225 240 146 63 163 240 240 240 240 228
+ 240 240 198 61 5 103 235 240 234 102 58 175 232 240 240 240
+ 240 134 54 13 91 226 240 240 240 229 96 68 188 238 239 222
+ 90 15 3 150 240 240 240 240 240 240 213 105 48 134 204 213
+ 156 14 195 233 236 240 237 240 239 239 240 192 106 57 125 238
+
+ 192 236 240 237 234 240 240 219 240 231 217 226 240 216 200 237
+ 181 240 240 240 240 240 240 240 240 240 240 240 240 238 192 120
+ 192 240 240 240 240 240 240 240 240 240 240 240 240 226 117 53
+ 198 240 240 240 240 240 240 240 240 240 240 240 228 170 30 93
+ 192 240 240 240 240 240 240 240 240 240 240 240 174 64 95 186
+ 181 240 240 240 240 240 240 240 240 240 230 158 58 93 204 240
+ 227 240 240 240 240 240 240 240 228 185 80 62 104 229 240 239
+ 214 240 220 240 240 207 177 130 78 36 67 156 240 240 240 238
+ 204 232 128 53 31 49 54 31 57 157 225 240 240 240 240 240
+ 216 225 75 106 118 74 53 64 37 62 65 225 235 240 240 236
+ 240 240 240 240 238 240 240 240 180 118 82 76 111 227 240 240
+ 214 240 240 240 240 240 240 240 240 240 240 53 9 92 240 235
+ 225 240 240 240 240 240 240 240 240 240 240 225 61 26 156 233
+ 240 240 240 240 240 240 240 240 240 240 240 240 199 64 12 195
+ 225 240 240 240 240 240 240 240 240 240 240 240 240 142 26 16
+ 214 240 240 240 240 240 240 240 240 240 240 240 240 240 90 156
+ 194 238 240 237 234 240 240 222 240 234 222 228 240 222 213 238
+ 185 240 240 240 240 240 240 240 240 240 240 240 240 239 204 125
+ 192 240 240 240 240 240 240 240 240 240 240 240 240 233 133 57
+ 198 240 240 240 240 240 240 240 240 240 240 240 228 178 46 106
+ 192 240 240 240 240 240 240 240 240 240 240 240 174 74 109 192
+ 181 240 240 240 240 240 240 240 240 240 240 162 49 96 213 240
+ 226 240 240 240 240 240 240 240 230 192 82 63 91 228 240 240
+ 212 240 225 240 240 207 177 130 86 45 74 158 234 240 240 239
+ 204 232 138 59 31 47 49 41 49 165 222 240 240 240 240 240
+ 216 227 95 108 118 83 56 73 46 58 63 225 235 240 240 237
+ 240 240 240 240 238 240 240 240 185 118 91 86 103 226 240 240
+ 212 240 240 240 240 240 240 240 240 240 240 66 11 91 240 236
+ 225 240 240 240 240 240 240 240 240 240 240 226 76 16 150 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 202 68 4 195
+ 226 240 240 240 240 240 240 240 240 240 240 240 240 142 26 14
+ 214 240 240 240 240 240 240 240 240 240 240 240 240 240 90 156
+ 192 236 240 237 234 240 240 219 240 231 219 228 240 222 213 238
+ 184 240 240 240 240 240 240 240 240 240 240 240 240 239 204 125
+ 192 240 240 240 240 240 240 240 240 240 240 240 240 238 134 57
+ 198 240 240 240 240 240 240 240 240 240 240 240 232 188 48 106
+ 192 240 240 240 240 240 240 240 240 240 240 240 175 68 105 192
+ 181 240 240 240 240 240 240 240 240 240 235 163 58 96 213 240
+ 227 240 240 240 240 240 240 240 228 186 92 63 102 229 240 239
+ 214 240 220 240 240 210 178 130 86 41 60 146 234 240 240 239
+ 204 232 134 58 32 60 58 31 59 168 225 240 240 240 240 240
+ 216 226 85 107 118 87 58 73 46 62 65 225 235 240 240 237
+ 240 240 240 240 238 240 240 240 185 118 90 82 103 226 240 240
+ 212 240 240 240 240 240 240 240 240 240 240 53 5 91 240 236
+ 225 240 240 240 240 240 240 240 240 240 240 225 61 13 150 233
+ 240 240 240 240 240 240 240 240 240 240 240 240 198 54 3 195
+ 226 240 240 240 240 240 240 240 240 240 240 240 240 134 15 14
+ 214 240 240 240 240 240 240 240 240 240 240 240 240 240 90 156
+
+ 237 120 53 93 186 240 239 238 240 236 240 235 233 195 16 156
+ 200 192 117 30 95 204 240 240 240 240 240 240 156 12 26 90
+ 216 238 226 170 64 93 229 240 240 240 227 92 26 64 142 240
+ 240 240 240 228 174 58 104 240 240 235 111 9 61 199 240 240
+ 226 240 240 240 240 158 62 156 240 225 76 53 225 240 240 240
+ 217 240 240 240 240 230 80 67 225 65 82 240 240 240 240 240
+ 231 240 240 240 240 240 185 36 157 62 118 240 240 240 240 240
+ 240 240 240 240 240 240 228 78 57 37 180 240 240 240 240 240
+ 219 240 240 240 240 240 240 130 31 64 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 177 54 53 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 207 49 74 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 31 118 238 240 240 240 240 240
+ 237 240 240 240 240 240 240 240 53 106 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 220 128 75 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 232 225 240 240 240 240 240 240
+ 192 181 192 198 192 181 227 214 204 216 240 214 225 240 225 214
+ 238 125 57 106 192 240 240 239 240 237 240 236 234 195 14 156
+ 213 204 133 46 109 213 240 240 240 240 240 240 150 4 26 90
+ 222 239 233 178 74 96 228 240 240 240 226 91 16 68 142 240
+ 240 240 240 228 174 49 91 234 240 235 103 11 76 202 240 240
+ 228 240 240 240 240 162 63 158 240 225 86 66 226 240 240 240
+ 222 240 240 240 240 240 82 74 222 63 91 240 240 240 240 240
+ 234 240 240 240 240 240 192 45 165 58 118 240 240 240 240 240
+ 240 240 240 240 240 240 230 86 49 46 185 240 240 240 240 240
+ 222 240 240 240 240 240 240 130 41 73 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 177 49 56 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 207 47 83 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 31 118 238 240 240 240 240 240
+ 237 240 240 240 240 240 240 240 59 108 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 225 138 95 240 240 240 240 240 240
+ 238 240 240 240 240 240 240 240 232 227 240 240 240 240 240 240
+ 194 185 192 198 192 181 226 212 204 216 240 212 225 240 226 214
+ 238 125 57 106 192 240 239 239 240 237 240 236 233 195 14 156
+ 213 204 134 48 105 213 240 240 240 240 240 240 150 3 15 90
+ 222 239 238 188 68 96 229 240 240 240 226 91 13 54 134 240
+ 240 240 240 232 175 58 102 234 240 235 103 5 61 198 240 240
+ 228 240 240 240 240 163 63 146 240 225 82 53 225 240 240 240
+ 219 240 240 240 240 235 92 60 225 65 90 240 240 240 240 240
+ 231 240 240 240 240 240 186 41 168 62 118 240 240 240 240 240
+ 240 240 240 240 240 240 228 86 59 46 185 240 240 240 240 240
+ 219 240 240 240 240 240 240 130 31 73 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 178 58 58 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 210 60 87 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 32 118 238 240 240 240 240 240
+ 237 240 240 240 240 240 240 240 58 107 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 220 134 85 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 232 226 240 240 240 240 240 240
+ 192 184 192 198 192 181 227 214 204 216 240 212 225 240 226 214
+
+ 156 90 240 240 240 240 240 240 240 240 240 240 240 240 240 214
+ 16 26 142 240 240 240 240 240 240 240 240 240 240 240 240 225
+ 195 12 64 199 240 240 240 240 240 240 240 240 240 240 240 240
+ 233 156 26 61 225 240 240 240 240 240 240 240 240 240 240 225
+ 235 240 92 9 53 240 240 240 240 240 240 240 240 240 240 214
+ 240 240 227 111 76 82 118 180 240 240 240 238 240 240 240 240
+ 236 240 240 235 225 65 62 37 64 53 74 118 106 75 225 216
+ 240 240 240 240 240 225 157 57 31 54 49 31 53 128 232 204
+ 238 240 240 240 156 67 36 78 130 177 207 240 240 220 240 214
+ 239 240 229 104 62 80 185 228 240 240 240 240 240 240 240 227
+ 240 204 93 58 158 230 240 240 240 240 240 240 240 240 240 181
+ 186 95 64 174 240 240 240 240 240 240 240 240 240 240 240 192
+ 93 30 170 228 240 240 240 240 240 240 240 240 240 240 240 198
+ 53 117 226 240 240 240 240 240 240 240 240 240 240 240 240 192
+ 120 192 238 240 240 240 240 240 240 240 240 240 240 240 240 181
+ 237 200 216 240 226 217 231 240 219 240 240 234 237 240 236 192
+ 156 90 240 240 240 240 240 240 240 240 240 240 240 240 240 214
+ 14 26 142 240 240 240 240 240 240 240 240 240 240 240 240 226
+ 195 4 68 202 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 150 16 76 226 240 240 240 240 240 240 240 240 240 240 225
+ 236 240 91 11 66 240 240 240 240 240 240 240 240 240 240 212
+ 240 240 226 103 86 91 118 185 240 240 240 238 240 240 240 240
+ 237 240 240 235 225 63 58 46 73 56 83 118 108 95 227 216
+ 240 240 240 240 240 222 165 49 41 49 47 31 59 138 232 204
+ 239 240 240 234 158 74 45 86 130 177 207 240 240 225 240 212
+ 240 240 228 91 63 82 192 230 240 240 240 240 240 240 240 226
+ 240 213 96 49 162 240 240 240 240 240 240 240 240 240 240 181
+ 192 109 74 174 240 240 240 240 240 240 240 240 240 240 240 192
+ 106 46 178 228 240 240 240 240 240 240 240 240 240 240 240 198
+ 57 133 233 240 240 240 240 240 240 240 240 240 240 240 240 192
+ 125 204 239 240 240 240 240 240 240 240 240 240 240 240 240 185
+ 238 213 222 240 228 222 234 240 222 240 240 234 237 240 238 194
+ 156 90 240 240 240 240 240 240 240 240 240 240 240 240 240 214
+ 14 15 134 240 240 240 240 240 240 240 240 240 240 240 240 226
+ 195 3 54 198 240 240 240 240 240 240 240 240 240 240 240 240
+ 233 150 13 61 225 240 240 240 240 240 240 240 240 240 240 225
+ 236 240 91 5 53 240 240 240 240 240 240 240 240 240 240 212
+ 240 240 226 103 82 90 118 185 240 240 240 238 240 240 240 240
+ 237 240 240 235 225 65 62 46 73 58 87 118 107 85 226 216
+ 240 240 240 240 240 225 168 59 31 58 60 32 58 134 232 204
+ 239 240 240 234 146 60 41 86 130 178 210 240 240 220 240 214
+ 239 240 229 102 63 92 186 228 240 240 240 240 240 240 240 227
+ 240 213 96 58 163 235 240 240 240 240 240 240 240 240 240 181
+ 192 105 68 175 240 240 240 240 240 240 240 240 240 240 240 192
+ 106 48 188 232 240 240 240 240 240 240 240 240 240 240 240 198
+ 57 134 238 240 240 240 240 240 240 240 240 240 240 240 240 192
+ 125 204 239 240 240 240 240 240 240 240 240 240 240 240 240 184
+ 238 213 222 240 228 219 231 240 219 240 240 234 237 240 236 192
+
Index: Data/pattKanji.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: Data\pattKanji.pdf
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream