OSDN Git Service

[バックアップ]NyARToolkit
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Thu, 25 Sep 2008 14:23:04 +0000 (14:23 +0000)
committernyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Thu, 25 Sep 2008 14:23:04 +0000 (14:23 +0000)
24 files changed:
sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/x2/GLNyARSingleDetectMarker_X2.java
sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/x2/JavaSimpleLite_X2.java
src/jp/nyatla/nyartoolkit/core/NyARSquareDetector.java
src/jp/nyatla/nyartoolkit/core/NyARVertexCounter.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/core/param/NyARCameraDistortionFactor.java
src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java
src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix.java
src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint.java
src/jp/nyatla/nyartoolkit/core/types/NyARLinear.java
src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/core2/rasterfilter/NyARRasterFilter_Edge.java [moved from src/jp/nyatla/nyartoolkit/nymodel/x2/NyARRasterFilter_Edge.java with 95% similarity]
src/jp/nyatla/nyartoolkit/nymodel/x2/NyARQrCodeDetector.java [moved from src/jp/nyatla/nyartoolkit/nymodel/x2/NyARSquareDetector_X2.java with 94% similarity]
src/jp/nyatla/nyartoolkit/nymodel/x2/NyARRotMatrix_X2.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/nymodel/x2/NyARRotTransOptimize_X2.java
src/jp/nyatla/nyartoolkit/nymodel/x2/NyARSinTable.java [new file with mode: 0644]
src/jp/nyatla/nyartoolkit/nymodel/x2/NyARSingleDetectMarker_X2.java
src/jp/nyatla/nyartoolkit/nymodel/x2/NyARTransMat_X2.java
src/jp/nyatla/utils/j2se/LabelingBufferdImage.java
test/jp/nyatla/nyartoolkit/dev/CopyOfLabelingCamera.java [new file with mode: 0644]
test/jp/nyatla/nyartoolkit/dev/LabelingCamera.java

index 714cbb0..4cded6d 100644 (file)
@@ -35,7 +35,7 @@ import jp.nyatla.nyartoolkit.NyARException;
 import jp.nyatla.nyartoolkit.core.NyARCode;\r
 import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
 import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
-import jp.nyatla.nyartoolkit.core2.x2.*;\r
+import jp.nyatla.nyartoolkit.nymodel.x2.*;\r
 \r
 \r
 /**\r
index b2b7d61..e2b2859 100644 (file)
@@ -44,7 +44,6 @@ import jp.nyatla.nyartoolkit.core.NyARCode;
 import jp.nyatla.nyartoolkit.jmf.utils.JmfCameraCapture;\r
 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;\r
 import jp.nyatla.nyartoolkit.jogl.utils.*;\r
-import jp.nyatla.nyartoolkit.jogl.utils2.*;\r
 /**\r
  * simpleLiteと同じようなテストプログラム\r
  * 出来る限りARToolKitのサンプルと似せて作ってあります。\r
index 5ffcb5f..1a385a3 100644 (file)
@@ -35,7 +35,9 @@ import jp.nyatla.nyartoolkit.core.labeling.*;
 import jp.nyatla.nyartoolkit.core.raster.*;\r
 import jp.nyatla.nyartoolkit.core.types.*;\r
 import jp.nyatla.nyartoolkit.core.param.*;\r
-\r
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.pca2d.*;\r
 \r
 \r
 \r
@@ -83,6 +85,9 @@ public class NyARSquareDetector implements INyARSquareDetector
                this._max_coord = number_of_coord;\r
                this._xcoord = new int[number_of_coord * 2];\r
                this._ycoord = new int[number_of_coord * 2];\r
+               //PCA(最大頂点数は対角線長さ)\r
+               this._pca=new NyARPca2d_MatrixPCA_O2(this._width+this._height);\r
+               \r
        }\r
 \r
        private final int _max_coord;\r
@@ -197,7 +202,7 @@ public class NyARSquareDetector implements INyARSquareDetector
                                o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
                                continue;\r
                        }\r
-\r
+                       // マーカーを検出\r
                        if (!getSquareLine(mkvertex, xcoord, ycoord, square_ptr)) {\r
                                // 矩形が成立しなかった。\r
                                o_square_stack.pop();\r
@@ -328,14 +333,10 @@ public class NyARSquareDetector implements INyARSquareDetector
                return true;\r
        }\r
 \r
-       private final NyARMat __getSquareLine_input = new NyARMat(1, 2);\r
-\r
-       private final NyARMat __getSquareLine_evec = new NyARMat(2, 2);\r
-\r
-       private final NyARVec __getSquareLine_ev = new NyARVec(2);\r
-\r
-       private final NyARVec __getSquareLine_mean = new NyARVec(2);\r
-\r
+       private final INyARPca2d _pca;\r
+       private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();\r
+       private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();\r
+       private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();\r
        /**\r
         * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int\r
         * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。\r
@@ -348,13 +349,12 @@ public class NyARSquareDetector implements INyARSquareDetector
        private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException\r
        {\r
                final NyARLinear[] l_line = o_square.line;\r
-               final NyARVec ev = this.__getSquareLine_ev; // matrixPCAの戻り値を受け取る\r
-               final NyARVec mean = this.__getSquareLine_mean;// matrixPCAの戻り値を受け取る\r
-               final double[] mean_array = mean.getArray();\r
                final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;  \r
-               final NyARMat input = this.__getSquareLine_input;// 次処理で初期化される。\r
-               final NyARMat evec = this.__getSquareLine_evec;// アウトパラメータを受け取るから初期化不要//new NyARMat(2,2);\r
-               final double[][] evec_array = evec.getArray();\r
+               final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
+               final NyARDoublePoint2d mean=this.__getSquareLine_mean;\r
+               final NyARDoublePoint2d ev=this.__getSquareLine_ev;\r
+       \r
+               \r
                for (int i = 0; i < 4; i++) {\r
                        final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
                        final int st = (int) (i_mkvertex[i] + w1);\r
@@ -364,17 +364,12 @@ public class NyARSquareDetector implements INyARSquareDetector
                                // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
                                return false;\r
                        }\r
-                       // pcaの準備\r
-                       input.realloc(n, 2);\r
-                       // バッチ取得\r
-                       dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n, input.getArray());\r
-\r
-                       // 主成分分析\r
-                       input.matrixPCA(evec, ev, mean);\r
+                       //主成分分析する。\r
+                       this._pca.pcaWithDistortionFactor(i_xcoord, i_ycoord, st, n,dist_factor, evec, ev,mean);\r
                        final NyARLinear l_line_i = l_line[i];\r
-                       l_line_i.run = evec_array[0][1];// line[i][0] = evec->m[1];\r
-                       l_line_i.rise = -evec_array[0][0];// line[i][1] = -evec->m[0];\r
-                       l_line_i.intercept = -(l_line_i.run * mean_array[0] + l_line_i.rise * mean_array[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
+                       l_line_i.run = evec.m01;// line[i][0] = evec->m[1];\r
+                       l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];\r
+                       l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
                }\r
 \r
                final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
@@ -396,74 +391,7 @@ public class NyARSquareDetector implements INyARSquareDetector
        }\r
 }\r
 \r
-/**\r
- * get_vertex関数を切り離すためのクラス\r
- * \r
- */\r
-final class NyARVertexCounter\r
-{\r
-       public final int[] vertex = new int[10];// 5まで削れる\r
-\r
-       public int number_of_vertex;\r
-\r
-       private double thresh;\r
-\r
-       private int[] x_coord;\r
-\r
-       private int[] y_coord;\r
-\r
-       public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)\r
-       {\r
-               this.number_of_vertex = 0;\r
-               this.thresh = i_thresh;\r
-               this.x_coord = i_x_coord;\r
-               this.y_coord = i_y_coord;\r
-               return get_vertex(st, ed);\r
-       }\r
 \r
-       /**\r
-        * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数\r
-        * \r
-        * @param x_coord\r
-        * @param y_coord\r
-        * @param st\r
-        * @param ed\r
-        * @param thresh\r
-        * @return\r
-        */\r
-       private boolean get_vertex(int st, int ed)\r
-       {\r
-               int v1 = 0;\r
-               final int[] lx_coord = this.x_coord;\r
-               final int[] ly_coord = this.y_coord;\r
-               final double a = ly_coord[ed] - ly_coord[st];\r
-               final double b = lx_coord[st] - lx_coord[ed];\r
-               final double c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
-               double dmax = 0;\r
-               for (int i = st + 1; i < ed; i++) {\r
-                       final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
-                       if (d * d > dmax) {\r
-                               dmax = d * d;\r
-                               v1 = i;\r
-                       }\r
-               }\r
-               if (dmax / (a * a + b * b) > thresh) {\r
-                       if (!get_vertex(st, v1)) {\r
-                               return false;\r
-                       }\r
-                       if (number_of_vertex > 5) {\r
-                               return false;\r
-                       }\r
-                       vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
-                       number_of_vertex++;// (*vnum)++;\r
-\r
-                       if (!get_vertex(v1, ed)) {\r
-                               return false;\r
-                       }\r
-               }\r
-               return true;\r
-       }\r
-}\r
 \r
 /**\r
  * ラベル同士の重なり(内包関係)を調べるクラスです。 ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。\r
diff --git a/src/jp/nyatla/nyartoolkit/core/NyARVertexCounter.java b/src/jp/nyatla/nyartoolkit/core/NyARVertexCounter.java
new file mode 100644 (file)
index 0000000..56fd6c5
--- /dev/null
@@ -0,0 +1,70 @@
+package jp.nyatla.nyartoolkit.core;\r
+\r
+/**\r
+ * get_vertex関数を切り離すためのクラス\r
+ * \r
+ */\r
+final public class NyARVertexCounter\r
+{\r
+       public final int[] vertex = new int[10];// 5まで削れる\r
+\r
+       public int number_of_vertex;\r
+\r
+       private double thresh;\r
+\r
+       private int[] x_coord;\r
+\r
+       private int[] y_coord;\r
+\r
+       public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)\r
+       {\r
+               this.number_of_vertex = 0;\r
+               this.thresh = i_thresh;\r
+               this.x_coord = i_x_coord;\r
+               this.y_coord = i_y_coord;\r
+               return get_vertex(st, ed);\r
+       }\r
+\r
+       /**\r
+        * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数\r
+        * \r
+        * @param x_coord\r
+        * @param y_coord\r
+        * @param st\r
+        * @param ed\r
+        * @param thresh\r
+        * @return\r
+        */\r
+       private boolean get_vertex(int st, int ed)\r
+       {\r
+               int v1 = 0;\r
+               final int[] lx_coord = this.x_coord;\r
+               final int[] ly_coord = this.y_coord;\r
+               final double a = ly_coord[ed] - ly_coord[st];\r
+               final double b = lx_coord[st] - lx_coord[ed];\r
+               final double c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
+               double dmax = 0;\r
+               for (int i = st + 1; i < ed; i++) {\r
+                       final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+                       if (d * d > dmax) {\r
+                               dmax = d * d;\r
+                               v1 = i;\r
+                       }\r
+               }\r
+               if (dmax / (a * a + b * b) > thresh) {\r
+                       if (!get_vertex(st, v1)) {\r
+                               return false;\r
+                       }\r
+                       if (number_of_vertex > 5) {\r
+                               return false;\r
+                       }\r
+                       vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
+                       number_of_vertex++;// (*vnum)++;\r
+\r
+                       if (!get_vertex(v1, ed)) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
index 92c3975..555a5d2 100644 (file)
@@ -220,5 +220,43 @@ final public class NyARCameraDistortionFactor
                        o_ideal[j][1] = py / d3 + d1;\r
                }\r
                return;\r
+       }\r
+       public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord)\r
+       {\r
+               double z02, z0, q, z, px, py, opttmp_1;\r
+               final double d0 = this._f0;\r
+               final double d1 = this._f1;\r
+               final double d3 = this._f3;\r
+               final double p = this._f2 / 100000000.0;\r
+               for (int j = 0; j < i_num; j++) {\r
+\r
+                       px = i_x_coord[i_start + j] - d0;\r
+                       py = i_y_coord[i_start + j] - d1;\r
+\r
+                       z02 = px * px + py * py;\r
+                       q = z0 = Math.sqrt(z02);// Optimize//q = z0 = Math.sqrt(px*px+py*py);\r
+\r
+                       for (int i = 1;; i++) {\r
+                               if (z0 != 0.0) {\r
+                                       // Optimize opttmp_1\r
+                                       opttmp_1 = p * z02;\r
+                                       z = z0 - ((1.0 - opttmp_1) * z0 - q)/ (1.0 - 3.0 * opttmp_1);\r
+                                       px = px * z / z0;\r
+                                       py = py * z / z0;\r
+                               } else {\r
+                                       px = 0.0;\r
+                                       py = 0.0;\r
+                                       break;\r
+                               }\r
+                               if (i == PD_LOOP) {\r
+                                       break;\r
+                               }\r
+                               z02 = px * px + py * py;\r
+                               z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);\r
+                       }\r
+                       o_x_coord[j] = px / d3 + d0;\r
+                       o_y_coord[j] = py / d3 + d1;\r
+               }\r
+               return;\r
        }       \r
 }\r
diff --git a/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java b/src/jp/nyatla/nyartoolkit/core/pca2d/INyARPca2d.java
new file mode 100644 (file)
index 0000000..fb6511b
--- /dev/null
@@ -0,0 +1,65 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\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.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+\r
+public interface INyARPca2d\r
+{\r
+       /**\r
+        * 通常のPCA\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_start\r
+        * @param i_number_of_point\r
+        * @param o_evec\r
+        * @param o_ev\r
+        * @param o_mean\r
+        * @throws NyARException\r
+        */\r
+       public void pca(double[] i_x,double[] i_y,int i_start,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException;\r
+       /**\r
+        * カメラ歪み補正つきのPCA\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_start\r
+        * @param i_number_of_point\r
+        * @param i_factor\r
+        * @param o_evec\r
+        * @param o_mean\r
+        * @throws NyARException\r
+        */\r
+       public void pcaWithDistortionFactor(int[] i_x,int[] i_y,int i_start,int i_number_of_point,NyARCameraDistortionFactor i_factor,NyARDoubleMatrix22 o_evec,NyARDoublePoint2d o_ev, NyARDoublePoint2d o_mean) throws NyARException;\r
+}\r
diff --git a/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java b/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java
new file mode 100644 (file)
index 0000000..4bed108
--- /dev/null
@@ -0,0 +1,97 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\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.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.NyARVec;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+/**\r
+ * NyARMatrixを利用した主成分分析\r
+ * ARToolKitと同じ処理をします。\r
+ */\r
+public class NyARPca2d_MatrixPCA implements INyARPca2d\r
+{\r
+       private final NyARMat __pca_input = new NyARMat(1, 2);\r
+       private final NyARMat __pca_evec = new NyARMat(2, 2);\r
+       private final NyARVec __pca_ev = new NyARVec(2);\r
+       private final NyARVec __pca_mean = new NyARVec(2);      \r
+       \r
+       public void pca(double[] i_x,double[] i_y,int i_start,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException\r
+       {\r
+               final NyARMat input = this.__pca_input;// 次処理で初期化される。\r
+               final double[][] input_array=input.getArray();\r
+               // pcaの準備\r
+               input.realloc(i_number_of_point, 2);\r
+               System.arraycopy(i_x, 0, input_array[0], i_start, i_number_of_point);\r
+               System.arraycopy(i_y, 0, input_array[1], i_start, i_number_of_point);\r
+               // 主成分分析\r
+               input.matrixPCA(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
+               final double[] mean_array = this.__pca_mean.getArray();\r
+               final double[][] evec_array = this.__pca_evec.getArray();\r
+               final double[] ev_array=this.__pca_ev.getArray();\r
+               o_evec.m00=evec_array[0][0];\r
+               o_evec.m01=evec_array[0][1];\r
+               o_evec.m10=evec_array[1][0];\r
+               o_evec.m11=evec_array[1][1];\r
+               o_ev.x=ev_array[0];\r
+               o_ev.x=ev_array[1];\r
+               o_mean.x=mean_array[0];\r
+               o_mean.y=mean_array[1];\r
+               return;\r
+               \r
+       }\r
+\r
+       public void pcaWithDistortionFactor(int[] i_x,int[] i_y,int i_start,int i_number_of_point,NyARCameraDistortionFactor i_factor,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException\r
+       {\r
+               final NyARMat input = this.__pca_input;// 次処理で初期化される。             \r
+               // pcaの準備\r
+               input.realloc(i_number_of_point, 2);\r
+               i_factor.observ2IdealBatch(i_x, i_y, i_start, i_number_of_point, input.getArray());\r
+               // 主成分分析\r
+               input.matrixPCA(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
+               final double[] mean_array = this.__pca_mean.getArray();\r
+               final double[][] evec_array = this.__pca_evec.getArray();\r
+               final double[] ev_array=this.__pca_ev.getArray();\r
+               o_evec.m00=evec_array[0][0];\r
+               o_evec.m01=evec_array[0][1];\r
+               o_evec.m10=evec_array[1][0];\r
+               o_evec.m11=evec_array[1][1];\r
+               o_ev.x=ev_array[0];\r
+               o_ev.x=ev_array[1];\r
+               o_mean.x=mean_array[0];\r
+               o_mean.y=mean_array[1];\r
+               return;\r
+       }\r
+}\r
diff --git a/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java b/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA_O2.java
new file mode 100644 (file)
index 0000000..f5c6771
--- /dev/null
@@ -0,0 +1,250 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\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.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * ARToolkitのPCA関数を二次元に特化させて単純化したもの\r
+ *\r
+ */\r
+public class NyARPca2d_MatrixPCA_O2 implements INyARPca2d\r
+{\r
+       private double _x[];\r
+\r
+       private double _y[];\r
+\r
+       private int _number_of_data;\r
+\r
+       private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
+\r
+       private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100\r
+\r
+       private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16\r
+       public NyARPca2d_MatrixPCA_O2(int i_max_points)\r
+       {\r
+               this._x=new double[i_max_points];\r
+               this._y=new double[i_max_points];\r
+               this._number_of_data=0;\r
+               return;\r
+       }\r
+\r
+\r
+       /**\r
+        * static int QRM( ARMat *a, ARVec *dv )の代替関数\r
+        * \r
+        * @param a\r
+        * @param dv\r
+        * @throws NyARException\r
+        */\r
+       private static void PCA_QRM(NyARDoubleMatrix22 o_matrix, NyARDoublePoint2d dv) throws NyARException\r
+       {\r
+               double w, t, s, x, y, c;\r
+               double ev1;\r
+               double dv_x,dv_y;\r
+               double mat00,mat01,mat10,mat11;\r
+               // <this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+               dv_x = o_matrix.m00;// this.m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];\r
+               ev1 = o_matrix.m01;// this.m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];\r
+               dv_y = o_matrix.m11;// this.m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];\r
+               // 単位行列にする。\r
+               mat00 = mat11 = 1;\r
+               mat01 = mat10 = 0;\r
+               // </this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+\r
+               // int j = 1;\r
+               // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))\r
+               // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {\r
+               // j--;\r
+               // }\r
+               // if (j == 0) {\r
+               int iter = 0;\r
+               do {\r
+                       iter++;\r
+                       if (iter > PCA_MAX_ITER) {\r
+                               break;\r
+                       }\r
+                       w = (dv_x - dv_y) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ?\r
+                       t = ev1 * ev1;// t = ev->v[h] * ev->v[h];\r
+                       s = Math.sqrt(w * w + t);\r
+                       if (w < 0) {\r
+                               s = -s;\r
+                       }\r
+                       x = dv_x - dv_y + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);\r
+                       y = ev1;// y = ev->v[j+1];\r
+\r
+                       if (Math.abs(x) >= Math.abs(y)) {\r
+                               if (Math.abs(x) > PCA_VZERO) {\r
+                                       t = -y / x;\r
+                                       c = 1 / Math.sqrt(t * t + 1);\r
+                                       s = t * c;\r
+                               } else {\r
+                                       c = 1.0;\r
+                                       s = 0.0;\r
+                               }\r
+                       } else {\r
+                               t = -x / y;\r
+                               s = 1.0 / Math.sqrt(t * t + 1);\r
+                               c = t * s;\r
+                       }\r
+                       w = dv_x - dv_y;// w = dv->v[k] -dv->v[k+1];\r
+                       t = (w * s + 2 * c * ev1) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;\r
+                       dv_x -= t;// dv->v[k] -= t;\r
+                       dv_y += t;// dv->v[k+1] += t;\r
+                       ev1 += s * (c * w - 2 * s * ev1);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);\r
+\r
+                       x = mat00;// x = a->m[k*dim+i];\r
+                       y = mat10;// y = a->m[(k+1)*dim+i];\r
+                       mat00 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+                       mat10 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+                       \r
+                       x = mat01;// x = a->m[k*dim+i];\r
+                       y = mat11;// y = a->m[(k+1)*dim+i];\r
+                       mat01 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+                       mat11 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+               } while (Math.abs(ev1) > PCA_EPS * (Math.abs(dv_x) + Math.abs(dv_y)));\r
+               // }\r
+\r
+               t = dv_x;// t = dv->v[h];\r
+               if (dv_y > t) {// if( dv->v[i] > t ) {\r
+                       t = dv_y;// t = dv->v[h];\r
+                       dv_y = dv_x;// dv->v[h] = dv->v[k];\r
+                       dv_x = t;// dv->v[k] = t;\r
+                       // 行の入れ替え\r
+                       o_matrix.m00 = mat10;\r
+                       o_matrix.m01 = mat11;\r
+                       o_matrix.m10 = mat00;           \r
+                       o_matrix.m11 = mat01;\r
+                       \r
+               } else {\r
+                       // 行の入れ替えはなし\r
+                       o_matrix.m00 = mat00;\r
+                       o_matrix.m01 = mat01;\r
+                       o_matrix.m10 = mat10;           \r
+                       o_matrix.m11 = mat11;\r
+               }\r
+               dv.x=dv_x;\r
+               dv.y=dv_y;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * static int PCA( ARMat *input, ARMat *output, ARVec *ev )\r
+        * \r
+        * @param output\r
+        * @param o_ev\r
+        * @throws NyARException\r
+        */\r
+       private void PCA_PCA(NyARDoubleMatrix22 o_matrix, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException\r
+       {\r
+               // double[] mean_array=mean.getArray();\r
+               // mean.zeroClear();\r
+\r
+               //PCA_EXの処理\r
+               double sx = 0;\r
+               double sy = 0;\r
+               final int number_of_data = this._number_of_data;\r
+               for (int i = 0; i < number_of_data; i++) {\r
+                       sx += this._x[i];\r
+                       sy += this._y[i];\r
+               }\r
+               sx = sx / number_of_data;\r
+               sy = sy / number_of_data;\r
+               \r
+               //PCA_CENTERとPCA_xt_by_xを一緒に処理\r
+               final double srow = Math.sqrt((double) this._number_of_data);\r
+               double w00, w11, w10;\r
+               w00 = w11 = w10 = 0.0;// *out = 0.0;\r
+               for (int i = 0; i < number_of_data; i++) {\r
+                       final double x = (this._x[i] - sx) / srow;\r
+                       final double y = (this._y[i] - sy) / srow;\r
+                       w00 += (x * x);// *out += *in1 * *in2;\r
+                       w10 += (x * y);// *out += *in1 * *in2;\r
+                       w11 += (y * y);// *out += *in1 * *in2;\r
+               }\r
+               o_matrix.m00=w00;\r
+               o_matrix.m01=o_matrix.m10=w10;\r
+               o_matrix.m11=w11;\r
+               \r
+               //PCA_PCAの処理\r
+               PCA_QRM(o_matrix, o_ev);\r
+               // m2 = o_output.m;// m2 = output->m;\r
+               if (o_ev.x < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+                       o_ev.x = 0.0;// ev->v[i] = 0.0;\r
+                       o_matrix.m00 = 0.0;// *(m2++) = 0.0;\r
+                       o_matrix.m01 = 0.0;// *(m2++) = 0.0;\r
+               }\r
+\r
+               if (o_ev.y < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+                       o_ev.y = 0.0;// ev->v[i] = 0.0;\r
+                       o_matrix.m10 = 0.0;// *(m2++) = 0.0;\r
+                       o_matrix.m11 = 0.0;// *(m2++) = 0.0;\r
+               }\r
+               o_mean.x=sx;\r
+               o_mean.y=sy;\r
+               // }\r
+               return;\r
+       }\r
+       public void pca(double[] i_x,double[] i_y,int i_start,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException\r
+       {\r
+               assert(this._x.length>i_number_of_point);               \r
+               this._number_of_data = i_number_of_point;\r
+               System.arraycopy(i_x, 0, this._x, i_start, i_number_of_point);\r
+               System.arraycopy(i_y, 0, this._y, i_start, i_number_of_point);\r
+               \r
+               PCA_PCA(o_evec, o_ev,o_mean);\r
+\r
+               final double sum = o_ev.x + o_ev.y;\r
+               // For順変更禁止\r
+               o_ev.x /= sum;// ev->v[i] /= sum;\r
+               o_ev.y /= sum;// ev->v[i] /= sum;\r
+               return; \r
+       }\r
+       \r
+       public void pcaWithDistortionFactor(int[] i_x,int[] i_y,int i_start,int i_number_of_point,NyARCameraDistortionFactor i_factor,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException\r
+       {\r
+               assert(this._x.length>i_number_of_point);\r
+               this._number_of_data = i_number_of_point;\r
+               i_factor.observ2IdealBatch(i_x, i_y, i_start, i_number_of_point, this._x, this._y);\r
+\r
+               PCA_PCA(o_evec,o_ev,o_mean);\r
+\r
+               final double sum = o_ev.x + o_ev.y;\r
+               // For順変更禁止\r
+               o_ev.x /= sum;// ev->v[i] /= sum;\r
+               o_ev.y /= sum;// ev->v[i] /= sum;\r
+               return; \r
+       }\r
+}\r
index 5533f04..4dd46a1 100644 (file)
@@ -36,7 +36,7 @@ import jp.nyatla.nyartoolkit.core.NyARSquare;
 import jp.nyatla.nyartoolkit.core.param.*;\r
 import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.NyARFitVecCalculator;\r
 import jp.nyatla.nyartoolkit.core.transmat.optimize.*;\r
-import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.NyARRotMatrix;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
 import jp.nyatla.nyartoolkit.core.types.*;\r
 \r
 \r
@@ -51,24 +51,26 @@ public class NyARTransMat implements INyARTransMat
 \r
        private final NyARDoublePoint2d _center=new NyARDoublePoint2d(0,0);\r
        private final NyARTransOffset _offset=new NyARTransOffset();\r
-       private final NyARRotMatrix _rotmatrix;\r
-       private final NyARFitVecCalculator _calculator;\r
-       private final INyARRotTransOptimize _mat_optimize;\r
+       protected NyARRotMatrix _rotmatrix;\r
+       protected NyARFitVecCalculator _calculator;\r
+       protected INyARRotTransOptimize _mat_optimize;\r
 \r
-       protected NyARTransMat(NyARParam i_param,NyARRotMatrix i_rotmatrix,INyARRotTransOptimize i_optimize)\r
+       /**\r
+        * 派生クラスで自分でメンバオブジェクトを指定したい場合はこちらを使う。\r
+        *\r
+        */\r
+       protected NyARTransMat()\r
        {\r
-               final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();\r
-               final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
-               this._calculator=new NyARFitVecCalculator(pmat,dist);\r
-               this._rotmatrix =i_rotmatrix;\r
-               this._mat_optimize=i_optimize;          \r
+               //_calculator,_rotmatrix,_mat_optimizeをコンストラクタの終了後に\r
+               //作成して割り当ててください。\r
+               return;\r
        }\r
        public NyARTransMat(NyARParam i_param) throws NyARException\r
        {\r
                final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();\r
                final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
                this._calculator=new NyARFitVecCalculator(pmat,dist);\r
-               this._rotmatrix = new NyARRotMatrix(pmat);\r
+               this._rotmatrix = new NyARRotMatrix_ARToolKit(pmat);\r
                this._mat_optimize=new NyARRotTransOptimize(pmat);\r
        }\r
 \r
index a105225..b3a4e93 100644 (file)
@@ -35,85 +35,18 @@ import jp.nyatla.nyartoolkit.NyARException;
 import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
 import jp.nyatla.nyartoolkit.core.types.*;\r
 import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;\r
-import jp.nyatla.nyartoolkit.core.param.*;\r
 /**\r
  * 回転行列計算用の、3x3行列\r
  *\r
  */\r
-public class NyARRotMatrix extends NyARDoubleMatrix33\r
+public abstract class NyARRotMatrix extends NyARDoubleMatrix33\r
 {      \r
        /**\r
-        * インスタンスを準備します。\r
-        * \r
-        * @param i_param\r
+        * NyARTransMatResultの内容からNyARRotMatrixを復元します。\r
+        * @param i_prev_result\r
         */\r
-       public NyARRotMatrix(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
-       {\r
-               this.__initRot_vec1=new NyARRotVector(i_matrix);\r
-               this.__initRot_vec2=new NyARRotVector(i_matrix);\r
-               return;\r
-       }\r
-       final private NyARRotVector __initRot_vec1;\r
-       final private NyARRotVector __initRot_vec2;\r
-\r
-       \r
-\r
-       public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
-       {\r
-\r
-               this.m00=i_prev_result.m00;\r
-               this.m01=i_prev_result.m01;\r
-               this.m02=i_prev_result.m02;\r
-\r
-               this.m10=i_prev_result.m10;\r
-               this.m11=i_prev_result.m11;\r
-               this.m12=i_prev_result.m12;\r
-\r
-               this.m20=i_prev_result.m20;\r
-               this.m21=i_prev_result.m21;\r
-               this.m22=i_prev_result.m22;\r
-               return;\r
-       }       \r
-       \r
-       \r
-       public final void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
-       {\r
-               final NyARRotVector vec1=this.__initRot_vec1;\r
-               final NyARRotVector vec2=this.__initRot_vec2;\r
-\r
-               //向かい合った辺から、2本のベクトルを計算\r
-               \r
-               //軸1\r
-               vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);\r
-               vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);\r
-\r
-               //軸2\r
-               vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);\r
-               vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);\r
-\r
-               //回転の最適化?\r
-               NyARRotVector.checkRotation(vec1,vec2);\r
-\r
-               this.m00 =vec1.v1;\r
-               this.m10 =vec1.v2;\r
-               this.m20 =vec1.v3;\r
-               this.m01 =vec2.v1;\r
-               this.m11 =vec2.v2;\r
-               this.m21 =vec2.v3;\r
-               \r
-               //最後の軸を計算\r
-               final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;\r
-               final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;\r
-               final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;\r
-               final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);\r
-               this.m02 = w02/w;\r
-               this.m12 = w12/w;\r
-               this.m22 = w22/w;\r
-               return;\r
-       }\r
-\r
-       \r
-\r
+       public abstract void initRotByPrevResult(NyARTransMatResult i_prev_result);\r
+       public abstract void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException;\r
        /**\r
         * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc )\r
         * Optimize:2008.04.20:STEP[481→433]\r
@@ -121,182 +54,25 @@ public class NyARRotMatrix extends NyARDoubleMatrix33
         * @param o_angle\r
         * @return\r
         */\r
-       public final void getAngle(final NyARDoublePoint3d o_angle)\r
-       {\r
-               double a,b,c;\r
-               double sina, cosa, sinb,cosb,sinc, cosc;\r
-               \r
-               if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {\r
-                       this.m22 = 1.0;// <Optimize/>rot[2][2] = 1.0;\r
-               } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {\r
-                       this.m22 = -1.0;// <Optimize/>rot[2][2] = -1.0;\r
-               }\r
-               cosb =this.m22;// <Optimize/>cosb = rot[2][2];\r
-               b = Math.acos(cosb);\r
-               sinb =Math.sin(b);\r
-               final double rot02=this.m02;\r
-               final double rot12=this.m12;\r
-               if (b >= 0.000001 || b <= -0.000001) {\r
-                       cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;\r
-                       sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;\r
-                       if (cosa > 1.0) {\r
-                               /* printf("cos(alph) = %f\n", cosa); */\r
-                               cosa = 1.0;\r
-                               sina = 0.0;\r
-                       }\r
-                       if (cosa < -1.0) {\r
-                               /* printf("cos(alph) = %f\n", cosa); */\r
-                               cosa = -1.0;\r
-                               sina = 0.0;\r
-                       }\r
-                       if (sina > 1.0) {\r
-                               /* printf("sin(alph) = %f\n", sina); */\r
-                               sina = 1.0;\r
-                               cosa = 0.0;\r
-                       }\r
-                       if (sina < -1.0) {\r
-                               /* printf("sin(alph) = %f\n", sina); */\r
-                               sina = -1.0;\r
-                               cosa = 0.0;\r
-                       }\r
-                       a = Math.acos(cosa);\r
-                       if (sina < 0) {\r
-                               a = -a;\r
-                       }\r
-                       // <Optimize>\r
-                       // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
-                       // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
-                       final double tmp = (rot02 * rot02 + rot12 * rot12);\r
-                       sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;\r
-                       cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;\r
-                       // </Optimize>\r
-\r
-                       if (cosc > 1.0) {\r
-                               /* printf("cos(r) = %f\n", cosc); */\r
-                               cosc = 1.0;\r
-                               sinc = 0.0;\r
-                       }\r
-                       if (cosc < -1.0) {\r
-                               /* printf("cos(r) = %f\n", cosc); */\r
-                               cosc = -1.0;\r
-                               sinc = 0.0;\r
-                       }\r
-                       if (sinc > 1.0) {\r
-                               /* printf("sin(r) = %f\n", sinc); */\r
-                               sinc = 1.0;\r
-                               cosc = 0.0;\r
-                       }\r
-                       if (sinc < -1.0) {\r
-                               /* printf("sin(r) = %f\n", sinc); */\r
-                               sinc = -1.0;\r
-                               cosc = 0.0;\r
-                       }\r
-                       c = Math.acos(cosc);\r
-                       if (sinc < 0) {\r
-                               c = -c;\r
-                       }\r
-               } else {\r
-                       a = b = 0.0;\r
-                       cosa = cosb = 1.0;\r
-                       sina = sinb = 0.0;\r
-                       cosc=this.m00;//cosc = rot[0];// <Optimize/>cosc = rot[0][0];\r
-                       sinc=this.m01;//sinc = rot[1];// <Optimize/>sinc = rot[1][0];\r
-                       if (cosc > 1.0) {\r
-                               /* printf("cos(r) = %f\n", cosc); */\r
-                               cosc = 1.0;\r
-                               sinc = 0.0;\r
-                       }\r
-                       if (cosc < -1.0) {\r
-                               /* printf("cos(r) = %f\n", cosc); */\r
-                               cosc = -1.0;\r
-                               sinc = 0.0;\r
-                       }\r
-                       if (sinc > 1.0) {\r
-                               /* printf("sin(r) = %f\n", sinc); */\r
-                               sinc = 1.0;\r
-                               cosc = 0.0;\r
-                       }\r
-                       if (sinc < -1.0) {\r
-                               /* printf("sin(r) = %f\n", sinc); */\r
-                               sinc = -1.0;\r
-                               cosc = 0.0;\r
-                       }\r
-                       c = Math.acos(cosc);\r
-                       if (sinc < 0) {\r
-                               c = -c;\r
-                       }\r
-               }\r
-               o_angle.x = a;// wa.value=a;//*wa = a;\r
-               o_angle.y = b;// wb.value=b;//*wb = b;\r
-               o_angle.z = c;// wc.value=c;//*wc = c;\r
-               return;\r
-       }\r
+       public abstract void getAngle(final NyARDoublePoint3d o_angle);\r
        /**\r
         * 回転角から回転行列を計算してセットします。\r
         * @param i_x\r
         * @param i_y\r
         * @param i_z\r
         */\r
-       public final void setAngle(final double i_x, final double i_y, final double i_z)\r
-       {\r
-               final double sina = Math.sin(i_x);\r
-               final double cosa = Math.cos(i_x);\r
-               final double sinb = Math.sin(i_y);\r
-               final double cosb = Math.cos(i_y);\r
-               final double sinc = Math.sin(i_z);\r
-               final double cosc = Math.cos(i_z);\r
-               // Optimize\r
-               final double CACA = cosa * cosa;\r
-               final double SASA = sina * sina;\r
-               final double SACA = sina * cosa;\r
-               final double SASB = sina * sinb;\r
-               final double CASB = cosa * sinb;\r
-               final double SACACB = SACA * cosb;\r
-\r
-               this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
-               this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
-               this.m02 = CASB;\r
-               this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;\r
-               this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;\r
-               this.m12 = SASB;\r
-               this.m20 = -CASB * cosc - SASB * sinc;\r
-               this.m21 = CASB * sinc - SASB * cosc;\r
-               this.m22 = cosb;\r
-               return;\r
-       }\r
+       public abstract void setAngle(final double i_x, final double i_y, final double i_z);\r
        /**\r
         * i_in_pointを変換行列で座標変換する。\r
         * @param i_in_point\r
         * @param i_out_point\r
-        */\r
-       public final void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point)\r
-       {\r
-               final double x=i_in_point.x;\r
-               final double y=i_in_point.y;\r
-               final double z=i_in_point.z;\r
-               i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
-               i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
-               i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
-               return;\r
-       }\r
+        */     \r
+       public abstract void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point);\r
        /**\r
         * 複数の頂点を一括して変換する\r
         * @param i_in_point\r
         * @param i_out_point\r
         * @param i_number_of_vertex\r
         */\r
-       public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex)\r
-       {\r
-               for(int i=i_number_of_vertex-1;i>=0;i--){\r
-                       final NyARDoublePoint3d out_ptr=i_out_point[i];\r
-                       final NyARDoublePoint3d in_ptr=i_in_point[i];\r
-                       final double x=in_ptr.x;\r
-                       final double y=in_ptr.y;\r
-                       final double z=in_ptr.z;\r
-                       out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
-                       out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
-                       out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
-               }\r
-               return;\r
-       }       \r
+       public abstract void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex);\r
 }\r
diff --git a/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java b/src/jp/nyatla/nyartoolkit/core/transmat/rotmatrix/NyARRotMatrix_ARToolKit.java
new file mode 100644 (file)
index 0000000..7338df2
--- /dev/null
@@ -0,0 +1,301 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\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.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ *\r
+ */\r
+public class NyARRotMatrix_ARToolKit extends NyARRotMatrix\r
+{      \r
+       /**\r
+        * インスタンスを準備します。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARRotMatrix_ARToolKit(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+       {\r
+               this.__initRot_vec1=new NyARRotVector(i_matrix);\r
+               this.__initRot_vec2=new NyARRotVector(i_matrix);\r
+               return;\r
+       }\r
+       final private NyARRotVector __initRot_vec1;\r
+       final private NyARRotVector __initRot_vec2;\r
+\r
+       \r
+\r
+       public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
+       {\r
+\r
+               this.m00=i_prev_result.m00;\r
+               this.m01=i_prev_result.m01;\r
+               this.m02=i_prev_result.m02;\r
+\r
+               this.m10=i_prev_result.m10;\r
+               this.m11=i_prev_result.m11;\r
+               this.m12=i_prev_result.m12;\r
+\r
+               this.m20=i_prev_result.m20;\r
+               this.m21=i_prev_result.m21;\r
+               this.m22=i_prev_result.m22;\r
+               return;\r
+       }       \r
+       \r
+       \r
+       public final void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
+       {\r
+               final NyARRotVector vec1=this.__initRot_vec1;\r
+               final NyARRotVector vec2=this.__initRot_vec2;\r
+\r
+               //向かい合った辺から、2本のベクトルを計算\r
+               \r
+               //軸1\r
+               vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);\r
+               vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);\r
+\r
+               //軸2\r
+               vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);\r
+               vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);\r
+\r
+               //回転の最適化?\r
+               NyARRotVector.checkRotation(vec1,vec2);\r
+\r
+               this.m00 =vec1.v1;\r
+               this.m10 =vec1.v2;\r
+               this.m20 =vec1.v3;\r
+               this.m01 =vec2.v1;\r
+               this.m11 =vec2.v2;\r
+               this.m21 =vec2.v3;\r
+               \r
+               //最後の軸を計算\r
+               final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;\r
+               final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;\r
+               final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;\r
+               final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);\r
+               this.m02 = w02/w;\r
+               this.m12 = w12/w;\r
+               this.m22 = w22/w;\r
+               return;\r
+       }\r
+\r
+       \r
+\r
+       /**\r
+        * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc )\r
+        * Optimize:2008.04.20:STEP[481→433]\r
+        * 3x3変換行列から、回転角を復元して返します。\r
+        * @param o_angle\r
+        * @return\r
+        */\r
+       public final void getAngle(final NyARDoublePoint3d o_angle)\r
+       {\r
+               double a,b,c;\r
+               double sina, cosa, sinb,cosb,sinc, cosc;\r
+               \r
+               if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {\r
+                       this.m22 = 1.0;// <Optimize/>rot[2][2] = 1.0;\r
+               } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {\r
+                       this.m22 = -1.0;// <Optimize/>rot[2][2] = -1.0;\r
+               }\r
+               cosb =this.m22;// <Optimize/>cosb = rot[2][2];\r
+               b = Math.acos(cosb);\r
+               sinb =Math.sin(b);\r
+               final double rot02=this.m02;\r
+               final double rot12=this.m12;\r
+               if (b >= 0.000001 || b <= -0.000001) {\r
+                       cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;\r
+                       sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;\r
+                       if (cosa > 1.0) {\r
+                               /* printf("cos(alph) = %f\n", cosa); */\r
+                               cosa = 1.0;\r
+                               sina = 0.0;\r
+                       }\r
+                       if (cosa < -1.0) {\r
+                               /* printf("cos(alph) = %f\n", cosa); */\r
+                               cosa = -1.0;\r
+                               sina = 0.0;\r
+                       }\r
+                       if (sina > 1.0) {\r
+                               /* printf("sin(alph) = %f\n", sina); */\r
+                               sina = 1.0;\r
+                               cosa = 0.0;\r
+                       }\r
+                       if (sina < -1.0) {\r
+                               /* printf("sin(alph) = %f\n", sina); */\r
+                               sina = -1.0;\r
+                               cosa = 0.0;\r
+                       }\r
+                       a = Math.acos(cosa);\r
+                       if (sina < 0) {\r
+                               a = -a;\r
+                       }\r
+                       // <Optimize>\r
+                       // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+                       // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+                       final double tmp = (rot02 * rot02 + rot12 * rot12);\r
+                       sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;\r
+                       cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;\r
+                       // </Optimize>\r
+\r
+                       if (cosc > 1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = 1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (cosc < -1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = -1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (sinc > 1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = 1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       if (sinc < -1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = -1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       c = Math.acos(cosc);\r
+                       if (sinc < 0) {\r
+                               c = -c;\r
+                       }\r
+               } else {\r
+                       a = b = 0.0;\r
+                       cosa = cosb = 1.0;\r
+                       sina = sinb = 0.0;\r
+                       cosc=this.m00;//cosc = rot[0];// <Optimize/>cosc = rot[0][0];\r
+                       sinc=this.m01;//sinc = rot[1];// <Optimize/>sinc = rot[1][0];\r
+                       if (cosc > 1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = 1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (cosc < -1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = -1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (sinc > 1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = 1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       if (sinc < -1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = -1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       c = Math.acos(cosc);\r
+                       if (sinc < 0) {\r
+                               c = -c;\r
+                       }\r
+               }\r
+               o_angle.x = a;// wa.value=a;//*wa = a;\r
+               o_angle.y = b;// wb.value=b;//*wb = b;\r
+               o_angle.z = c;// wc.value=c;//*wc = c;\r
+               return;\r
+       }\r
+       /**\r
+        * 回転角から回転行列を計算してセットします。\r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_z\r
+        */\r
+       public final void setAngle(final double i_x, final double i_y, final double i_z)\r
+       {\r
+               final double sina = Math.sin(i_x);\r
+               final double cosa = Math.cos(i_x);\r
+               final double sinb = Math.sin(i_y);\r
+               final double cosb = Math.cos(i_y);\r
+               final double sinc = Math.sin(i_z);\r
+               final double cosc = Math.cos(i_z);\r
+               // Optimize\r
+               final double CACA = cosa * cosa;\r
+               final double SASA = sina * sina;\r
+               final double SACA = sina * cosa;\r
+               final double SASB = sina * sinb;\r
+               final double CASB = cosa * sinb;\r
+               final double SACACB = SACA * cosb;\r
+\r
+               this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+               this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+               this.m02 = CASB;\r
+               this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;\r
+               this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;\r
+               this.m12 = SASB;\r
+               this.m20 = -CASB * cosc - SASB * sinc;\r
+               this.m21 = CASB * sinc - SASB * cosc;\r
+               this.m22 = cosb;\r
+               return;\r
+       }\r
+       /**\r
+        * i_in_pointを変換行列で座標変換する。\r
+        * @param i_in_point\r
+        * @param i_out_point\r
+        */\r
+       public final void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point)\r
+       {\r
+               final double x=i_in_point.x;\r
+               final double y=i_in_point.y;\r
+               final double z=i_in_point.z;\r
+               i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
+               i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
+               i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
+               return;\r
+       }\r
+       /**\r
+        * 複数の頂点を一括して変換する\r
+        * @param i_in_point\r
+        * @param i_out_point\r
+        * @param i_number_of_vertex\r
+        */\r
+       public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex)\r
+       {\r
+               for(int i=i_number_of_vertex-1;i>=0;i--){\r
+                       final NyARDoublePoint3d out_ptr=i_out_point[i];\r
+                       final NyARDoublePoint3d in_ptr=i_in_point[i];\r
+                       final double x=in_ptr.x;\r
+                       final double y=in_ptr.y;\r
+                       final double z=in_ptr.z;\r
+                       out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
+                       out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
+                       out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
+               }\r
+               return;\r
+       }       \r
+}\r
index e5cc24c..13ada74 100644 (file)
@@ -36,5 +36,18 @@ public class NyARIntPoint
        public int x;\r
 \r
        public int y;\r
-\r
+       /**\r
+        * 配列ファクトリ\r
+        * @param i_number\r
+        * @return\r
+        */\r
+       public static NyARIntPoint[] createArray(int i_number)\r
+       {\r
+               NyARIntPoint[] ret=new NyARIntPoint[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARIntPoint();\r
+               }\r
+               return ret;\r
+       }\r
 }\r
index 5e51041..df0e062 100644 (file)
@@ -36,4 +36,11 @@ public class NyARLinear
        public double rise;//y軸の増加量\r
        public double run;//x軸の増加量\r
        public double intercept;//切片\r
+       public final void copyFrom(NyARLinear i_source)\r
+       {\r
+               this.rise=i_source.rise;\r
+               this.run=i_source.run;\r
+               this.intercept=i_source.intercept;\r
+               return;\r
+       }\r
 }\r
diff --git a/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java b/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix22.java
new file mode 100644 (file)
index 0000000..27097b2
--- /dev/null
@@ -0,0 +1,62 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\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.core.types.matrix;\r
+\r
+public class NyARDoubleMatrix22 implements INyARDoubleMatrix\r
+{\r
+       public double m00;\r
+       public double m01;\r
+       public double m10;\r
+       public double m11;\r
+       /**\r
+        * 遅いからあんまり使わないでね。\r
+        */\r
+       public void setValue(double[] i_value)\r
+       {\r
+               this.m00=i_value[0];\r
+               this.m01=i_value[1];\r
+               this.m10=i_value[3];\r
+               this.m11=i_value[4];\r
+               return;\r
+       }\r
+       /**\r
+        * 遅いからあんまり使わないでね。\r
+        */\r
+       public void getValue(double[] o_value)\r
+       {\r
+               o_value[0]=this.m00;\r
+               o_value[1]=this.m01;\r
+               o_value[3]=this.m10;\r
+               o_value[4]=this.m11;\r
+               return;\r
+       }\r
+}\r
@@ -29,7 +29,7 @@
  *     <airmail(at)ebony.plala.or.jp>\r
  * \r
  */\r
-package jp.nyatla.nyartoolkit.nymodel.x2;\r
+package jp.nyatla.nyartoolkit.core2.rasterfilter;\r
 \r
 import jp.nyatla.nyartoolkit.NyARException;\r
 import jp.nyatla.nyartoolkit.core.raster.*;\r
@@ -39,10 +39,10 @@ import jp.nyatla.nyartoolkit.core.*;
 \r
 \r
 /**\r
- * 矩形座標をPCAではなく、頂点座標そのものから計算する。\r
+ * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス\r
  *\r
  */\r
-public class NyARSquareDetector_X2 implements INyARSquareDetector\r
+public class NyARQrCodeDetector implements INyARSquareDetector\r
 {\r
        private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ\r
 \r
@@ -64,7 +64,7 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
         * \r
         * @param i_param\r
         */\r
-       public NyARSquareDetector_X2(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+       public NyARQrCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
        {\r
                this._width = i_size.w;\r
                this._height = i_size.h;\r
@@ -202,6 +202,12 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
                }       \r
                return;\r
        }\r
+       /**\r
+        * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。\r
+        * @param i_v1\r
+        * @param i_v2\r
+        * @param o_line\r
+        */\r
        final private void getLine(NyARDoublePoint2d i_v1,NyARDoublePoint2d i_v2,NyARLinear o_line)\r
        {\r
                final double x=i_v1.x-i_v2.x;\r
@@ -229,6 +235,7 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
                o_line.intercept=(i_v1.y+(o_line.run/o_line.rise)*(i_v1.x))*rise_;\r
                \r
        }\r
+/*\r
        private void getSquare(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square)\r
        {\r
                final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;             \r
@@ -245,11 +252,10 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
                getLine(vertex[1],vertex[0],o_square.line[0]);\r
                getLine(vertex[2],vertex[1],o_square.line[1]);\r
                getLine(vertex[3],vertex[2],o_square.line[2]);\r
-               getLine(vertex[0],vertex[3],o_square.line[3]);\r
-               \r
+               getLine(vertex[0],vertex[3],o_square.line[3]);  \r
                return;\r
        }\r
-\r
+*/\r
        /**\r
         * 辺からの対角線が最長になる点を対角線候補として返す。\r
         * \r
diff --git a/src/jp/nyatla/nyartoolkit/nymodel/x2/NyARRotMatrix_X2.java b/src/jp/nyatla/nyartoolkit/nymodel/x2/NyARRotMatrix_X2.java
new file mode 100644 (file)
index 0000000..249bc2f
--- /dev/null
@@ -0,0 +1,311 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\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.nymodel.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+\r
+\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ * \r
+ */\r
+public class NyARRotMatrix_X2 extends NyARRotMatrix\r
+{\r
+       private NyARSinTable _sin_table_ref;\r
+\r
+       /**\r
+        * インスタンスを準備します。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARRotMatrix_X2(NyARPerspectiveProjectionMatrix i_matrix,NyARSinTable i_sin_table_ref) throws NyARException\r
+       {\r
+               this.__initRot_vec1 = new NyARRotVector(i_matrix);\r
+               this.__initRot_vec2 = new NyARRotVector(i_matrix);\r
+               this._sin_table_ref=i_sin_table_ref;\r
+               return;\r
+       }\r
+\r
+       final private NyARRotVector __initRot_vec1;\r
+\r
+       final private NyARRotVector __initRot_vec2;\r
+\r
+       public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
+       {\r
+\r
+               this.m00 = i_prev_result.m00;\r
+               this.m01 = i_prev_result.m01;\r
+               this.m02 = i_prev_result.m02;\r
+\r
+               this.m10 = i_prev_result.m10;\r
+               this.m11 = i_prev_result.m11;\r
+               this.m12 = i_prev_result.m12;\r
+\r
+               this.m20 = i_prev_result.m20;\r
+               this.m21 = i_prev_result.m21;\r
+               this.m22 = i_prev_result.m22;\r
+               return;\r
+       }\r
+\r
+       public final void initRotBySquare(final NyARLinear[] i_linear, final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
+       {\r
+               final NyARRotVector vec1 = this.__initRot_vec1;\r
+               final NyARRotVector vec2 = this.__initRot_vec2;\r
+\r
+               // 向かい合った辺から、2本のベクトルを計算\r
+\r
+               // 軸1\r
+               vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);\r
+               vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);\r
+\r
+               // 軸2\r
+               vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);\r
+               vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);\r
+\r
+               // 回転の最適化?\r
+               NyARRotVector.checkRotation(vec1, vec2);\r
+\r
+               this.m00 = vec1.v1;\r
+               this.m10 = vec1.v2;\r
+               this.m20 = vec1.v3;\r
+               this.m01 = vec2.v1;\r
+               this.m11 = vec2.v2;\r
+               this.m21 = vec2.v3;\r
+\r
+               // 最後の軸を計算\r
+               final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;\r
+               final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;\r
+               final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;\r
+               final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);\r
+               this.m02 = w02 / w;\r
+               this.m12 = w12 / w;\r
+               this.m22 = w22 / w;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc ) Optimize:2008.04.20:STEP[481→433] 3x3変換行列から、回転角を復元して返します。\r
+        * \r
+        * @param o_angle\r
+        * @return\r
+        */\r
+       public final void getAngle(final NyARDoublePoint3d o_angle)\r
+       {\r
+               double a, b, c;\r
+               double sina, cosa, sinb, cosb, sinc, cosc;\r
+\r
+               if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {\r
+                       this.m22 = 1.0;// <Optimize/>rot[2][2] = 1.0;\r
+               } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {\r
+                       this.m22 = -1.0;// <Optimize/>rot[2][2] = -1.0;\r
+               }\r
+               cosb = this.m22;// <Optimize/>cosb = rot[2][2];\r
+               b = Math.acos(cosb);\r
+               sinb = this._sin_table_ref.sin(b);\r
+               final double rot02 = this.m02;\r
+               final double rot12 = this.m12;\r
+               if (b >= 0.000001 || b <= -0.000001) {\r
+                       cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;\r
+                       sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;\r
+                       if (cosa > 1.0) {\r
+                               /* printf("cos(alph) = %f\n", cosa); */\r
+                               cosa = 1.0;\r
+                               sina = 0.0;\r
+                       }\r
+                       if (cosa < -1.0) {\r
+                               /* printf("cos(alph) = %f\n", cosa); */\r
+                               cosa = -1.0;\r
+                               sina = 0.0;\r
+                       }\r
+                       if (sina > 1.0) {\r
+                               /* printf("sin(alph) = %f\n", sina); */\r
+                               sina = 1.0;\r
+                               cosa = 0.0;\r
+                       }\r
+                       if (sina < -1.0) {\r
+                               /* printf("sin(alph) = %f\n", sina); */\r
+                               sina = -1.0;\r
+                               cosa = 0.0;\r
+                       }\r
+                       a = Math.acos(cosa);\r
+                       if (sina < 0) {\r
+                               a = -a;\r
+                       }\r
+                       // <Optimize>\r
+                       // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+                       // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+                       final double tmp = (rot02 * rot02 + rot12 * rot12);\r
+                       sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;\r
+                       cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;\r
+                       // </Optimize>\r
+\r
+                       if (cosc > 1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = 1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (cosc < -1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = -1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (sinc > 1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = 1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       if (sinc < -1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = -1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       c = Math.acos(cosc);\r
+                       if (sinc < 0) {\r
+                               c = -c;\r
+                       }\r
+               } else {\r
+                       a = b = 0.0;\r
+                       cosa = cosb = 1.0;\r
+                       sina = sinb = 0.0;\r
+                       cosc = this.m00;// cosc = rot[0];// <Optimize/>cosc = rot[0][0];\r
+                       sinc = this.m01;// sinc = rot[1];// <Optimize/>sinc = rot[1][0];\r
+                       if (cosc > 1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = 1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (cosc < -1.0) {\r
+                               /* printf("cos(r) = %f\n", cosc); */\r
+                               cosc = -1.0;\r
+                               sinc = 0.0;\r
+                       }\r
+                       if (sinc > 1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = 1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       if (sinc < -1.0) {\r
+                               /* printf("sin(r) = %f\n", sinc); */\r
+                               sinc = -1.0;\r
+                               cosc = 0.0;\r
+                       }\r
+                       c = Math.acos(cosc);\r
+                       if (sinc < 0) {\r
+                               c = -c;\r
+                       }\r
+               }\r
+               o_angle.x = a;// wa.value=a;//*wa = a;\r
+               o_angle.y = b;// wb.value=b;//*wb = b;\r
+               o_angle.z = c;// wc.value=c;//*wc = c;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 回転角から回転行列を計算してセットします。\r
+        * \r
+        * @param i_x\r
+        * @param i_y\r
+        * @param i_z\r
+        */\r
+       public final void setAngle(final double i_x, final double i_y, final double i_z)\r
+       {\r
+               /*\r
+                * |cos(a) -sin(a) 0| |cos(b) 0 sin(b)| |cos(a-c) sin(a-c) 0| rot = |sin(a) cos(a) 0| |0 1 0 | |-sin(a-c) cos(a-c) 0| |0 0 1| |-sin(b) 0 cos(b)| |0 0 1|\r
+                */\r
+\r
+               double Sa, Sb, Ca, Cb, Sac, Cac, CaCb, SaCb;\r
+               Sa = this._sin_table_ref.sin(i_x);\r
+               Ca = this._sin_table_ref.cos(i_x);\r
+               Sb = this._sin_table_ref.sin(i_y);\r
+               Cb = this._sin_table_ref.cos(i_y);\r
+               Sac = this._sin_table_ref.sin(i_x - i_z);\r
+               Cac = this._sin_table_ref.cos(i_x - i_z);\r
+               CaCb = Ca * Cb;\r
+               SaCb = Sa * Cb;\r
+\r
+               this.m00 = CaCb * Cac + Sa * Sac;\r
+               this.m01 = CaCb * Sac - Sa * Cac;\r
+               this.m02 = Ca * Sb;\r
+               this.m10 = SaCb * Cac - Ca * Sac;\r
+               this.m11 = SaCb * Sac + Ca * Cac;\r
+               this.m12 = Sa * Sb;\r
+               this.m20 = -Sb * Cac;\r
+               this.m21 = -Sb * Sac;\r
+               this.m22 = Cb;\r
+\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * i_in_pointを変換行列で座標変換する。\r
+        * \r
+        * @param i_in_point\r
+        * @param i_out_point\r
+        */\r
+       public final void getPoint3d(final NyARDoublePoint3d i_in_point, final NyARDoublePoint3d i_out_point)\r
+       {\r
+               final double x = i_in_point.x;\r
+               final double y = i_in_point.y;\r
+               final double z = i_in_point.z;\r
+               i_out_point.x = this.m00 * x + this.m01 * y + this.m02 * z;\r
+               i_out_point.y = this.m10 * x + this.m11 * y + this.m12 * z;\r
+               i_out_point.z = this.m20 * x + this.m21 * y + this.m22 * z;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 複数の頂点を一括して変換する\r
+        * \r
+        * @param i_in_point\r
+        * @param i_out_point\r
+        * @param i_number_of_vertex\r
+        */\r
+       public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point, NyARDoublePoint3d[] i_out_point, int i_number_of_vertex)\r
+       {\r
+               for (int i = i_number_of_vertex - 1; i >= 0; i--) {\r
+                       final NyARDoublePoint3d out_ptr = i_out_point[i];\r
+                       final NyARDoublePoint3d in_ptr = i_in_point[i];\r
+                       final double x = in_ptr.x;\r
+                       final double y = in_ptr.y;\r
+                       final double z = in_ptr.z;\r
+                       out_ptr.x = this.m00 * x + this.m01 * y + this.m02 * z;\r
+                       out_ptr.y = this.m10 * x + this.m11 * y + this.m12 * z;\r
+                       out_ptr.z = this.m20 * x + this.m21 * y + this.m22 * z;\r
+               }\r
+               return;\r
+       }\r
+}\r
index 9d7e8ed..0ec2979 100644 (file)
@@ -46,11 +46,13 @@ import jp.nyatla.nyartoolkit.core.transmat.optimize.*;
  */\r
 public class NyARRotTransOptimize_X2 implements INyARRotTransOptimize\r
 {\r
-       private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 1;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+       private NyARSinTable _sin_table_ref;    \r
+       private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
        private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0\r
        private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
-       public NyARRotTransOptimize_X2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+       public NyARRotTransOptimize_X2(NyARPerspectiveProjectionMatrix i_projection_mat_ref,NyARSinTable _sin_table_ref)\r
        {\r
+               this._sin_table_ref=_sin_table_ref;\r
                this._projection_mat_ref=i_projection_mat_ref;\r
                return;\r
        }\r
@@ -59,6 +61,7 @@ public class NyARRotTransOptimize_X2 implements INyARRotTransOptimize
        {\r
                final NyARDoublePoint2d[] fit_vertex=i_calculator.getFitSquare();\r
                final NyARDoublePoint3d[] offset_square=i_calculator.getOffsetVertex().vertex;\r
+\r
                \r
                double err = -1;\r
                /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/\r
@@ -185,17 +188,17 @@ public class NyARRotTransOptimize_X2 implements INyARRotTransOptimize
                                a_factor[j] = w;\r
                                w = b2 + w2;\r
                                b_factor[j] = w;\r
-                               sinb[j] = Math.sin(w);\r
-                               cosb[j] = Math.cos(w);\r
+                               sinb[j] = this._sin_table_ref.sin(w);\r
+                               cosb[j] = this._sin_table_ref.cos(w);\r
                                w = c2 + w2;\r
                                c_factor[j] = w;\r
-                               sinc[j] = Math.sin(w);\r
-                               cosc[j] = Math.cos(w);\r
+                               sinc[j] = this._sin_table_ref.sin(w);\r
+                               cosc[j] = this._sin_table_ref.cos(w);\r
                        }\r
                        //\r
                        for (t1 = 0; t1 < 3; t1++) {\r
-                               SA = Math.sin(a_factor[t1]);\r
-                               CA = Math.cos(a_factor[t1]);\r
+                               SA = this._sin_table_ref.sin(a_factor[t1]);\r
+                               CA = this._sin_table_ref.cos(a_factor[t1]);\r
                                // Optimize\r
                                CACA = CA * CA;\r
                                SASA = SA * SA;\r
@@ -287,7 +290,5 @@ public class NyARRotTransOptimize_X2 implements INyARRotTransOptimize
                io_rot.setAngle(ma, mb, mc);\r
                /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
                return minerr / 4;\r
-       }       \r
-       \r
-       \r
+       }\r
 }\r
diff --git a/src/jp/nyatla/nyartoolkit/nymodel/x2/NyARSinTable.java b/src/jp/nyatla/nyartoolkit/nymodel/x2/NyARSinTable.java
new file mode 100644 (file)
index 0000000..284430e
--- /dev/null
@@ -0,0 +1,89 @@
+package jp.nyatla.nyartoolkit.nymodel.x2;\r
+/**\r
+ * 単純Sinテーブル\r
+ *\r
+ */\r
+public class NyARSinTable\r
+{\r
+       private double[] _table = null;\r
+       private int _resolution;\r
+\r
+       private void initTable(int i_resolution)\r
+       {\r
+               //解像度は4の倍数で無いとダメ\r
+               assert(i_resolution%4==0);\r
+               if (this._table == null) {\r
+                       this._table = new double[i_resolution];\r
+                       int d4 = i_resolution / 4;\r
+                       // テーブル初期化(0-2PIを0-1024に作成)\r
+                       for (int i = 1; i < i_resolution; i++) {\r
+                               this._table[i] = (Math.sin(2 * Math.PI * (double) i / (double) i_resolution));\r
+                       }\r
+                       this._table[0] = 0;\r
+                       this._table[d4 - 1] = 1;\r
+                       this._table[d4 * 2 - 1] = 0;\r
+                       this._table[d4 * 3 - 1] = -1;\r
+               }\r
+               return;\r
+       }\r
+\r
+       public NyARSinTable(int i_resolution)\r
+       {\r
+               initTable(i_resolution);\r
+               this._resolution=i_resolution;\r
+               return;\r
+       }\r
+\r
+       public double sin(double i_rad)\r
+       {\r
+               final int resolution=this._resolution;\r
+               // 0~2PIを0~1024に変換\r
+               int rad_index = (int) (i_rad * resolution / (2 * Math.PI));\r
+               rad_index = rad_index % resolution;\r
+               if (rad_index < 0) {\r
+                       rad_index += resolution;\r
+               }\r
+               // ここで0-1024にいる\r
+               return this._table[rad_index];\r
+       }\r
+\r
+       public double cos(double i_rad)\r
+       {\r
+               final int resolution=this._resolution;\r
+               // 0~Math.PI/2を 0~256の値空間に変換\r
+               int rad_index = (int) (i_rad * resolution / (2 * Math.PI));\r
+               // 90度ずらす\r
+               rad_index = (rad_index + resolution / 4) % resolution;\r
+               // 負の領域に居たら、+1024しておく\r
+               if (rad_index < 0) {\r
+                       rad_index += resolution;\r
+               }\r
+               // ここで0-1024にいる\r
+               return this._table[rad_index];\r
+       }\r
+       /**\r
+        * ラジアン角度をテーブルの角度インデックス番号に変換する。\r
+        * 角度インデックスは、0<=n<_resolutionの範囲の整数\r
+        * @param i_rad\r
+        * @return\r
+        */\r
+       public int rad2tableIndex(double i_rad)\r
+       {\r
+               final int resolution=this._resolution;\r
+               int rad_index = (int) (i_rad * resolution / (2 * Math.PI));\r
+               rad_index = rad_index % resolution;\r
+               if (rad_index < 0) {\r
+                       rad_index += resolution;\r
+               }\r
+               return rad_index;\r
+       }\r
+       public double sinByIdx(int i_rad_idx)\r
+       {\r
+               return 0;\r
+       }\r
+       public double cosByIdx(int i_rad_idx)\r
+       {\r
+               return 0;               \r
+       }\r
+       \r
+}\r
index 0e72334..b3a0e24 100644 (file)
@@ -86,7 +86,7 @@ public class NyARSingleDetectMarker_X2
        {\r
                final NyARIntSize scr_size=i_param.getScreenSize();             \r
                // 解析オブジェクトを作る\r
-               this._square_detect = new NyARSquareDetector_X2(i_param.getDistortionFactor(),scr_size);\r
+               this._square_detect = new NyARQrCodeDetector(i_param.getDistortionFactor(),scr_size);\r
                this._transmat = new NyARTransMat_X2(i_param);\r
                // 比較コードを保存\r
                this._code = i_code;\r
@@ -99,8 +99,8 @@ public class NyARSingleDetectMarker_X2
                this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
        }\r
 \r
-       NyARBinRaster _bin_raster;\r
-       NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);\r
+       private NyARBinRaster _bin_raster;\r
+       private NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);\r
 \r
        /**\r
         * i_imageにマーカー検出処理を実行し、結果を記録します。\r
index 5f14528..8cada57 100644 (file)
@@ -33,8 +33,8 @@ package jp.nyatla.nyartoolkit.nymodel.x2;
 \r
 import jp.nyatla.nyartoolkit.NyARException;\r
 import jp.nyatla.nyartoolkit.core.param.*;\r
-import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
 import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.fitveccalc.NyARFitVecCalculator;\r
 \r
 \r
 /**\r
@@ -44,11 +44,15 @@ import jp.nyatla.nyartoolkit.core.transmat.*;
  */\r
 public class NyARTransMat_X2 extends NyARTransMat\r
 {\r
+       private NyARSinTable _sin_table=new NyARSinTable(1024);\r
        public NyARTransMat_X2(NyARParam i_param) throws NyARException\r
        {\r
-               super(\r
-                       i_param,\r
-                       new NyARRotMatrix(i_param.getPerspectiveProjectionMatrix()),\r
-                       new NyARRotTransOptimize_X2(i_param.getPerspectiveProjectionMatrix()));\r
+               super();\r
+               final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();\r
+               final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
+               this._calculator=new NyARFitVecCalculator(pmat,dist);\r
+               this._rotmatrix = new NyARRotMatrix_X2(pmat,this._sin_table);\r
+               this._mat_optimize=new NyARRotTransOptimize_X2(pmat,this._sin_table);\r
+               return;\r
        }\r
 }\r
index 18d57d6..6306ae0 100644 (file)
@@ -42,7 +42,7 @@ import jp.nyatla.nyartoolkit.core.types.*;
 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
 import jp.nyatla.nyartoolkit.core.raster.*;\r
 import jp.nyatla.nyartoolkit.core.types.stack.*;\r
-\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
 \r
 /**\r
  * bitmapとして利用可能なラベリングイメージです。\r
@@ -63,9 +63,8 @@ public class LabelingBufferdImage extends BufferedImage
 \r
        public final static int COLOR_8_MONO = 5;// 16階調モノクロモード\r
 \r
-       private int[] _rgb_table;\r
+       private int[] _rgb_table_125;\r
 \r
-       private int _number_of_color;\r
 \r
        /**\r
         * i_width x i_heightの大きさのイメージを作成します。\r
@@ -73,23 +72,19 @@ public class LabelingBufferdImage extends BufferedImage
         * @param i_width\r
         * @param i_height\r
         */\r
-       public LabelingBufferdImage(int i_width, int i_height, int i_color_mode)\r
+       public LabelingBufferdImage(int i_width, int i_height)\r
        {\r
                super(i_width, i_height, ColorSpace.TYPE_RGB);\r
                // RGBテーブルを作成\r
-               switch (i_color_mode) {\r
-               case COLOR_125_COLOR:\r
-                       this._rgb_table = new int[125];\r
-                       this._number_of_color = 125;\r
-                       for (int i = 0; i < 5; i++) {\r
-                               for (int i2 = 0; i2 < 5; i2++) {\r
-                                       for (int i3 = 0; i3 < 5; i3++) {\r
-                                               this._rgb_table[((i * 5) + i2) * 5 + i3] = ((((i * 63) << 8) | (i2 * 63)) << 8) | (i3 * 63);\r
-                                       }\r
+               this._rgb_table_125 = new int[125];\r
+               for (int i = 0; i < 5; i++) {\r
+                       for (int i2 = 0; i2 < 5; i2++) {\r
+                               for (int i3 = 0; i3 < 5; i3++) {\r
+                                       this._rgb_table_125[((i * 5) + i2) * 5 + i3] = ((((i * 63) << 8) | (i2 * 63)) << 8) | (i3 * 63);\r
                                }\r
                        }\r
-                       break;\r
-               case COLOR_256_MONO:\r
+               }\r
+/*             case COLOR_256_MONO:\r
                        this._rgb_table = new int[256];\r
                        this._number_of_color = 256;\r
                        for (int i = 0; i < 256; i++) {\r
@@ -120,7 +115,7 @@ public class LabelingBufferdImage extends BufferedImage
                                this._rgb_table[i] = (m << 16) | (m << 8) | m;\r
                        }\r
                        break;\r
-               }\r
+               }*/\r
        }\r
 \r
 \r
@@ -142,12 +137,16 @@ public class LabelingBufferdImage extends BufferedImage
                limg = (int[][]) i_raster.getBufferReader().getBuffer();\r
                for (int i = 0; i < h; i++) {\r
                        for (int i2 = 0; i2 < w; i2++) {\r
-                               this.setRGB(i2, i, this._rgb_table[limg[i][i2] % this._number_of_color]);\r
+                               this.setRGB(i2, i,limg[i][i2]);\r
                        }\r
                }\r
                return;\r
        }\r
-\r
+       /**\r
+        * バイナリラスタ\r
+        * @param i_raster\r
+        * @throws NyARException\r
+        */\r
        public void drawImage(NyARBinRaster i_raster) throws NyARException\r
        {\r
                assert (i_raster.getBufferReader().getBufferType() == INyARBufferReader.BUFFERFORMAT_INT2D_BIN_8);\r
@@ -170,6 +169,55 @@ public class LabelingBufferdImage extends BufferedImage
                }\r
                return;\r
        }\r
+               \r
+       /**\r
+        * ラベリングイメージを書く\r
+        * @param i_raster\r
+        * @throws NyARException\r
+        */\r
+       public void drawLabel(NyARLabelingImage i_image) throws NyARException\r
+       {\r
+               int w = this.getWidth();\r
+               int h = this.getHeight();\r
+               // サイズをチェック\r
+               NyARIntSize size = i_image.getSize();\r
+               if (size.h > h || size.w > w) {\r
+                       throw new NyARException();\r
+               }\r
+               int[] index_array=i_image.getIndexArray();\r
+\r
+               int[][] limg;\r
+               // イメージの描画\r
+               limg = (int[][]) i_image.getBufferReader().getBuffer();\r
+               for (int i = 0; i < h; i++) {\r
+                       for (int i2 = 0; i2 < w; i2++) {\r
+                               int t=limg[i][i2]-1;\r
+                               if(t<0){\r
+                                       t=0;\r
+                               }else{\r
+                                       t=index_array[t];\r
+                               }\r
+                               this.setRGB(i2, i,_rgb_table_125[t% _rgb_table_125.length]);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * \r
+        * @param i_stack\r
+        */\r
+\r
+       public void overlayData(NyARLabelingLabel i_label)\r
+       {\r
+               Graphics g = this.getGraphics();\r
+               g.setColor(Color.red);\r
+               g.drawRect(i_label.clip_l,i_label.clip_t,i_label.clip_r-i_label.clip_l,i_label.clip_b-i_label.clip_t);\r
+               return;\r
+       }       \r
+       /**\r
+        * \r
+        * @param i_stack\r
+        */\r
 \r
        public void overlayData(NyARIntPointStack i_stack)\r
        {\r
diff --git a/test/jp/nyatla/nyartoolkit/dev/CopyOfLabelingCamera.java b/test/jp/nyatla/nyartoolkit/dev/CopyOfLabelingCamera.java
new file mode 100644 (file)
index 0000000..dadbfff
--- /dev/null
@@ -0,0 +1,920 @@
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ * 
+ */
+package jp.nyatla.nyartoolkit.dev;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.nymodel.x2.NyARLabeling_ARToolKit_X2;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.nymodel.x2.NyARTransMat_X2;
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.INyARSquareDetector;
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.pickup.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.NyARRasterFilter_RgbAve;
+import jp.nyatla.utils.NyObjectStack;
+import jp.nyatla.utils.j2se.LabelingBufferdImage;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+
+
+class NyARMkVertexStack extends NyObjectStack
+{
+       public NyARMkVertexStack(int i_length)
+       {
+               super(new NyARIntPoint[i_length][]);
+
+       }
+
+       protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)
+       {
+               for (int i = i_start; i < i_end; i++) {
+                       i_buffer[i] = NyARIntPoint.createArray(4);
+               }
+       }
+}
+/**
+ * QRコードのシンボルを結びつける偉いクラス
+ *
+ */
+class NyQrCodeSymbolBinder
+{
+       LabelingBufferdImage bimg;
+       
+       NyARIntPoint[][] _sqare;
+       /**
+        * 最小の三角形を構成する頂点セットを得る
+        * @param i_s0
+        * @param i_s1
+        * @param i_s2
+        * @param o_vertex
+        */
+       public static void getMinimumTriangleVertex(NyARIntPoint[][] i_sqare,int[] o_vertex_id)
+       {
+               //辺の長さが最小になる頂点の組合せを探す
+               int d;
+               int x,y;
+               int dmax=0x7fffffff;
+               for(int i=0;i<4;i++)
+               {
+                       for(int i2=0;i2<4;i2++)
+                       {
+                               for(int i3=0;i3<4;i3++){
+                                       x=i_sqare[0][i].x-i_sqare[2][i3].x;
+                                       y=i_sqare[0][i].y-i_sqare[2][i3].y;
+                                       d=x*x+y*y;
+                                       x=i_sqare[1][i2].x-i_sqare[2][i3].x;
+                                       y=i_sqare[1][i2].y-i_sqare[2][i3].y;
+                                       d+=x*x+y*y;
+                                       x=i_sqare[1][i2].x-i_sqare[0][i].x;
+                                       y=i_sqare[1][i2].y-i_sqare[0][i].y;
+                                       d+=x*x+y*y;
+                                       if(d<dmax){
+                                               dmax=d;
+                                               o_vertex_id[0]=i;                                       
+                                               o_vertex_id[1]=i2;
+                                               o_vertex_id[2]=i3;
+                                       }
+                               }
+                       }
+               }
+               return;
+       }
+       /**
+        * 2矩形の頂点距離が最低の組合せを探す
+        * @param i_sqare
+        * @param o_vertex_id
+        */
+       public static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
+       {
+               //辺の長さが最小になる頂点の組合せを探す
+               int d;
+               int x,y;
+               int dmax=0x7fffffff;
+               for(int i=0;i<4;i++)
+               {
+                       for(int i2=0;i2<4;i2++)
+                       {
+                               x=i_sqare1[i2].x-i_sqare0[i].x;
+                               y=i_sqare1[i2].y-i_sqare0[i].y;
+                               d=x*x+y*y;
+                               if(d<dmax){
+                                       dmax=d;
+                                       o_vertex_id[0]=i;                                       
+                                       o_vertex_id[1]=i2;
+                               }
+                       }
+               }
+               return;
+       }       
+       
+       /**
+        * キーシンボルのインデックスを得る
+        * @param i_sqare
+        * @param i_vertex_id
+        * 最小三角形の頂点IDセット
+        * @return
+        */
+       public static int getKeySymble(NyARIntPoint[][] i_sqare,int[] i_vertex_id)
+       {
+               //シンボルグループの重心を計算
+               int cx,cy;
+               cx=cy=0;
+               for(int i=0;i<3;i++)
+               {
+                       final NyARIntPoint[] sq_ptr=i_sqare[i];
+                       cx+=sq_ptr[0].x;                        
+                       cx+=sq_ptr[1].x;                        
+                       cx+=sq_ptr[2].x;                        
+                       cx+=sq_ptr[3].x;                        
+                       cy+=sq_ptr[0].y;                        
+                       cy+=sq_ptr[1].y;                        
+                       cy+=sq_ptr[2].y;                        
+                       cy+=sq_ptr[3].y;                        
+               }
+               cx/=12;
+               cy/=12; 
+               //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
+               int key_symble_idx=0;
+               int x=i_sqare[0][i_vertex_id[0]].x-cx;
+               int y=i_sqare[0][i_vertex_id[0]].y-cy;
+               int dmax=x*x+y*y;
+               for(int i=1;i<3;i++){
+                       x=i_sqare[i][i_vertex_id[i]].x-cx;
+                       y=i_sqare[i][i_vertex_id[i]].y-cy;
+                       final int d=x*x+y*y;
+                       if(d<dmax){
+                               dmax=d;
+                               key_symble_idx=i;
+                       }
+               }
+               return key_symble_idx;
+       }
+       public void getLineFromVertex(NyARIntPoint i_v1,NyARIntPoint i_v2)
+       {
+               double sx=i_v1.x-i_v2.x;
+               double sy=i_v1.y-i_v2.y;
+               double k=sy/sx;
+               double b=i_v2.y-k*i_v2.x;
+               Graphics g=this.bimg.getGraphics();
+               g.setColor(Color.red);
+               g.drawLine(0,(int)b,320,(int)(k*320+b));
+               
+       }
+       /**
+        *
+        * @param i_sq
+        * @param o_sq
+        * @return
+        */
+       public boolean margeEdge(NyARIntPoint[][] i_sq,NyARSquare o_sq)
+       {
+               int[] minimum_triangle_vertex=new int[3];
+               int[] minimum_line_vertex=new int[2];
+
+               //辺の長さが最小になる頂点の組合せを探す
+               getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
+               
+               //キーシンボルのインデクス番号を得る
+               int key_simble_idx=getKeySymble(i_sq,minimum_triangle_vertex);
+               
+               //エッジシンボルのインデックス番号を決める
+               int symbol_e1_idx=(key_simble_idx+1)%3;
+               int symbol_e2_idx=(key_simble_idx+2)%3;
+               
+               //エッジシンボル間で最短距離を取る頂点ペアを取る
+               //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
+               getMinimumLineVertex(i_sq[symbol_e1_idx],i_sq[symbol_e2_idx],minimum_line_vertex);
+               
+               //内対角を外対角に変換
+               int lv1=(minimum_line_vertex[0]+2)%4;
+               int lv2=(minimum_line_vertex[1]+2)%4;
+               int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
+
+               getLineFromVertex(i_sq[symbol_e1_idx][(lv1+1)%4],i_sq[symbol_e1_idx][lv1]);
+               getLineFromVertex(i_sq[symbol_e1_idx][(lv1+3)%4],i_sq[symbol_e1_idx][lv1]);
+               getLineFromVertex(i_sq[symbol_e2_idx][(lv2+1)%4],i_sq[symbol_e2_idx][lv2]);
+               getLineFromVertex(i_sq[symbol_e2_idx][(lv2+3)%4],i_sq[symbol_e2_idx][lv2]);
+               getLineFromVertex(i_sq[key_simble_idx][(kv+2)%4],i_sq[key_simble_idx][kv]);
+                               
+               
+               Graphics g=this.bimg.getGraphics();
+               //内対角に緑の点を打つ
+               g.setColor(Color.green);
+               g.fillRect(i_sq[key_simble_idx][minimum_triangle_vertex[key_simble_idx]].x-2,i_sq[key_simble_idx][minimum_triangle_vertex[key_simble_idx]].y-2,4,4);
+               g.fillRect(i_sq[symbol_e1_idx][minimum_line_vertex[0]].x-2,i_sq[symbol_e1_idx][minimum_line_vertex[0]].y-2,4,4);
+               g.fillRect(i_sq[symbol_e2_idx][minimum_line_vertex[1]].x-2,i_sq[symbol_e2_idx][minimum_line_vertex[1]].y-2,4,4);
+               
+               
+               //中央の中心エッジから最も遠い点が
+               //両端のエッジも探す
+               
+               
+               
+
+//             this.bimg.getGraphics().fillRect(i_sq[edge1_id][vid1_id].x,i_sq[edge1_id][vid1_id].y,5,5);
+               
+               for (int i = 0; i <3; i++) {
+                       int[] xp=new int[4]; 
+                       int[] yp=new int[4]; 
+                       for(int i2=0;i2<4;i2++){
+                               xp[i2]=i_sq[i][i2].x;
+                               yp[i2]=i_sq[i][i2].y;
+                       }
+                       this.bimg.getGraphics().setColor(Color.RED);
+                       this.bimg.getGraphics().drawPolygon(xp, yp,4);
+               }               
+               
+               
+               return false;
+               
+               
+               
+               
+
+               
+       }       
+       
+       
+       
+       
+}
+
+
+/**
+ * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス
+ * 
+ */
+class NyARQRCodeDetector implements INyARSquareDetector
+{
+       LabelingBufferdImage bimg;
+       private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
+
+       private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
+
+       private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
+
+       private final int _width;
+
+       private final int _height;
+
+       private final NyARLabeling_ARToolKit_X2 _labeling;
+
+       private final NyARLabelingImage _limage;
+
+       private final NyARCameraDistortionFactor _dist_factor_ref;
+
+       /**
+        * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+        * 
+        * @param i_param
+        */
+       public NyARQRCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+       {
+               this._width = i_size.w;
+               this._height = i_size.h;
+               this._dist_factor_ref = i_dist_factor_ref;
+               this._labeling = new NyARLabeling_ARToolKit_X2();
+               this._limage = new NyARLabelingImage(this._width, this._height);
+               this._labeling.attachDestination(this._limage);
+
+               // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+               int number_of_coord = (this._width + this._height) * 2;
+
+               // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+               this._max_coord = number_of_coord;
+               this._xcoord = new int[number_of_coord * 2];
+               this._ycoord = new int[number_of_coord * 2];
+       }
+
+       private final int _max_coord;
+
+       private final int[] _xcoord;
+
+       private final int[] _ycoord;
+
+       private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+       {
+               // vertex1を境界にして、後方に配列を連結
+               System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+               System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+       }
+
+       private final int[] __detectMarker_mkvertex = new int[5];
+
+       /**
+        * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+        * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+        * 
+        * @param i_raster
+        * 解析する2値ラスタイメージを指定します。
+        * @param o_square_stack
+        * 抽出した正方形候補を格納するリスト
+        * @throws NyARException
+        */
+       public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+       {
+               final INyARLabeling labeling_proc = this._labeling;
+               final NyARLabelingImage limage = this._limage;
+
+               // 初期化
+
+               // マーカーホルダをリセット
+               o_square_stack.clear();
+
+               // ラベリング
+               labeling_proc.labeling(i_raster);
+
+               // ラベル数が0ならここまで
+               final int label_num = limage.getLabelStack().getLength();
+               if (label_num < 1) {
+                       return;
+               }
+
+               final NyARLabelingLabelStack stack = limage.getLabelStack();
+               final NyARLabelingLabel[] labels = (NyARLabelingLabel[]) stack.getArray();
+
+               // ラベルを大きい順に整列
+               stack.sortByArea();
+
+               // デカいラベルを読み飛ばし
+               int i;
+               for (i = 0; i < label_num; i++) {
+                       // 検査対象内のラベルサイズになるまで無視
+                       if (labels[i].area <= AR_AREA_MAX) {
+                               break;
+                       }
+               }
+               
+               final int xsize = this._width;
+               final int ysize = this._height;
+               final int[] xcoord = this._xcoord;
+               final int[] ycoord = this._ycoord;
+               final int coord_max = this._max_coord;
+               final int[] mkvertex = this.__detectMarker_mkvertex;
+               final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
+               final int[] indextable = limage.getIndexArray();
+               int coord_num;
+               int label_area;
+               NyARLabelingLabel label_pt;
+               NyARMkVertexStack vertex_stack=new NyARMkVertexStack(100);
+
+               for (; i < label_num; i++) {
+                       label_pt = labels[i];
+                       label_area = label_pt.area;
+                       // 検査対象サイズよりも小さくなったら終了
+                       if (label_area < AR_AREA_MIN) {
+                               break;
+                       }
+                       // クリップ領域が画面の枠に接していれば除外
+                       if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+                               continue;
+                       }
+                       if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+                               continue;
+                       }
+                       // 特徴点候補であるかを確認する。
+                       if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
+                               continue;
+                       }
+
+                       // 輪郭を取得
+                       coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+                       if (coord_num == coord_max) {
+                               // 輪郭が大きすぎる。
+                               continue;
+                       }
+                       // 頂点候補のインデクスを取得
+                       final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+                       // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+                       normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+
+                       // 頂点情報を取得
+                       if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+//                             o_square_stack.pop();// 頂点の取得が出来なかったので破棄
+                               continue;
+                       }
+                       // 領域を準備する。
+                       NyARIntPoint[] vertex_ptr = (NyARIntPoint[]) vertex_stack.prePush();
+                       vertex_ptr[0].x=xcoord[mkvertex[0]];
+                       vertex_ptr[0].y=ycoord[mkvertex[0]];
+                       vertex_ptr[1].x=xcoord[mkvertex[1]];
+                       vertex_ptr[1].y=ycoord[mkvertex[1]];
+                       vertex_ptr[2].x=xcoord[mkvertex[2]];
+                       vertex_ptr[2].y=ycoord[mkvertex[2]];
+                       vertex_ptr[3].x=xcoord[mkvertex[3]];
+                       vertex_ptr[3].y=ycoord[mkvertex[3]];
+
+//                     // 頂点情報からライン情報を作っちゃう
+//                     getSquare(mkvertex, xcoord, ycoord, vertex_ptr);
+               }
+               bindQrcodeEdge(vertex_stack);
+               //エッジ同士の相関関係をしらべる。
+
+               return;
+       }
+       /**
+        *
+        * @param i_sq
+        * @param o_sq
+        * @return
+        */
+       public boolean margeEdge(NyARIntPoint[][] i_sq,NyARSquare o_sq)
+       {
+               NyQrCodeSymbolBinder binder=new NyQrCodeSymbolBinder();
+               binder.bimg=this.bimg;
+               binder.margeEdge(i_sq, o_sq);
+
+               return false;
+               
+               
+               
+               
+       }
+       /**
+        * QRコードのエッジペアを作る
+        * @param i_square_stack
+        */
+       public void bindQrcodeEdge(NyARMkVertexStack i_square_stack)
+       {
+               
+               NyARIntPoint[] sq_ptr1,sq_ptr2,sq_ptr3;
+               int number_of_edge=i_square_stack.getLength();
+               if(number_of_edge<3){
+                       return;
+               }
+               NyARIntPoint[][] sa=(NyARIntPoint[][])i_square_stack.getArray();
+               for(int i=0;i<number_of_edge;i++)
+               {       
+                       for(int i2=i+1;i2<number_of_edge;i2++)
+                       {
+                               sq_ptr2=sa[i2];
+                               for(int i3=i2+1;i3<number_of_edge;i3++){
+                                       sq_ptr3=sa[i3];
+                                       //3個のエッジの関連性を確認する。
+                                       margeEdge(sa,null);
+                               }
+                               //
+                       }
+               }
+       }
+       /**
+        * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
+        * 
+        * @param i_v1
+        * @param i_v2
+        * @param o_line
+        */
+       final private void getLine(NyARDoublePoint2d i_v1, NyARDoublePoint2d i_v2, NyARLinear o_line)
+       {
+               final double x = i_v1.x - i_v2.x;
+               final double y = i_v1.y - i_v2.y;
+               final double x2 = x * x;
+               final double y2 = y * y;
+               final double rise_ = Math.sqrt(x2 / (x2 + y2));
+               o_line.rise = rise_;
+               o_line.run = Math.sqrt(y2 / (x2 + y2));
+               if (x < 0) {
+                       if (y < 0) {
+                               o_line.rise = -o_line.rise;
+                       } else {
+                               o_line.rise = -o_line.rise;
+                               o_line.run = -o_line.run;
+                       }
+               } else {
+                       if (y < 0) {
+                               o_line.rise = -o_line.rise;
+                               o_line.run = -o_line.run;
+                       } else {
+                               o_line.rise = -o_line.rise;
+                       }
+               }
+               o_line.intercept = (i_v1.y + (o_line.run / o_line.rise) * (i_v1.x)) * rise_;
+
+       }
+
+       private void getSquare(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square)
+       {
+               final NyARCameraDistortionFactor dist_factor = this._dist_factor_ref;
+               final NyARDoublePoint2d[] vertex = o_square.sqvertex;
+
+               NyARIntPoint[] imvertex_ptr=o_square.imvertex;
+               NyARIntPoint wk_vertex;
+               //頂点座標取得
+               for (int i = 0; i < 4; i++) {
+                       final int idx = i_mkvertex[i];
+                       imvertex_ptr[i].x = i_xcoord[idx];
+                       imvertex_ptr[i].y = i_ycoord[idx];
+               }
+               // 歪み補正
+               for (int i = 0; i < 4; i++) {
+                       dist_factor.observ2Ideal(imvertex_ptr[i].x,imvertex_ptr[i].y, vertex[i]);
+               }
+               // ライン計算
+               getLine(vertex[1], vertex[0], o_square.line[0]);
+               getLine(vertex[2], vertex[1], o_square.line[1]);
+               getLine(vertex[3], vertex[2], o_square.line[2]);
+               getLine(vertex[0], vertex[3], o_square.line[3]);
+               return;
+       }
+
+       /**
+        * 辺からの対角線が最長になる点を対角線候補として返す。
+        * 
+        * @param i_xcoord
+        * @param i_ycoord
+        * @param i_coord_num
+        * @return
+        */
+       private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+       {
+               final int sx = i_xcoord[0];
+               final int sy = i_ycoord[0];
+               int d = 0;
+               int w, x, y;
+               int ret = 0;
+               for (int i = 1; i < i_coord_num; i++) {
+                       x = i_xcoord[i] - sx;
+                       y = i_ycoord[i] - sy;
+                       w = x * x + y * y;
+                       if (w > d) {
+                               d = w;
+                               ret = i;
+                       }
+                       // ここでうまく終了条件入れられないかな。
+               }
+               return ret;
+       }
+
+       private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+       private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+       /**
+        * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+        * 
+        * @param i_x_coord
+        * @param i_y_coord
+        * @param i_vertex1_index
+        * @param i_coord_num
+        * @param i_area
+        * @param o_vertex
+        * 要素数はint[4]である事
+        * @return
+        */
+       private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+       {
+               final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+               final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+               final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+               final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+               final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+               int dmax = 0;
+               int v1 = i_vertex1_index;
+               for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+                       // {
+                       final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+                       if (d > dmax) {
+                               dmax = d;
+                               v1 = i;
+                       }
+               }
+               final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+               o_vertex[0] = i_vertex1_index;
+
+               if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+                       // 0 ) {
+                       return false;
+               }
+               if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+                       // < 0) {
+                       return false;
+               }
+
+               int v2;
+               if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+                       o_vertex[1] = wv1.vertex[0];
+                       o_vertex[2] = v1;
+                       o_vertex[3] = wv2.vertex[0];
+               } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+                       // 頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+                       v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+                       if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+                               return false;
+                       }
+                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+                               return false;
+                       }
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+                               o_vertex[1] = wv1.vertex[0];
+                               o_vertex[2] = wv2.vertex[0];
+                               o_vertex[3] = v1;
+                       } else {
+                               return false;
+                       }
+               } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+                       // v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+                       v2 = (v1 + end_of_coord) / 2;
+
+                       if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+                               return false;
+                       }
+                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+                               return false;
+                       }
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+                               o_vertex[1] = v1;
+                               o_vertex[2] = wv1.vertex[0];
+                               o_vertex[3] = wv2.vertex[0];
+                       } else {
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+               o_vertex[4] = end_of_coord;
+               return true;
+       }
+       /**
+        * QRコードのエッジ特徴を持つラベルであるかを調べる
+        * @param buf
+        * @param index_table
+        * @param i_label
+        * @return
+        */
+       private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)
+       {
+               int tx, bx;
+               int w;
+               int i_label_id = i_label.id;
+               int[] limage_j;
+               final int clip_l = i_label.clip_l;
+               final int clip_b = i_label.clip_b;
+               final int clip_r = i_label.clip_r;
+               final int clip_t = i_label.clip_t;
+
+               tx = bx = 0;
+               // 上接点(→)
+               limage_j = buf[clip_t];
+               for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+                       w = limage_j[i];
+                       if (w > 0 && index_table[w - 1] == i_label_id) {
+                               tx = i;
+                               break;
+                       }
+               }
+               // 下接点(←)
+               limage_j = buf[clip_b];
+               for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+                       w = limage_j[i];
+                       if (w > 0 && index_table[w - 1] == i_label_id) {
+                               bx = i;
+                               break;
+                       }
+               }
+               final int cx = (clip_l + clip_r) / 2;
+               final int cy = (clip_t + clip_b) / 2;
+               // 横断チェック(中心から線を引いて、101になるかしらべる)
+               if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {
+                       return false;
+               }
+               if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * 対角線のパターンを調べる。
+        * 
+        * @param buf
+        * @param i_px1
+        * @param i_py1
+        * @param i_px2
+        * @param i_py2
+        * @return
+        */
+       private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)
+       {
+               int sub_y = i_py2 - i_py1;
+               int sub_x = i_px2 - i_px1;
+               // 黒
+               int i = 0;
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+                               break;
+                       }
+
+               }
+               if (i == sub_y) {
+                       return false;
+               }
+               // 白
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {
+                               break;
+                       }
+
+               }
+               if (i == sub_y) {
+                       return false;
+               }
+               // 黒
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+                               break;
+                       }
+
+               }
+               if (i != sub_y) {
+                       return false;
+               }
+               // 端まで到達したらOK
+               return true;
+       }
+
+}
+
+
+public class CopyOfLabelingCamera extends Frame implements JmfCaptureListener
+{
+       private final String camera_file = "../Data/camera_para.dat";
+
+       private JmfNyARRaster_RGB _raster;
+
+       private JmfCameraCapture capture;
+       private NyARParam ap;
+       public CopyOfLabelingCamera() throws NyARException, NyARException
+       {
+               setBounds(0, 0, 640 + 64, 720 + 64);
+               // キャプチャの準備
+               capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+               capture.setCaptureListener(this);
+
+               // キャプチャイメージ用のラスタを準備
+               this._raster = new JmfNyARRaster_RGB(320, 240);
+               
+               // AR用カメラパラメタファイルをロード
+               ap = new NyARParam();
+               ap.loadARParamFromFile(camera_file);
+               ap.changeScreenSize(320, 240);          
+               
+               
+       }
+
+       // そのラベルが特徴点候補か返す。
+
+       private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+       private NyARGlayscaleRaster _gsraster1 = new NyARGlayscaleRaster(320, 240);
+
+       private NyARLabelingImage _limage = new NyARLabelingImage(320, 240);
+
+       private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+       private NyARRasterFilter_ARToolkitThreshold filter_gs2bin;
+
+       public void onUpdateBuffer(Buffer i_buffer)
+       {
+               NyARRasterFilter_AreaAverage gs2bin=new NyARRasterFilter_AreaAverage();
+
+               try {
+                       // キャプチャしたバッファをラスタにセット
+                       _raster.setBuffer(i_buffer);
+
+                       Graphics g = getGraphics();
+                       // キャプチャ画像
+                       BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+                       Image img = b2i.createImage(i_buffer);
+                       this.getGraphics().drawImage(img, 32, 32, this);
+
+                       // 画像1
+                       INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+                       filter_rgb2gs.doFilter(_raster, _gsraster1);
+                       this._bimg.drawImage(this._gsraster1);
+                       this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+                       
+
+                       // 画像2
+                       gs2bin.doFilter(_gsraster1, _binraster1);
+                       this._bimg.drawImage(_binraster1);
+                       this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+                       // 画像3
+                       NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+                       NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+                       labeling.attachDestination(limage);
+                       labeling.labeling(_binraster1);
+                       this._bimg.drawImage(this._gsraster1);
+                       NyARLabelingLabel[] labels = (NyARLabelingLabel[]) limage.getLabelStack().getArray();
+
+                       NyARSquareStack stack = new NyARSquareStack(100);
+                       NyARQRCodeDetector detect = new NyARQRCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+                       detect.bimg=this._bimg;
+
+                       detect.detectMarker(_binraster1, stack);
+                       for (int i = 0; i < stack.getLength(); i++) {
+                               NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray();
+                               int[] xp=new int[4]; 
+                               int[] yp=new int[4]; 
+                               for(int i2=0;i2<4;i2++){
+                                       xp[i2]=square_ptr[i].imvertex[i2].x;
+                                       yp[i2]=square_ptr[i].imvertex[i2].y;
+                               }
+                               this._bimg.getGraphics().setColor(Color.RED);
+                               this._bimg.getGraphics().drawPolygon(xp, yp,2);
+                       }
+                       this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+                       // 画像3
+                       // threshold.debugDrawHistgramMap(_workraster, _workraster2);
+                       // this._bimg2.setImage(this._workraster2);
+                       // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+                       // 画像4
+                       // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+                       // threshold.analyzeRaster(_gsraster1);
+                       // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+                       // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+                       // this._bimg.drawImage(_binraster1);
+
+                       // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+                       // detector.analyzeRaster(_binraster1);
+
+                       // this._bimg.overlayData(detector.geResult());
+
+                       // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+                       // 画像5
+
+                       /*
+                        * threshold2.debugDrawHistgramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+                        * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+                        */
+
+                       // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+       private INyARLabeling labelingFactory(int i_idx)
+       {
+               // switch(i_idx){
+               // case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
+               // case 1:{return new NyLineLabeling();}
+               // }
+               return null;
+
+       }
+
+       private void startCapture()
+       {
+               try {
+                       capture.start();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public static void main(String[] args)
+       {
+               try {
+                       CopyOfLabelingCamera mainwin = new CopyOfLabelingCamera();
+                       mainwin.setVisible(true);
+                       mainwin.startCapture();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+}
index d22fdbf..1946a5d 100644 (file)
@@ -11,129 +11,958 @@ import javax.media.format.*;
 
 import jp.nyatla.nyartoolkit.NyARException;
 import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.nymodel.x2.NyARLabeling_ARToolKit_X2;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.nymodel.x2.NyARTransMat_X2;
 
 import java.awt.*;
 
-
+import jp.nyatla.nyartoolkit.core.INyARSquareDetector;
 import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;
+import jp.nyatla.nyartoolkit.core.pickup.*;
 import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
 import jp.nyatla.nyartoolkit.core.rasterfilter.*;
 import jp.nyatla.nyartoolkit.core2.rasteranalyzer.*;
 import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
 import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
 import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.NyARRasterFilter_RgbAve;
+import jp.nyatla.utils.NyObjectStack;
 import jp.nyatla.utils.j2se.LabelingBufferdImage;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
+
+
+class NyARMkVertexStack extends NyObjectStack
+{
+       public NyARMkVertexStack(int i_length)
+       {
+               super(new NyARIntPoint[i_length][]);
+
+       }
 
-public class LabelingCamera extends Frame implements JmfCaptureListener {
-    private JmfNyARRaster_RGB _raster;
-    private JmfCameraCapture capture;
-
-
-    public LabelingCamera() throws NyARException, NyARException
-    {
-       setBounds(0, 0, 640 + 64, 720 + 64);
-       // キャプチャの準備
-       capture = new JmfCameraCapture(320, 240, 30f,
-               JmfCameraCapture.PIXEL_FORMAT_RGB);
-       capture.setCaptureListener(this);
-
-       // キャプチャイメージ用のラスタを準備
-       this._raster = new JmfNyARRaster_RGB(320, 240);
-    }
-    
-    private NyARBinRaster _binraster1=new NyARBinRaster(320,240);
-    private NyARGlayscaleRaster _gsraster1=new NyARGlayscaleRaster(320,240);
-    private NyARLabelingImage _limage=new NyARLabelingImage(320, 240);
-    private LabelingBufferdImage _bimg=new LabelingBufferdImage(320, 240,LabelingBufferdImage.COLOR_256_MONO);
-    private LabelingBufferdImage _bimg2=new LabelingBufferdImage(320, 240,LabelingBufferdImage.COLOR_256_MONO);
-
-    public void onUpdateBuffer(Buffer i_buffer)
-    {
-       try {
-           // キャプチャしたバッファをラスタにセット
-           _raster.setBuffer(i_buffer);
-           
-           Graphics g = getGraphics();
-           //キャプチャ画像
-           BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
-           Image img = b2i.createImage(i_buffer);
-           this.getGraphics().drawImage(img, 32, 32, this);
-           
-           INyARRasterFilter_GsToBin filter_gs2bin;
-           //画像1
-           INyARRasterFilter_RgbToGs filter_rgb2gs=new NyARRasterFilter_RgbAve();
-           filter_rgb2gs.doFilter(_raster, _gsraster1);
-           this._bimg2.drawImage(this._gsraster1);
-           this.getGraphics().drawImage(this._bimg2, 32+320, 32,320+320+32,240+32,0,240,320,0, this);
-
-           //画像2
-           filter_gs2bin=new NyARRasterFilter_ARToolKitThreshold(128);
-           filter_gs2bin.doFilter(_gsraster1, _binraster1);
-           this._bimg.drawImage(_binraster1);
-           this.getGraphics().drawImage(this._bimg, 32, 32+240,320+32,240+32+240,0,240,320,0, this);
-           //画像3
-           //threshold.debugDrawHistgramMap(_workraster, _workraster2);
-           //this._bimg2.setImage(this._workraster2);
-           //this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
-
-           //画像4
-           NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
-           threshold.analyzeRaster(_gsraster1);
-           filter_gs2bin=new NyARRasterFilter_AreaAverage();
-           filter_gs2bin.doFilter(_gsraster1, _binraster1);
-           this._bimg.drawImage(_binraster1);
-           
-           NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
-           detector.analyzeRaster(_binraster1);
-           
-           this._bimg.overlayData(detector.geResult());
-           
-           this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
-           //画像5
-           
-           
-/*         threshold2.debugDrawHistgramMap(_workraster, _workraster2);
-           this._bimg2.drawImage(this._workraster2);
-           this.getGraphics().drawImage(this._bimg2, 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
-*/         
-           
-           //      this.getGraphics().drawImage(this._bimg, 32, 32, this);
-
-
-       } catch (Exception e) {
-           e.printStackTrace();
-       }
-
-    }
-    private INyARLabeling labelingFactory(int i_idx)
-    {
-       switch(i_idx){
-       case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
-       case 1:{return new NyLineLabeling();}
-       }
-       return null;
+       protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)
+       {
+               for (int i = i_start; i < i_end; i++) {
+                       i_buffer[i] = NyARIntPoint.createArray(4);
+               }
+       }
+}
+/**
+ * QRコードのシンボルを結びつける偉いクラス
+ *
+ */
+class NyQrCodeSymbolBinder
+{
+       LabelingBufferdImage bimg;
        
+       NyARIntPoint[][] _sqare;
+       /**
+        * 最小の三角形を構成する頂点セットを得る
+        * @param i_s0
+        * @param i_s1
+        * @param i_s2
+        * @param o_vertex
+        */
+       public static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id)
+       {
+               //辺の長さが最小になる頂点の組合せを探す
+               int d;
+               int x,y;
+               int dmax=0x7fffffff;
+               final NyARIntPoint[] vertex0=i_sqare[0].imvertex;
+               final NyARIntPoint[] vertex1=i_sqare[1].imvertex;
+               final NyARIntPoint[] vertex2=i_sqare[2].imvertex;
+               for(int i=0;i<4;i++)
+               {
+                       for(int i2=0;i2<4;i2++)
+                       {
+                               for(int i3=0;i3<4;i3++){
+                                       x=vertex0[i].x-vertex2[i3].x;
+                                       y=vertex0[i].y-vertex2[i3].y;
+                                       d=x*x+y*y;
+                                       x=vertex1[i2].x-vertex2[i3].x;
+                                       y=vertex1[i2].y-vertex2[i3].y;
+                                       d+=x*x+y*y;
+                                       x=vertex1[i2].x-vertex0[i].x;
+                                       y=vertex1[i2].y-vertex0[i].y;
+                                       d+=x*x+y*y;
+                                       if(d<dmax){
+                                               dmax=d;
+                                               o_vertex_id[0]=i;                                       
+                                               o_vertex_id[1]=i2;
+                                               o_vertex_id[2]=i3;
+                                       }
+                               }
+                       }
+               }
+               return;
+       }
+       /**
+        * 2矩形の頂点距離が最低の組合せを探す
+        * @param i_sqare
+        * @param o_vertex_id
+        */
+       public static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
+       {
+               //辺の長さが最小になる頂点の組合せを探す
+               int d;
+               int x,y;
+               int dmax=0x7fffffff;
+               for(int i=0;i<4;i++)
+               {
+                       for(int i2=0;i2<4;i2++)
+                       {
+                               x=i_sqare1[i2].x-i_sqare0[i].x;
+                               y=i_sqare1[i2].y-i_sqare0[i].y;
+                               d=x*x+y*y;
+                               if(d<dmax){
+                                       dmax=d;
+                                       o_vertex_id[0]=i;                                       
+                                       o_vertex_id[1]=i2;
+                               }
+                       }
+               }
+               return;
+       }       
+       
+       /**
+        * キーシンボルのインデックスを得る
+        * @param i_sqare
+        * @param i_vertex_id
+        * 最小三角形の頂点IDセット
+        * @return
+        */
+       public static int getKeySymble(NyARSquare[] i_sqare,int[] i_vertex_id)
+       {
+               //シンボルグループの重心を計算
+               int cx,cy;
+               cx=cy=0;
+               for(int i=0;i<3;i++)
+               {
+                       final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;
+                       cx+=sq_ptr[0].x;                        
+                       cx+=sq_ptr[1].x;                        
+                       cx+=sq_ptr[2].x;                        
+                       cx+=sq_ptr[3].x;                        
+                       cy+=sq_ptr[0].y;                        
+                       cy+=sq_ptr[1].y;                        
+                       cy+=sq_ptr[2].y;                        
+                       cy+=sq_ptr[3].y;                        
+               }
+               cx/=12;
+               cy/=12; 
+               //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
+               int key_symble_idx=0;
+               int x=i_sqare[0].imvertex[i_vertex_id[0]].x-cx;
+               int y=i_sqare[0].imvertex[i_vertex_id[0]].y-cy;
+               int dmax=x*x+y*y;
+               for(int i=1;i<3;i++){
+                       x=i_sqare[i].imvertex[i_vertex_id[i]].x-cx;
+                       y=i_sqare[i].imvertex[i_vertex_id[i]].y-cy;
+                       final int d=x*x+y*y;
+                       if(d<dmax){
+                               dmax=d;
+                               key_symble_idx=i;
+                       }
+               }
+               return key_symble_idx;
+       }
+       public void bindSquare(NyARSquare i_sq1,int i_lv1,NyARSquare i_sq2,int i_lv2)
+       {
+               NyARSquare new_square=new NyARSquare();
+               //4辺の式を計算
+               new_square.line[0].copyFrom(i_sq1.line[(i_lv1)%4]);
+               new_square.line[1].copyFrom(i_sq1.line[(i_lv1+3)%4]);
+               new_square.line[2].copyFrom(i_sq2.line[(i_lv2)%4]);
+               new_square.line[3].copyFrom(i_sq2.line[(i_lv2+3)%4]);
+               //歪み無しの座標系を計算
+               final NyARDoublePoint2d[] l_sqvertex = new_square.sqvertex;
+               final NyARLinear[] l_line = new_square.line;            
+               for (int i = 0; i < 4; i++) {
+                       final NyARLinear l_line_i = l_line[i];
+                       final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+                       final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+                       if (w1 == 0.0) {
+                               return;
+                       }
+                       l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+                       l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+//                     // 頂点インデクスから頂点座標を得て保存
+//                     l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+//                     l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+               }
+               Graphics g=this.bimg.getGraphics();
+               g.setColor(Color.red);
+               int[] x=new int[4];
+               int[] y=new int[4];
+               for(int i=0;i<4;i++){
+                       x[i]=(int)l_sqvertex[i].x;
+                       y[i]=(int)l_sqvertex[i].y;
+               }
+               g.drawPolygon(x,y,4);
+               //基準点はVertexをそのまま採用
+               //2個の想定点は座標を逆変換して設定
+       }
+       /**
+        *
+        * @param i_sq
+        * @param o_sq
+        * @return
+        */
+       public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+       {
+               int[] minimum_triangle_vertex=new int[3];
+               int[] minimum_line_vertex=new int[2];
+
+               //辺の長さが最小になる頂点の組合せを探す
+               getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
+               
+               //キーシンボルのインデクス番号を得る
+               int key_simble_idx=getKeySymble(i_sq,minimum_triangle_vertex);
+               
+               //エッジシンボルのインデックス番号を決める
+               int symbol_e1_idx=(key_simble_idx+1)%3;
+               int symbol_e2_idx=(key_simble_idx+2)%3;
+               
+               //エッジシンボル間で最短距離を取る頂点ペアを取る
+               //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
+               getMinimumLineVertex(i_sq[symbol_e1_idx].imvertex,i_sq[symbol_e2_idx].imvertex,minimum_line_vertex);
+               
+               //内対角を外対角に変換
+               int lv1=(minimum_line_vertex[0]+2)%4;
+               int lv2=(minimum_line_vertex[1]+2)%4;
+               int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
+               //矩形のバインド
+               bindSquare(i_sq[symbol_e1_idx],lv1,i_sq[symbol_e2_idx],lv2);
+                               
+               
+               Graphics g=this.bimg.getGraphics();
+               //内対角に緑の点を打つ
+               g.setColor(Color.green);
+               g.fillRect(i_sq[symbol_e1_idx].imvertex[lv1].x-2,i_sq[symbol_e1_idx].imvertex[lv1].y-2,4,4);
+               g.fillRect(i_sq[symbol_e2_idx].imvertex[lv2].x-2,i_sq[symbol_e2_idx].imvertex[lv2].y-2,4,4);
+//             g.fillRect(i_sq[symbol_e2_idx][minimum_line_vertex[1]].x-2,i_sq[symbol_e2_idx][minimum_line_vertex[1]].y-2,4,4);
+               
+               
+               //中央の中心エッジから最も遠い点が
+               //両端のエッジも探す
+               
+               
+               
+
+//             this.bimg.getGraphics().fillRect(i_sq[edge1_id][vid1_id].x,i_sq[edge1_id][vid1_id].y,5,5);
+               
+               for (int i = 0; i <3; i++) {
+                       int[] xp=new int[4]; 
+                       int[] yp=new int[4]; 
+                       for(int i2=0;i2<4;i2++){
+                               xp[i2]=i_sq[i].imvertex[i2].x;
+                               yp[i2]=i_sq[i].imvertex[i2].y;
+                       }
+                       this.bimg.getGraphics().setColor(Color.RED);
+                       this.bimg.getGraphics().drawPolygon(xp, yp,4);
+               }               
+               
+               
+               return false;
+               
+               
+               
+               
+
+               
+       }       
        
-    }
+       
+       
+       
+}
+
+
+/**
+ * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス
+ * 
+ */
+class NyARQRCodeDetector implements INyARSquareDetector
+{
+       LabelingBufferdImage bimg;
+       private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
+
+       private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
+
+       private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
+
+       private final int _width;
+
+       private final int _height;
+
+       private final NyARLabeling_ARToolKit_X2 _labeling;
+
+       private final NyARLabelingImage _limage;
 
-    private void startCapture()
-    {
-       try {
-           capture.start();
-       } catch (Exception e) {
-           e.printStackTrace();
+       private final NyARCameraDistortionFactor _dist_factor_ref;
+
+       /**
+        * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+        * 
+        * @param i_param
+        */
+       public NyARQRCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+       {
+               this._width = i_size.w;
+               this._height = i_size.h;
+               this._dist_factor_ref = i_dist_factor_ref;
+               this._labeling = new NyARLabeling_ARToolKit_X2();
+               this._limage = new NyARLabelingImage(this._width, this._height);
+               this._labeling.attachDestination(this._limage);
+
+               // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+               int number_of_coord = (this._width + this._height) * 2;
+
+               // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+               this._max_coord = number_of_coord;
+               this._xcoord = new int[number_of_coord * 2];
+               this._ycoord = new int[number_of_coord * 2];
+       }
+
+       private final int _max_coord;
+
+       private final int[] _xcoord;
+
+       private final int[] _ycoord;
+
+       private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+       {
+               // vertex1を境界にして、後方に配列を連結
+               System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+               System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+       }
+
+       private final int[] __detectMarker_mkvertex = new int[5];
+
+       /**
+        * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+        * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+        * 
+        * @param i_raster
+        * 解析する2値ラスタイメージを指定します。
+        * @param o_square_stack
+        * 抽出した正方形候補を格納するリスト
+        * @throws NyARException
+        */
+       public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+       {
+               final INyARLabeling labeling_proc = this._labeling;
+               final NyARLabelingImage limage = this._limage;
+
+               // 初期化
+
+               // マーカーホルダをリセット
+               o_square_stack.clear();
+
+               // ラベリング
+               labeling_proc.labeling(i_raster);
+
+               // ラベル数が0ならここまで
+               final int label_num = limage.getLabelStack().getLength();
+               if (label_num < 1) {
+                       return;
+               }
+
+               final NyARLabelingLabelStack stack = limage.getLabelStack();
+               final NyARLabelingLabel[] labels = (NyARLabelingLabel[]) stack.getArray();
+
+               // ラベルを大きい順に整列
+               stack.sortByArea();
+
+               // デカいラベルを読み飛ばし
+               int i;
+               for (i = 0; i < label_num; i++) {
+                       // 検査対象内のラベルサイズになるまで無視
+                       if (labels[i].area <= AR_AREA_MAX) {
+                               break;
+                       }
+               }
+               
+               final int xsize = this._width;
+               final int ysize = this._height;
+               final int[] xcoord = this._xcoord;
+               final int[] ycoord = this._ycoord;
+               final int coord_max = this._max_coord;
+               final int[] mkvertex = this.__detectMarker_mkvertex;
+               final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
+               final int[] indextable = limage.getIndexArray();
+               int coord_num;
+               int label_area;
+               NyARLabelingLabel label_pt;
+               NyARSquareStack wk_stack=new NyARSquareStack(100);
+
+               for (; i < label_num; i++) {
+                       label_pt = labels[i];
+                       label_area = label_pt.area;
+                       // 検査対象サイズよりも小さくなったら終了
+                       if (label_area < AR_AREA_MIN) {
+                               break;
+                       }
+                       // クリップ領域が画面の枠に接していれば除外
+                       if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+                               continue;
+                       }
+                       if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+                               continue;
+                       }
+                       // 特徴点候補であるかを確認する。
+                       if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
+                               continue;
+                       }
+
+                       // 輪郭を取得
+                       coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+                       if (coord_num == coord_max) {
+                               // 輪郭が大きすぎる。
+                               continue;
+                       }
+                       // 頂点候補のインデクスを取得
+                       final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+                       // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+                       normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+                       // 頂点情報を取得
+                       if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+//                             o_square_stack.pop();// 頂点の取得が出来なかったので破棄
+                               continue;
+                       }
+                       NyARSquare square=(NyARSquare)wk_stack.prePush();
+                       if(!getSquareLine(mkvertex,xcoord,ycoord,square)){
+                               wk_stack.pop();
+                               continue;
+                       }
+               }
+               bindQrcodeEdge(wk_stack);
+               //エッジ同士の相関関係をしらべる。
+
+               return;
        }
-    }
+       /**
+        *
+        * @param i_sq
+        * @param o_sq
+        * @return
+        */
+       public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+       {
+               NyQrCodeSymbolBinder binder=new NyQrCodeSymbolBinder();
+               binder.bimg=this.bimg;
+               binder.margeEdge(i_sq, o_sq);
 
-    public static void main(String[] args) {
-       try {
-           LabelingCamera mainwin = new LabelingCamera();
-           mainwin.setVisible(true);
-           mainwin.startCapture();
-       } catch (Exception e) {
-           e.printStackTrace();
+               return false;
+               
+               
+               
+               
        }
+       /**
+        * QRコードのエッジペアを作る
+        * @param i_square_stack
+        */
+       public void bindQrcodeEdge(NyARSquareStack i_square_stack)
+       {
+               
+               NyARSquare sq_ptr1,sq_ptr2,sq_ptr3;
+               int number_of_edge=i_square_stack.getLength();
+               if(number_of_edge<3){
+                       return;
+               }
+               NyARSquare[] sa=(NyARSquare[])i_square_stack.getArray();
+               for(int i=0;i<number_of_edge;i++)
+               {       
+                       for(int i2=i+1;i2<number_of_edge;i2++)
+                       {
+                               sq_ptr2=sa[i2];
+                               for(int i3=i2+1;i3<number_of_edge;i3++){
+                                       sq_ptr3=sa[i3];
+                                       //3個のエッジの関連性を確認する。
+                                       margeEdge(sa,null);
+                               }
+                               //
+                       }
+               }
+       }
+       /**
+        * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
+        * 
+        * @param i_v1
+        * @param i_v2
+        * @param o_line
+        */
+       final private void getLine(NyARDoublePoint2d i_v1, NyARDoublePoint2d i_v2, NyARLinear o_line)
+       {
+               final double x = i_v1.x - i_v2.x;
+               final double y = i_v1.y - i_v2.y;
+               final double x2 = x * x;
+               final double y2 = y * y;
+               final double rise_ = Math.sqrt(x2 / (x2 + y2));
+               o_line.rise = rise_;
+               o_line.run = Math.sqrt(y2 / (x2 + y2));
+               if (x < 0) {
+                       if (y < 0) {
+                               o_line.rise = -o_line.rise;
+                       } else {
+                               o_line.rise = -o_line.rise;
+                               o_line.run = -o_line.run;
+                       }
+               } else {
+                       if (y < 0) {
+                               o_line.rise = -o_line.rise;
+                               o_line.run = -o_line.run;
+                       } else {
+                               o_line.rise = -o_line.rise;
+                       }
+               }
+               o_line.intercept = (i_v1.y + (o_line.run / o_line.rise) * (i_v1.x)) * rise_;
 
-    }
+       }
+       private final INyARPca2d _pca=new NyARPca2d_MatrixPCA_O2(100);
+       private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();
+       private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();
+       private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();
+       /**
+        * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
+        * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
+        * Optimize:STEP[424->391]
+        * 
+        * @param i_cparam
+        * @return
+        * @throws NyARException
+        */
+       private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
+       {
+               final NyARLinear[] l_line = o_square.line;
+               final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;  
+               final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;
+               final NyARDoublePoint2d mean=this.__getSquareLine_mean;
+               final NyARDoublePoint2d ev=this.__getSquareLine_ev;
+       
+               
+               for (int i = 0; i < 4; i++) {
+                       final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+                       final int st = (int) (i_mkvertex[i] + w1);
+                       final int ed = (int) (i_mkvertex[i + 1] - w1);
+                       final int n = ed - st + 1;
+                       if (n < 2) {
+                               // nが2以下でmatrix.PCAを計算することはできないので、エラー
+                               return false;
+                       }
+                       //主成分分析する。
+                       this._pca.pcaWithDistortionFactor(i_xcoord, i_ycoord, st, n,dist_factor, evec, ev,mean);
+                       final NyARLinear l_line_i = l_line[i];
+                       l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+                       l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+                       l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+               }
+
+               final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
+               final NyARIntPoint[] l_imvertex = o_square.imvertex;
+               for (int i = 0; i < 4; i++) {
+                       final NyARLinear l_line_i = l_line[i];
+                       final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+                       final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+                       if (w1 == 0.0) {
+                               return false;
+                       }
+                       l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+                       l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+                       // 頂点インデクスから頂点座標を得て保存
+                       l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+                       l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+               }
+               return true;
+       }
+       /**
+        * 辺からの対角線が最長になる点を対角線候補として返す。
+        * 
+        * @param i_xcoord
+        * @param i_ycoord
+        * @param i_coord_num
+        * @return
+        */
+       private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+       {
+               final int sx = i_xcoord[0];
+               final int sy = i_ycoord[0];
+               int d = 0;
+               int w, x, y;
+               int ret = 0;
+               for (int i = 1; i < i_coord_num; i++) {
+                       x = i_xcoord[i] - sx;
+                       y = i_ycoord[i] - sy;
+                       w = x * x + y * y;
+                       if (w > d) {
+                               d = w;
+                               ret = i;
+                       }
+                       // ここでうまく終了条件入れられないかな。
+               }
+               return ret;
+       }
+
+       private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+       private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+       /**
+        * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+        * 
+        * @param i_x_coord
+        * @param i_y_coord
+        * @param i_vertex1_index
+        * @param i_coord_num
+        * @param i_area
+        * @param o_vertex
+        * 要素数はint[4]である事
+        * @return
+        */
+       private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+       {
+               final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+               final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+               final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+               final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+               final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+               int dmax = 0;
+               int v1 = i_vertex1_index;
+               for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+                       // {
+                       final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+                       if (d > dmax) {
+                               dmax = d;
+                               v1 = i;
+                       }
+               }
+               final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+               o_vertex[0] = i_vertex1_index;
+
+               if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+                       // 0 ) {
+                       return false;
+               }
+               if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+                       // < 0) {
+                       return false;
+               }
+
+               int v2;
+               if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+                       o_vertex[1] = wv1.vertex[0];
+                       o_vertex[2] = v1;
+                       o_vertex[3] = wv2.vertex[0];
+               } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+                       // 頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+                       v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+                       if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+                               return false;
+                       }
+                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+                               return false;
+                       }
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+                               o_vertex[1] = wv1.vertex[0];
+                               o_vertex[2] = wv2.vertex[0];
+                               o_vertex[3] = v1;
+                       } else {
+                               return false;
+                       }
+               } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+                       // v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+                       v2 = (v1 + end_of_coord) / 2;
+
+                       if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+                               return false;
+                       }
+                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+                               return false;
+                       }
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+                               o_vertex[1] = v1;
+                               o_vertex[2] = wv1.vertex[0];
+                               o_vertex[3] = wv2.vertex[0];
+                       } else {
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+               o_vertex[4] = end_of_coord;
+               return true;
+       }
+       /**
+        * QRコードのエッジ特徴を持つラベルであるかを調べる
+        * @param buf
+        * @param index_table
+        * @param i_label
+        * @return
+        */
+       private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)
+       {
+               int tx, bx;
+               int w;
+               int i_label_id = i_label.id;
+               int[] limage_j;
+               final int clip_l = i_label.clip_l;
+               final int clip_b = i_label.clip_b;
+               final int clip_r = i_label.clip_r;
+               final int clip_t = i_label.clip_t;
+
+               tx = bx = 0;
+               // 上接点(→)
+               limage_j = buf[clip_t];
+               for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+                       w = limage_j[i];
+                       if (w > 0 && index_table[w - 1] == i_label_id) {
+                               tx = i;
+                               break;
+                       }
+               }
+               // 下接点(←)
+               limage_j = buf[clip_b];
+               for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+                       w = limage_j[i];
+                       if (w > 0 && index_table[w - 1] == i_label_id) {
+                               bx = i;
+                               break;
+                       }
+               }
+               final int cx = (clip_l + clip_r) / 2;
+               final int cy = (clip_t + clip_b) / 2;
+               // 横断チェック(中心から線を引いて、101になるかしらべる)
+               if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {
+                       return false;
+               }
+               if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * 対角線のパターンを調べる。
+        * 
+        * @param buf
+        * @param i_px1
+        * @param i_py1
+        * @param i_px2
+        * @param i_py2
+        * @return
+        */
+       private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)
+       {
+               int sub_y = i_py2 - i_py1;
+               int sub_x = i_px2 - i_px1;
+               // 黒
+               int i = 0;
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+                               break;
+                       }
+
+               }
+               if (i == sub_y) {
+                       return false;
+               }
+               // 白
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {
+                               break;
+                       }
+
+               }
+               if (i == sub_y) {
+                       return false;
+               }
+               // 黒
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+                               break;
+                       }
+
+               }
+               if (i != sub_y) {
+                       return false;
+               }
+               // 端まで到達したらOK
+               return true;
+       }
+
+}
+
+
+public class LabelingCamera extends Frame implements JmfCaptureListener
+{
+       private final String camera_file = "../Data/camera_para.dat";
+
+       private JmfNyARRaster_RGB _raster;
+
+       private JmfCameraCapture capture;
+       private NyARParam ap;
+       public LabelingCamera() throws NyARException, NyARException
+       {
+               setBounds(0, 0, 640 + 64, 720 + 64);
+               // キャプチャの準備
+               capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+               capture.setCaptureListener(this);
+
+               // キャプチャイメージ用のラスタを準備
+               this._raster = new JmfNyARRaster_RGB(320, 240);
+               
+               // AR用カメラパラメタファイルをロード
+               ap = new NyARParam();
+               ap.loadARParamFromFile(camera_file);
+               ap.changeScreenSize(320, 240);          
+               
+               
+       }
+
+       // そのラベルが特徴点候補か返す。
+
+       private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+       private NyARGlayscaleRaster _gsraster1 = new NyARGlayscaleRaster(320, 240);
+
+       private NyARLabelingImage _limage = new NyARLabelingImage(320, 240);
+
+       private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+       private NyARRasterFilter_ARToolkitThreshold filter_gs2bin;
+
+       public void onUpdateBuffer(Buffer i_buffer)
+       {
+               NyARRasterFilter_AreaAverage gs2bin=new NyARRasterFilter_AreaAverage();
+
+               try {
+                       // キャプチャしたバッファをラスタにセット
+                       _raster.setBuffer(i_buffer);
+
+                       Graphics g = getGraphics();
+                       // キャプチャ画像
+                       BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+                       Image img = b2i.createImage(i_buffer);
+                       this.getGraphics().drawImage(img, 32, 32, this);
+
+                       // 画像1
+                       INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+                       filter_rgb2gs.doFilter(_raster, _gsraster1);
+                       this._bimg.drawImage(this._gsraster1);
+                       this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+                       
+
+                       // 画像2
+                       gs2bin.doFilter(_gsraster1, _binraster1);
+                       this._bimg.drawImage(_binraster1);
+                       this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+                       // 画像3
+                       NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+                       NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+                       labeling.attachDestination(limage);
+                       labeling.labeling(_binraster1);
+                       this._bimg.drawImage(this._gsraster1);
+                       NyARLabelingLabel[] labels = (NyARLabelingLabel[]) limage.getLabelStack().getArray();
+
+                       NyARSquareStack stack = new NyARSquareStack(100);
+                       NyARQRCodeDetector detect = new NyARQRCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+                       detect.bimg=this._bimg;
+
+                       detect.detectMarker(_binraster1, stack);
+                       for (int i = 0; i < stack.getLength(); i++) {
+                               NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray();
+                               int[] xp=new int[4]; 
+                               int[] yp=new int[4]; 
+                               for(int i2=0;i2<4;i2++){
+                                       xp[i2]=square_ptr[i].imvertex[i2].x;
+                                       yp[i2]=square_ptr[i].imvertex[i2].y;
+                               }
+                               this._bimg.getGraphics().setColor(Color.RED);
+                               this._bimg.getGraphics().drawPolygon(xp, yp,2);
+                       }
+                       this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+                       // 画像3
+                       // threshold.debugDrawHistgramMap(_workraster, _workraster2);
+                       // this._bimg2.setImage(this._workraster2);
+                       // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+                       // 画像4
+                       // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+                       // threshold.analyzeRaster(_gsraster1);
+                       // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+                       // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+                       // this._bimg.drawImage(_binraster1);
+
+                       // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+                       // detector.analyzeRaster(_binraster1);
+
+                       // this._bimg.overlayData(detector.geResult());
+
+                       // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+                       // 画像5
+
+                       /*
+                        * threshold2.debugDrawHistgramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+                        * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+                        */
+
+                       // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+       private INyARLabeling labelingFactory(int i_idx)
+       {
+               // switch(i_idx){
+               // case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
+               // case 1:{return new NyLineLabeling();}
+               // }
+               return null;
+
+       }
+
+       private void startCapture()
+       {
+               try {
+                       capture.start();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public static void main(String[] args)
+       {
+               try {
+                       LabelingCamera mainwin = new LabelingCamera();
+                       mainwin.setVisible(true);
+                       mainwin.startCapture();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
 
 }