OSDN Git Service

[バックアップ]NyARToolkit for Java
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Sun, 3 May 2009 03:44:26 +0000 (03:44 +0000)
committernyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Sun, 3 May 2009 03:44:26 +0000 (03:44 +0000)
NyARIdマーカ関連のコード(未完成)

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit@228 7cac0a50-4618-4814-88d0-24b83990f816

51 files changed:
trunk/sample/jogl/jp/nyatla/nyartoolkit/jogl/sample/JavaSimpleLite.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeDetector.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeSymbolBinder.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSquareDetector_Quad.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/utils/NyARSingleEdgeFinder.java [new file with mode: 0644]
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARFixedFloatFitVecCalculator.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSquareDetector_X2.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/RawFileTest_X2.java
trunk/src/jp/nyatla/nyartoolkit/NyARException.java
trunk/src/jp/nyatla/nyartoolkit/core/NyARMat.java
trunk/src/jp/nyatla/nyartoolkit/core/NyARSquare.java
trunk/src/jp/nyatla/nyartoolkit/core/NyARSquareDetector.java
trunk/src/jp/nyatla/nyartoolkit/core/NyARVec.java
trunk/src/jp/nyatla/nyartoolkit/core/pca2d/NyARPca2d_MatrixPCA.java
trunk/src/jp/nyatla/nyartoolkit/core/pickup/INyARColorPatt.java
trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O1.java
trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_O3.java
trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_PseudoAffine.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_GLAY_8.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_X8R8G8B8_32.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/transmat/NyARTransMat.java
trunk/src/jp/nyatla/nyartoolkit/core/transmat/optimize/NyARRotTransOptimize_Base.java
trunk/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint2d.java
trunk/src/jp/nyatla/nyartoolkit/core/types/NyARDoublePoint3d.java
trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint.java
trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint2d.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix33.java
trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix34.java
trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix44.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/types/stack/NyARIntPointStack.java
trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARDoubleMatrixProcessor.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_O1.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARSystemOfLinearEquationsProcessor.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/core2/types/matrix/NyARI64Matrix22.java
trunk/src/jp/nyatla/nyartoolkit/detector/NyARCustomSingleDetectMarker.java
trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerData.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerParam.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerPickup.java [new file with mode: 0644]
trunk/src/jp/nyatla/nyartoolkit/processor/SingleARMarkerProcesser.java
trunk/src/jp/nyatla/utils/DoubleValue.java
trunk/src/jp/nyatla/utils/IntValue.java
trunk/src/jp/nyatla/utils/NyObjectStack.java
trunk/src/jp/nyatla/utils/j2se/BufferedImageSink.java [new file with mode: 0644]
trunk/src/jp/nyatla/utils/j2se/LabelingBufferdImage.java
trunk/test/jp/nyatla/nyartoolkit/dev/CopyOfNyARColorPatt_NyIdMarker.java [new file with mode: 0644]
trunk/test/jp/nyatla/nyartoolkit/dev/LabelingCamera.java
trunk/test/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java [new file with mode: 0644]
trunk/test/jp/nyatla/nyartoolkit/dev/PattPickupTest.java [new file with mode: 0644]
trunk/test/jp/nyatla/nyartoolkit/dev/Solver.java [new file with mode: 0644]

index 9ae8f80..bac9461 100644 (file)
@@ -49,9 +49,9 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
 \r
        private final String PARAM_FILE = "../../Data/camera_para.dat";\r
 \r
-       private final static int SCREEN_X = 320;\r
+       private final static int SCREEN_X = 640;\r
 \r
-       private final static int SCREEN_Y = 240;\r
+       private final static int SCREEN_Y = 480;\r
 \r
        private Animator _animator;\r
 \r
@@ -144,7 +144,7 @@ public class JavaSimpleLite implements GLEventListener, JmfCaptureListener
                        //キャプチャの準備\r
                        JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
                        this._capture=devlist.getDevice(0);\r
-                       if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,15f)){\r
+                       if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
                                throw new Exception();\r
                        }\r
                        this._capture.setOnCapture(this);\r
index 21803c9..d219d98 100644 (file)
@@ -14,10 +14,7 @@ import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;
 import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;\r
 import jp.nyatla.nyartoolkit.core.pca2d.*;\r
 import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
-import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntPoint;\r
-import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
-import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
 import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
 \r
 public class NyARQrCodeDetector implements INyARSquareDetector\r
@@ -230,7 +227,7 @@ public class NyARQrCodeDetector implements INyARSquareDetector
         * @return\r
         * @throws NyARException\r
         */\r
-       private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARLinear[] o_line,NyARIntPoint[] o_imvertex) throws NyARException\r
+       private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARLinear[] o_line,NyARIntPoint2d[] o_imvertex) throws NyARException\r
        {\r
                final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
                final NyARDoublePoint2d mean=this.__getSquareLine_mean;\r
index 7d3688a..298392a 100644 (file)
@@ -41,9 +41,9 @@ public class NyARQrCodeSymbolBinder
                int d;\r
                int x,y;\r
                int dmax=0x7fffffff;\r
-               final NyARIntPoint[] vertex0=i_sqare[0].imvertex;\r
-               final NyARIntPoint[] vertex1=i_sqare[1].imvertex;\r
-               final NyARIntPoint[] vertex2=i_sqare[2].imvertex;\r
+               final NyARIntPoint2d[] vertex0=i_sqare[0].imvertex;\r
+               final NyARIntPoint2d[] vertex1=i_sqare[1].imvertex;\r
+               final NyARIntPoint2d[] vertex2=i_sqare[2].imvertex;\r
                for(int i=0;i<4;i++)\r
                {\r
                        for(int i2=0;i2<4;i2++)\r
@@ -74,7 +74,7 @@ public class NyARQrCodeSymbolBinder
         * @param i_sqare\r
         * @param o_vertex_id\r
         */\r
-       private static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)\r
+       private static void getMinimumLineVertex(NyARIntPoint2d[] i_sqare0,NyARIntPoint2d[] i_sqare1,int[] o_vertex_id)\r
        {\r
                //辺の長さが最小になる頂点の組合せを探す\r
                int d;\r
@@ -101,14 +101,14 @@ public class NyARQrCodeSymbolBinder
         * @param i_sqare\r
         * @param i_center\r
         */\r
-       private void getSymbolGroupCenter(NyARSquare[] i_sqare,NyARIntPoint i_center)\r
+       private void getSymbolGroupCenter(NyARSquare[] i_sqare,NyARIntPoint2d i_center)\r
        {\r
                //シンボルグループの重心を計算\r
                int cx,cy;\r
                cx=cy=0;\r
                for(int i=0;i<3;i++)\r
                {\r
-                       final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;\r
+                       final NyARIntPoint2d[] sq_ptr=i_sqare[i].imvertex;\r
                        cx+=sq_ptr[0].x;                        \r
                        cx+=sq_ptr[1].x;                        \r
                        cx+=sq_ptr[2].x;                        \r
@@ -129,7 +129,7 @@ public class NyARQrCodeSymbolBinder
         * 最小三角形の頂点IDセット\r
         * @return\r
         */\r
-       private static int getKeySymble(NyARSquare[] i_sqare,NyARIntPoint i_center,int[] i_vertex_id)\r
+       private static int getKeySymble(NyARSquare[] i_sqare,NyARIntPoint2d i_center,int[] i_vertex_id)\r
        {\r
                //シンボルグループの重心を計算\r
                final int cx=i_center.x;\r
@@ -167,7 +167,7 @@ public class NyARQrCodeSymbolBinder
                o_qr_square.line[3].copyFrom(i_sq2.line[(i_lv2+0)%4]);\r
                //歪み無しの座標系を計算\r
                final NyARDoublePoint2d[] l_sqvertex = o_qr_square.sqvertex;\r
-               final NyARIntPoint[] imvertex_ptr = o_qr_square.imvertex;\r
+               final NyARIntPoint2d[] imvertex_ptr = o_qr_square.imvertex;\r
 \r
                final NyARLinear[] l_line = o_qr_square.line;\r
                final NyARDoublePoint2d ideal_vertex=this.__bindSquare_ideal_vertex;\r
@@ -209,7 +209,7 @@ public class NyARQrCodeSymbolBinder
                int[] minimum_triangle_vertex=new int[3];\r
                int[] minimum_line_vertex=new int[2];\r
                \r
-               NyARIntPoint center=new NyARIntPoint();\r
+               NyARIntPoint2d center=new NyARIntPoint2d();\r
 \r
                //辺の長さが最小になる頂点の組合せを探す\r
                getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);\r
@@ -251,7 +251,7 @@ public class NyARQrCodeSymbolBinder
         * @param i_center\r
         * @return\r
         */\r
-       private int getDirection(NyARSquare i_square,NyARIntPoint i_vertex,NyARIntPoint i_center)\r
+       private int getDirection(NyARSquare i_square,NyARIntPoint2d i_vertex,NyARIntPoint2d i_center)\r
        {\r
                //開始点(中央シンボル)までの頂点のシフト数を決める\r
                int x,y;\r
index f22b964..4918bea 100644 (file)
@@ -422,7 +422,7 @@ public class NyARSquareDetector_Quad implements INyARSquareDetector
         }\r
 \r
         NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
-        NyARIntPoint[] l_imvertex = o_square.imvertex;\r
+        NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
         for (int i = 0; i < 4; i++)\r
         {\r
             NyARI64Linear l_line_i = i64liner[i];\r
diff --git a/trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/utils/NyARSingleEdgeFinder.java b/trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/utils/NyARSingleEdgeFinder.java
new file mode 100644 (file)
index 0000000..46196b2
--- /dev/null
@@ -0,0 +1,208 @@
+package jp.nyatla.nyartoolkit.sandbox.utils;\r
+\r
+/**\r
+ * 1区間にある1個のエッジ位置を推定するクラスです。\r
+ *\r
+ */\r
+public class NyARSingleEdgeFinder\r
+{\r
+       public static class TEdgeInfo\r
+       {\r
+               double point;   //検出したエッジの位置\r
+               int sub;                //エッジの差分\r
+       }       \r
+       private int[] _work;\r
+       private int _width;\r
+       private int _height;\r
+       public NyARSingleEdgeFinder(int i_width,int i_height)\r
+       {\r
+               this._work=new int[(i_width>i_height?i_width:i_height)+1];\r
+               this._work[this._work.length-1]=0;\r
+               this._width=i_width;\r
+               this._height=i_height;\r
+               return;\r
+       }\r
+       /**\r
+        * この関数は、一区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+        * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+        * 検出方向は左→右の順です\r
+        * @param i_pixcel\r
+        * @param i_start\r
+        * @param i_length\r
+        * @param o_out\r
+        * @return\r
+        */\r
+       public boolean scanSingleEdgeLeftToRight(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int length=this._width-1;\r
+               int p=i_y*this._width;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p+1]-i_pixcel[p];\r
+                       p++;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }\r
+       /**\r
+        * 線分内のエッジを検出します。\r
+        * この関数は、1区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+        * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+        * 検出方向は右→左の順です\r
+        * @param i_pixcel\r
+        * @param i_start\r
+        * @param i_length\r
+        * @param o_out\r
+        * @return\r
+        */\r
+       public boolean scanSingleEdgeRightToLeft(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int length=this._width-1;\r
+               int p=(i_y+1)*this._width-1;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p-1]-i_pixcel[p];\r
+                       p--;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }       \r
+       public boolean scanSingleEdgeTopToBottom(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int step=this._width;\r
+               final int length=this._height-1;\r
+               int p=i_x;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p+step]-i_pixcel[p];\r
+                       p+=step;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }\r
+       public boolean scanSingleEdgeBottomToTop(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int step=this._width;\r
+               final int length=this._height-1;\r
+               int p=i_x+step*length;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p-step]-i_pixcel[p];\r
+                       p-=step;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }       \r
+       private boolean scanSingleEdge(int[] i_pixels,int i_length,TEdgeInfo o_out)\r
+       {\r
+               //微分(2回目)して、極値2か所を得る\r
+               int max_index,min_index;\r
+               int length=i_length-1;\r
+               max_index=min_index=0;\r
+               int max_value,min_value;\r
+               max_value=min_value=0;\r
+               for(int i2=0;i2<length;i2++){\r
+                       int t=i_pixels[i2+1]-i_pixels[i2];\r
+                       if(t>max_value){\r
+                               max_index=i2;\r
+                               max_value=t;\r
+                       }\r
+                       if(t<min_value){\r
+                               min_index=i2;\r
+                               min_value=t;\r
+                       }\r
+               }\r
+               //同符号である場合、範囲内にエッジはない\r
+               if(max_value*min_value>=0){\r
+                       return false;\r
+               }               \r
+               o_out.point=(max_index+min_index)/2.0;\r
+               o_out.sub=max_value-min_value;\r
+               return true;\r
+       }\r
+       public int scanEdgeLeftToRight(int[] i_pixel,int i_y,int i_noise_th,double[] o_edge_index)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int length=this._width-1;\r
+               int p=i_y*this._width;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixel[p+1]-i_pixel[p];\r
+                       p++;\r
+               }\r
+               //0終端させるために1要素を後続に追加\r
+               return scanEdge(temp,length+1,i_noise_th,o_edge_index);\r
+       }\r
+       private int scanEdge(int[] i_pixels,int i_length,int i_noise_th,double[] o_out)\r
+       {\r
+               int points=0;\r
+               final int length=i_length;\r
+               //エッジ1区間を抜き出す\r
+               for(int i2=0;i2<length;i2++){\r
+                       int t=i_pixels[i2];\r
+                       if(t>i_noise_th){\r
+                               int st=i2;\r
+                               i2++;\r
+                               for(;i2<length;i2++){\r
+                                       t=i_pixels[i2];\r
+                                       if(t<=0){\r
+                                               //(st - i2で1区間)\r
+                                               //エッジ位置は区間の中央にする。\r
+                                               o_out[points]=(st+i2)/2.0;\r
+                                               points++;\r
+                                               if(t<0){\r
+                                                       //マイナスであれば、0を補完する\r
+                                                       i2--;\r
+                                                       i_pixels[i2]=0;\r
+                                               }\r
+                                               break;\r
+                                       }\r
+\r
+                               }\r
+                       }else if(t<-i_noise_th){\r
+                               int st=i2;\r
+                               i2++;\r
+                               for(;i2<length;i2++){\r
+                                       t=i_pixels[i2];\r
+                                       if(t>=0){\r
+                                               //(st - i2で1区間)\r
+                                               //エッジ位置は区間の中央にする。\r
+                                               o_out[points]=(st+i2)/2.0;\r
+                                               points++;\r
+                                               if(t>0){\r
+                                                       //プラスであれば、0を補完する\r
+                                                       i2--;\r
+                                                       i_pixels[i2]=0;\r
+                                               }\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               return points;\r
+       }       \r
+       /**\r
+        * 指定した配列をノイズパターンとして、ノイズ値を計算します。\r
+        * このノイズ値は、scanEdgeのノイズ値として使用できます。\r
+        * @param i_pixels\r
+        * @param i_length\r
+        * @return\r
+        */\r
+       public int getNoiseValue(int[] i_pixels,int i_length)\r
+       {\r
+               //1回微分して、その最大値と最小値を計算\r
+               int length=i_length-1;\r
+               int max_value,min_value;\r
+               max_value=min_value=0;\r
+               for(int i2=0;i2<length;i2++){\r
+                       int t=i_pixels[i2+1]-i_pixels[i2];\r
+                       if(t>max_value){\r
+                               max_value=t;\r
+                       }\r
+                       if(t<min_value){\r
+                               min_value=t;\r
+                       }\r
+               }\r
+               return (-min_value>max_value)?-min_value:max_value;\r
+       }\r
+}\r
index e8f2fdd..c15782f 100644 (file)
@@ -52,7 +52,7 @@ class NyARCustomMatrix extends NyARMat
                for (r = 0; r < this.row; r++){\r
                        ptr=i_mat.getArray();\r
                        for (c = 0; c < this.clm; c++){\r
-                               this.m[c][r]=(double)ptr[c][r]/0x10000;\r
+                               this._m[c][r]=(double)ptr[c][r]/0x10000;\r
                        }\r
                }\r
                return;\r
index 5a4feb8..f298b2e 100644 (file)
@@ -379,7 +379,7 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
                }\r
 \r
                final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
-               final NyARIntPoint[] l_imvertex = o_square.imvertex;\r
+               final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
                for (int i = 0; i < 4; i++) {\r
                        final NyARI64Linear l_line_i = i64liner[i];\r
                        final NyARI64Linear l_line_2 = i64liner[(i + 3) % 4];\r
index 09e4e72..ab7bfce 100644 (file)
@@ -38,7 +38,6 @@ import jp.nyatla.nyartoolkit.core.*;
 import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
 import jp.nyatla.nyartoolkit.core.transmat.*;\r
-import jp.nyatla.nyartoolkit.sandbox.quadx2.*;\r
 \r
 \r
 /**\r
index 058e56a..7933f52 100644 (file)
  */\r
 package jp.nyatla.nyartoolkit;\r
 \r
+/**\r
+ * NyARToolkitライブラリが生成するExceptionオブジェクトです。\r
+ *\r
+ */\r
 public class NyARException extends Exception\r
 {\r
        private static final long serialVersionUID = 1L;\r
index 636b468..1303b16 100644 (file)
@@ -45,9 +45,11 @@ public class NyARMat
         * 配列サイズと行列サイズは必ずしも一致しないことに注意 返された配列のサイズを行列の大きさとして使わないこと!\r
         * \r
         */\r
-       protected double[][] m;\r
+       protected double[][] _m;\r
+       private int[] __matrixSelfInv_nos;\r
 \r
-       protected int clm, row;\r
+       protected int clm;\r
+       protected int row;\r
 \r
        /**\r
         * デフォルトコンストラクタは機能しません。\r
@@ -61,129 +63,90 @@ public class NyARMat
 \r
        public NyARMat(int i_row, int i_clm)\r
        {\r
-               m = new double[i_row][i_clm];\r
-               clm = i_clm;\r
-               row = i_row;\r
-       }\r
-\r
-       /**\r
-        * i_row x i_clmサイズの行列を格納できるように行列サイズを変更します。 実行後、行列の各値は不定になります。\r
-        * \r
-        * @param i_row\r
-        * @param i_clm\r
-        */\r
-       public void realloc(int i_row, int i_clm)\r
-       {\r
-               if (i_row <= this.m.length && i_clm <= this.m[0].length) {\r
-                       // 十分な配列があれば何もしない。\r
-               } else {\r
-                       // 不十分なら取り直す。\r
-                       m = new double[i_row][i_clm];\r
-               }\r
+               this._m = new double[i_row][i_clm];\r
                this.clm = i_clm;\r
                this.row = i_row;\r
+               this.__matrixSelfInv_nos=new int[i_row];\r
+               return;\r
        }\r
-\r
+       \r
+       /**\r
+        * 行列の列数を返します。\r
+        * @return\r
+        */\r
        public int getClm()\r
        {\r
                return clm;\r
        }\r
-\r
-       public int getRow()\r
-       {\r
-               return row;\r
-       }\r
-\r
        /**\r
-        * 行列をゼロクリアする。\r
+        * 行列の行数を返します。\r
+        * @return\r
         */\r
-       public void zeroClear()\r
+       public int getRow()\r
        {\r
-               int i, i2;\r
-               // For順変更OK\r
-               for (i = row - 1; i >= 0; i--) {\r
-                       for (i2 = clm - 1; i2 >= 0; i2--) {\r
-                               m[i][i2] = 0.0;\r
-                       }\r
-               }\r
-       }\r
-\r
+               return row;\r
+       }       \r
+       \r
        /**\r
-        * i_copy_fromの内容を自分自身にコピーします。 高さ・幅は同一で無いと失敗します。\r
-        * \r
-        * @param i_copy_from\r
+        * 行列のサイズを変更します。\r
+        * 実行後、行列の各値は不定になります。\r
+        * @param i_row\r
+        * @param i_clm\r
         */\r
-       public void copyFrom(NyARMat i_copy_from) throws NyARException\r
+       public void realloc(int i_row, int i_clm)\r
        {\r
-               // サイズ確認\r
-               if (this.row != i_copy_from.row || this.clm != i_copy_from.clm) {\r
-                       throw new NyARException();\r
-               }\r
-               // 値コピー\r
-               for (int r = this.row - 1; r >= 0; r--) {\r
-                       for (int c = this.clm - 1; c >= 0; c--) {\r
-                               this.m[r][c] = i_copy_from.m[r][c];\r
-                       }\r
+               if (i_row <= this._m.length && i_clm <= this._m[0].length) {\r
+                       // 十分な配列があれば何もしない。\r
+               } else {\r
+                       // 不十分なら取り直す。\r
+                       this._m = new double[i_row][i_clm];\r
+                       this.__matrixSelfInv_nos=new int[i_row];\r
                }\r
+               this.clm = i_clm;\r
+               this.row = i_row;\r
+               return;\r
        }\r
-\r
-       public double[][] getArray()\r
-       {\r
-               return m;\r
-       }\r
-\r
-       // public void getRowVec(int i_row,NyARVec o_vec)\r
-       // {\r
-       // o_vec.set(this.m[i_row],this.clm);\r
-       // }\r
+       \r
+       \r
+       \r
        /**\r
-        * aとbの積を自分自身に格納する。arMatrixMul()の代替品\r
-        * \r
-        * @param a\r
-        * @param b\r
+        * i_mat_aとi_mat_bの積を計算して、thisへ格納します。\r
+        * @param i_mat_a\r
+        * @param i_mat_b\r
         * @throws NyARException\r
         */\r
-       public void matrixMul(NyARMat a, NyARMat b) throws NyARException\r
+       public void matrixMul(NyARMat i_mat_a, NyARMat i_mat_b) throws NyARException\r
        {\r
-               if (a.clm != b.row || this.row != a.row || this.clm != b.clm) {\r
-                       throw new NyARException();\r
-               }\r
+               assert i_mat_a.clm == i_mat_b.row && this.row==i_mat_a.row && this.clm==i_mat_b.clm;\r
+\r
                double w;\r
                int r, c, i;\r
-               double[][] am = a.m, bm = b.m, dm = this.m;\r
+               double[][] am = i_mat_a._m, bm = i_mat_b._m, dm = this._m;\r
                // For順変更禁止\r
                for (r = 0; r < this.row; r++) {\r
                        for (c = 0; c < this.clm; c++) {\r
-                               w = 0.0;// dest.setARELEM0(r, c,0.0);\r
-                               for (i = 0; i < a.clm; i++) {\r
-                                       w += am[r][i] * bm[i][c];// ARELEM0(dest, r, c) +=ARELEM0(a, r, i) * ARELEM0(b,i, c);\r
+                               w = 0.0;\r
+                               for (i = 0; i < i_mat_a.clm; i++) {\r
+                                       w += am[r][i] * bm[i][c];\r
                                }\r
                                dm[r][c] = w;\r
                        }\r
                }\r
-       }\r
-\r
-       private int[] wk_nos_matrixSelfInv = new int[50];\r
-\r
-       // private final static double matrixSelfInv_epsl=1.0e-10;\r
+               return;\r
+       }       \r
+       \r
        /**\r
-        * i_targetを逆行列に変換する。arMatrixSelfInv()と、arMatrixSelfInv_minv()関数を合成してあります。\r
-        * OPTIMIZE STEP[485->422]\r
-        * \r
-        * @param i_target\r
-        *            逆行列にする行列\r
-        * @return 逆行列があればTRUE/無ければFALSE\r
-        * \r
+        * 逆行列を計算して、thisへ格納します。\r
         * @throws NyARException\r
         */\r
        public boolean matrixSelfInv() throws NyARException\r
        {\r
-               double[][] ap = this.m;\r
+               double[][] ap = this._m;\r
                int dimen = this.row;\r
                int dimen_1 = dimen - 1;\r
                double[] ap_n, ap_ip, ap_i;// wap;\r
                int j, ip, nwork;\r
-               int[] nos = wk_nos_matrixSelfInv;// この関数で初期化される。\r
+               int[] nos = __matrixSelfInv_nos;//ワーク変数\r
                // double epsl;\r
                double p, pbuf, work;\r
 \r
@@ -208,9 +171,7 @@ public class NyARMat
                for (int n = 0; n < dimen; n++) {\r
                        ap_n = ap[n];// wcp = ap + n * rowa;\r
                        p = 0.0;\r
-                       for (int i = n; i < dimen; i++) {// for(i = n, wap = wcp, p =\r
-                                                                                               // 0.0; i < dimen ; i++, wap +=\r
-                                                                                               // rowa)\r
+                       for (int i = n; i < dimen; i++) {\r
                                if (p < (pbuf = Math.abs(ap[i][0]))) {\r
                                        p = pbuf;\r
                                        ip = i;\r
@@ -235,15 +196,13 @@ public class NyARMat
                        }\r
 \r
                        work = ap_n[0];\r
-                       for (j = 0; j < dimen_1; j++) {// for(j = 1, wap = wcp, work =\r
-                                                                                       // *wcp; j < dimen ; j++, wap++)\r
+                       for (j = 0; j < dimen_1; j++) {\r
                                ap_n[j] = ap_n[j + 1] / work;// *wap = *(wap + 1) / work;\r
                        }\r
                        ap_n[j] = 1.0 / work;// *wap = 1.0 / work;\r
                        for (int i = 0; i < dimen; i++) {\r
                                if (i != n) {\r
                                        ap_i = ap[i];// wap = ap + i * rowa;\r
-\r
                                        work = ap_i[0];\r
                                        for (j = 0; j < dimen_1; j++) {// for(j = 1, wbp = wcp,work = *wap;j < dimen ;j++, wap++, wbp++)\r
                                                ap_i[j] = ap_i[j + 1] - work * ap_n[j];// wap = *(wap +1) - work *(*wbp);\r
@@ -260,9 +219,7 @@ public class NyARMat
                                }\r
                        }\r
                        nos[j] = nos[n];\r
-                       for (int i = 0; i < dimen; i++) {// for(i = 0, wap = ap + j, wbp\r
-                                                                                               // = ap + n; i < dimen ;i++, wap\r
-                                                                                               // += rowa, wbp += rowa) {\r
+                       for (int i = 0; i < dimen; i++) {\r
                                ap_i = ap[i];\r
                                work = ap_i[j];// work = *wap;\r
                                ap_i[j] = ap_i[n];// *wap = *wbp;\r
@@ -273,6 +230,45 @@ public class NyARMat
        }\r
 \r
        /**\r
+        * 行列をゼロクリアする。\r
+        */\r
+       public void zeroClear()\r
+       {\r
+               int i, i2;\r
+               // For順変更OK\r
+               for (i = row - 1; i >= 0; i--) {\r
+                       for (i2 = clm - 1; i2 >= 0; i2--) {\r
+                               _m[i][i2] = 0.0;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * i_copy_fromの内容を自分自身にコピーします。 高さ・幅は同一で無いと失敗します。\r
+        * \r
+        * @param i_copy_from\r
+        */\r
+       public void copyFrom(NyARMat i_copy_from) throws NyARException\r
+       {\r
+               // サイズ確認\r
+               if (this.row != i_copy_from.row || this.clm != i_copy_from.clm) {\r
+                       throw new NyARException();\r
+               }\r
+               // 値コピー\r
+               for (int r = this.row - 1; r >= 0; r--) {\r
+                       for (int c = this.clm - 1; c >= 0; c--) {\r
+                               this._m[r][c] = i_copy_from._m[r][c];\r
+                       }\r
+               }\r
+       }\r
+\r
+       public double[][] getArray()\r
+       {\r
+               return _m;\r
+       }\r
+\r
+\r
+       /**\r
         * sourceの転置行列をdestに得る。arMatrixTrans()の代替品\r
         * \r
         * @param dest\r
@@ -288,7 +284,7 @@ public class NyARMat
                // For順変更禁止\r
                for (int r = 0; r < dest.row; r++) {\r
                        for (int c = 0; c < dest.clm; c++) {\r
-                               dest.m[r][c] = source.m[c][r];\r
+                               dest._m[r][c] = source._m[c][r];\r
                        }\r
                }\r
        }\r
@@ -308,9 +304,9 @@ public class NyARMat
                for (int r = 0; r < unit.getRow(); r++) {\r
                        for (int c = 0; c < unit.getClm(); c++) {\r
                                if (r == c) {\r
-                                       unit.m[r][c] = 1.0;\r
+                                       unit._m[r][c] = 1.0;\r
                                } else {\r
-                                       unit.m[r][c] = 0.0;\r
+                                       unit._m[r][c] = 0.0;\r
                                }\r
                        }\r
                }\r
@@ -329,8 +325,8 @@ public class NyARMat
                // 内容を転写\r
                int r, c;\r
                double[][] src_m, dest_m;\r
-               src_m = i_source.m;\r
-               dest_m = this.m;\r
+               src_m = i_source._m;\r
+               dest_m = this._m;\r
                // コピーはFor順を変えてもOK\r
                for (r = this.row - 1; r >= 0; r--) {\r
                        for (c = this.clm - 1; c >= 0; c--) {\r
@@ -345,8 +341,8 @@ public class NyARMat
                // コピー\r
                int r, c;\r
                double[][] dest_m, src_m;\r
-               dest_m = result.m;\r
-               src_m = this.m;\r
+               dest_m = result._m;\r
+               src_m = this._m;\r
                // コピーはFor順を変えてもOK\r
                for (r = this.row - 1; r >= 0; r--) {\r
                        for (c = this.clm - 1; c >= 0; c--) {\r
@@ -356,69 +352,6 @@ public class NyARMat
                return result;\r
        }\r
 \r
-       /**\r
-        * arMatrixInv関数の代替品です。 destにsourceの逆行列を返します。\r
-        * \r
-        * @param dest\r
-        * @param source\r
-        * @throws NyARException\r
-        */\r
-       public static void matrixInv(NyARMat dest, NyARMat source)\r
-                       throws NyARException\r
-       {\r
-               NyARException.trap("未チェックのパス");\r
-               dest.matrixDup(source);\r
-\r
-               NyARException.trap("未チェックのパス");\r
-               dest.matrixSelfInv();\r
-       }\r
-\r
-       public NyARMat matrixAllocInv() throws NyARException\r
-       {\r
-               NyARException.trap("未チェックのパス");\r
-               NyARMat result = matrixAllocDup();\r
-\r
-               NyARException.trap("未チェックのパス");\r
-               result.matrixSelfInv();\r
-               return result;\r
-       }\r
-\r
-       /**\r
-        * dim x dim の単位行列を作る。\r
-        * \r
-        * @param dim\r
-        * @return\r
-        * @throws NyARException\r
-        */\r
-       public static NyARMat matrixAllocUnit(int dim) throws NyARException\r
-       {\r
-               NyARException.trap("未チェックのパス");\r
-               NyARMat result = new NyARMat(dim, dim);\r
-               NyARException.trap("未チェックのパス");\r
-               NyARMat.matrixUnit(result);\r
-               return result;\r
-       }\r
-\r
-       /**\r
-        * arMatrixDispの代替品\r
-        * \r
-        * @param m\r
-        * @return\r
-        */\r
-       public int matrixDisp() throws NyARException\r
-       {\r
-               NyARException.trap("未チェックのパス");\r
-               System.out.println(" === matrix (" + row + "," + clm + ") ===");// printf(" ===matrix (%d,%d) ===\n", m->row, m->clm);\r
-               for (int r = 0; r < row; r++) {// for(int r = 0; r < m->row; r++) {\r
-                       System.out.print(" |");// printf(" |");\r
-                       for (int c = 0; c < clm; c++) {// for(int c = 0; c < m->clm; c++) {\r
-                               System.out.print(" " + m[r][c]);// printf(" %10g", ARELEM0(m, r, c));\r
-                       }\r
-                       System.out.println(" |");// printf(" |\n");\r
-               }\r
-               System.out.println(" ======================");// printf(" ======================\n");\r
-               return 0;\r
-       }\r
 \r
        private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
 \r
@@ -440,7 +373,7 @@ public class NyARMat
                int i, i2;\r
                lrow = this.row;\r
                lclm = this.clm;\r
-               double[][] lm = this.m;\r
+               double[][] lm = this._m;\r
 \r
                if (lrow <= 0 || lclm <= 0) {\r
                        throw new NyARException();\r
@@ -475,12 +408,12 @@ public class NyARMat
                double[] v;\r
                int row, clm;\r
 \r
-               row = inout.getRow();\r
-               clm = inout.getClm();\r
+               row = inout.row;\r
+               clm = inout.clm;\r
                if (mean.getClm() != clm) {\r
                        throw new NyARException();\r
                }\r
-               double[][] im = inout.m;\r
+               double[][] im = inout._m;\r
                double[] im_i;\r
                double w0, w1;\r
                v = mean.getArray();\r
@@ -541,15 +474,15 @@ public class NyARMat
                        for (int j = 0; j < row; j++) {\r
                                if (j < i) {\r
                                        NyARException.trap("未チェックのパス");\r
-                                       output.m[i][j] = output.m[j][i];// *out =\r
+                                       output._m[i][j] = output._m[j][i];// *out =\r
                                                                                                        // output->m[j*row+i];\r
                                } else {\r
                                        NyARException.trap("未チェックのパス");\r
-                                       in1 = input.m[i];// input.getRowArray(i);//in1 = &(input->m[clm*i]);\r
-                                       in2 = input.m[j];// input.getRowArray(j);//in2 = &(input->m[clm*j]);\r
-                                       output.m[i][j] = 0;// *out = 0.0;\r
+                                       in1 = input._m[i];// input.getRowArray(i);//in1 = &(input->m[clm*i]);\r
+                                       in2 = input._m[j];// input.getRowArray(j);//in2 = &(input->m[clm*j]);\r
+                                       output._m[i][j] = 0;// *out = 0.0;\r
                                        for (int k = 0; k < clm; k++) {\r
-                                               output.m[i][j] += (in1[k] * in2[k]);// *out += *(in1++)\r
+                                               output._m[i][j] += (in1[k] * in2[k]);// *out += *(in1++)\r
                                                                                                                        // * *(in2++);\r
                                        }\r
                                }\r
@@ -578,7 +511,7 @@ public class NyARMat
                }\r
 \r
                int k, j;\r
-               double[][] out_m = i_output.m;\r
+               double[][] out_m = i_output._m;\r
                double w;\r
                for (int i = 0; i < clm; i++) {\r
                        for (j = 0; j < clm; j++) {\r
@@ -587,7 +520,7 @@ public class NyARMat
                                } else {\r
                                        w = 0.0;// *out = 0.0;\r
                                        for (k = 0; k < row; k++) {\r
-                                               in_ = input.m[k];// in=input.getRowArray(k);\r
+                                               in_ = input._m[k];// in=input.getRowArray(k);\r
                                                w += (in_[i] * in_[j]);// *out += *in1 * *in2;\r
                                        }\r
                                        out_m[i][j] = w;\r
@@ -625,7 +558,7 @@ public class NyARMat
                if (ev == null) {\r
                        throw new NyARException();\r
                }\r
-               final double[][] L_m = this.m;\r
+               final double[][] L_m = this._m;\r
                this.vecTridiagonalize(dv, ev, 1);\r
 \r
                ev_array[0] = 0.0;// ev->v[0] = 0.0;\r
@@ -722,7 +655,7 @@ public class NyARMat
        {\r
                int i;\r
                double w;\r
-               double[] r1 = this.m[i_row_1], r2 = this.m[i_row_2];\r
+               double[] r1 = this._m[i_row_1], r2 = this._m[i_row_2];\r
                // For順変更OK\r
                for (i = clm - 1; i >= 0; i--) {\r
                        w = r1[i];\r
@@ -767,8 +700,8 @@ public class NyARMat
                double sum, work;\r
 \r
                NyARException.trap("未チェックのパス");\r
-               m = output.m;// m = output->m;\r
-               in_ = input.m;\r
+               m = output._m;// m = output->m;\r
+               in_ = input._m;\r
                int i;\r
                ev_array = ev.getArray();\r
                for (i = 0; i < row; i++) {\r
@@ -781,7 +714,7 @@ public class NyARMat
                                                                                                                // sqrt(fabs(ev->v[i]));\r
                        for (int j = 0; j < clm; j++) {\r
                                sum = 0.0;\r
-                               m1 = u.m[i];// m1 = &(u->m[i*row]);\r
+                               m1 = u._m[i];// m1 = &(u->m[i*row]);\r
                                // m2=input.getPointer(j);//m2 = &(input->m[j]);\r
                                for (int k = 0; k < row; k++) {\r
                                        sum += m1[k] + in_[k][j];// sum += *m1 * *m2;\r
@@ -858,8 +791,8 @@ public class NyARMat
                        NyARException.trap("未チェックのパス");\r
                        PCA_EV_create(this, u, o_output, o_ev);\r
                } else {\r
-                       m1 = u.m;// m1 = u->m;\r
-                       m2 = o_output.m;// m2 = output->m;\r
+                       m1 = u._m;// m1 = u->m;\r
+                       m2 = o_output._m;// m2 = output->m;\r
                        int i;\r
                        for (i = 0; i < min; i++) {\r
                                if (ev_array[i] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
@@ -878,71 +811,40 @@ public class NyARMat
                        }\r
                }\r
        }\r
-\r
-       private NyARMat wk_work_matrixPCA = null;\r
-\r
        /**\r
-        * int arMatrixPCA( ARMat *input, ARMat *evec, ARVec *ev, ARVec *mean );\r
-        * 関数の置き換え。input引数がthisになる。 Optimize:2008.04.19\r
-        * \r
+        * 主成分分析を実行して、結果をthisと引数へ格納します。\r
         * @param o_evec\r
         * @param o_ev\r
-        * \r
-        * @param mean\r
+        * @param o_mean\r
         * @throws NyARException\r
         */\r
-       public void matrixPCA(NyARMat o_evec, NyARVec o_ev, NyARVec mean)throws NyARException\r
-       {\r
-               double srow, sum;\r
-               int l_row, l_clm;\r
-               int check;\r
-\r
-               l_row = this.row;// row = input->row;\r
-               l_clm = this.clm;// clm = input->clm;\r
-               check = (l_row < l_clm) ? l_row : l_clm;\r
-               if (l_row < 2 || l_clm < 2) {\r
-                       throw new NyARException();\r
-               }\r
-               if (o_evec.clm != l_clm || o_evec.row != check) {// if( evec->clm !=\r
-                                                                                                                       // input->clm ||\r
-                                                                                                                       // evec->row !=\r
-                                                                                                                       // check ){\r
-                       throw new NyARException();\r
-               }\r
-               if (o_ev.getClm() != check) {// if( ev->clm != check ){\r
-                       throw new NyARException();\r
-               }\r
-               if (mean.getClm() != l_clm) {// if( mean->clm != input->clm ){\r
-                       throw new NyARException();\r
-               }\r
-\r
-               // 自分の内容をワークにコピー(高速化の為に、1度作ったインスタンスは使いまわす)\r
-               NyARMat work;\r
-               if (this.wk_work_matrixPCA == null) {\r
-                       work = this.matrixAllocDup();\r
-                       this.wk_work_matrixPCA = work;\r
-               } else {\r
-                       work = this.wk_work_matrixPCA;\r
-                       work.matrixDup(this);// arMatrixAllocDup( input );work =\r
-                                                                       // arMatrixAllocDup( input );\r
-               }\r
-\r
-               srow = Math.sqrt((double) l_row);\r
-               work.PCA_EX(mean);\r
-\r
-               PCA_CENTER(work, mean);\r
+       public void pca(NyARMat o_evec, NyARVec o_ev, NyARVec o_mean)throws NyARException\r
+       {\r
+               final double l_row = this.row;// row = input->row;\r
+               final double l_clm = this.clm;// clm = input->clm;\r
+               final double check=(l_row < l_clm) ? l_row : l_clm;\r
+               \r
+               assert l_row >= 2 || l_clm >= 2;\r
+               assert o_evec.clm == l_clm && o_evec.row == check;\r
+               assert o_ev.getClm() == check;\r
+               assert o_mean.getClm() == l_clm;\r
+               \r
+               final double srow = Math.sqrt((double) l_row);\r
+               PCA_EX(o_mean);\r
+\r
+               PCA_CENTER(this, o_mean);\r
 \r
                int i, j;\r
                // For順変更OK\r
                for (i = 0; i < l_row; i++) {\r
                        for (j = 0; j < l_clm; j++) {\r
-                               work.m[i][j] /= srow;// work->m[i] /= srow;\r
+                               this._m[i][j] /= srow;// work->m[i] /= srow;\r
                        }\r
                }\r
 \r
-               work.PCA_PCA(o_evec, o_ev);\r
+               PCA_PCA(o_evec, o_ev);\r
 \r
-               sum = 0.0;\r
+               double sum = 0.0;\r
                double[] ev_array = o_ev.getArray();\r
                int ev_clm = o_ev.getClm();\r
                // For順変更禁止\r
@@ -953,111 +855,10 @@ public class NyARMat
                for (i = 0; i < ev_clm; i++) {// for(int i = 0; i < ev->clm; i++ ){\r
                        ev_array[i] /= sum;// ev->v[i] /= sum;\r
                }\r
-       }\r
-\r
-       /* int arMatrixPCA2( ARMat *input, ARMat *evec, ARVec *ev ); */\r
-       public static void arMatrixPCA2(NyARMat input, NyARMat evec, NyARVec ev) throws NyARException\r
-       {\r
-               NyARException.trap("未チェックのパス");\r
-               NyARMat work;\r
-               // double srow; // unreferenced\r
-               double sum;\r
-               int row, clm;\r
-               int check;\r
-\r
-               row = input.row;// row = input->row;\r
-               clm = input.clm;// clm = input->clm;\r
-               check = (row < clm) ? row : clm;\r
-               if (row < 2 || clm < 2) {\r
-                       throw new NyARException();\r
-               }\r
-               if (evec.getClm() != input.clm || evec.row != check) {// if( evec->clm!= input->clm|| evec->row!= check ){\r
-                       throw new NyARException();\r
-               }\r
-               if (ev.getClm() != check) {// if( ev->clm != check ){\r
-                       throw new NyARException();\r
-               }\r
-\r
-               NyARException.trap("未チェックのパス");\r
-               work = input.matrixAllocDup();\r
-\r
-               NyARException.trap("未チェックパス");\r
-               work.PCA_PCA(evec, ev);// rval = PCA( work, evec, ev );\r
-               sum = 0.0;\r
-               double[] ev_array = ev.getArray();\r
-               for (int i = 0; i < ev.getClm(); i++) {// for( i = 0; i < ev->clm; i++\r
-                                                                                               // ){\r
-                       NyARException.trap("未チェックパス");\r
-                       sum += ev_array[i];// sum += ev->v[i];\r
-               }\r
-               for (int i = 0; i < ev.getClm(); i++) {// for(int i = 0; i < ev->clm;i++ ){\r
-                       NyARException.trap("未チェックパス");\r
-                       ev_array[i] /= sum;// ev->v[i] /= sum;\r
-               }\r
                return;\r
        }\r
+       \r
 \r
-       public static NyARMat matrixAllocMul(NyARMat a, NyARMat b) throws NyARException\r
-       {\r
-               NyARException.trap("未チェックのパス");\r
-               NyARMat dest = new NyARMat(a.row, b.clm);\r
-               NyARException.trap("未チェックのパス");\r
-               dest.matrixMul(a, b);\r
-               return dest;\r
-       }\r
-\r
-       /* static double mdet(double *ap, int dimen, int rowa) */\r
-       private static double Det_mdet(double[][] ap, int dimen, int rowa) throws NyARException\r
-       {\r
-               NyARException.trap("動作未チェック/配列化未チェック");\r
-               double det = 1.0;\r
-               double work;\r
-               int is_ = 0;\r
-               int mmax;\r
-\r
-               for (int k = 0; k < dimen - 1; k++) {\r
-                       mmax = k;\r
-                       for (int i = k + 1; i < dimen; i++) {\r
-                               // if (Math.abs(arMatrixDet_MATRIX_get(ap, i, k, rowa)) >\r
-                               // Math.abs(arMatrixDet_MATRIX_get(ap, mmax, k, rowa))){\r
-                               if (Math.abs(ap[i][k]) > Math.abs(ap[mmax][k])) {\r
-                                       mmax = i;\r
-                               }\r
-                       }\r
-                       if (mmax != k) {\r
-                               for (int j = k; j < dimen; j++) {\r
-                                       work = ap[k][j];// work = MATRIX(ap, k, j, rowa);\r
-                                       ap[k][j] = ap[mmax][j];// MATRIX(ap, k, j, rowa) =MATRIX(ap, mmax, j, rowa);\r
-                                       ap[mmax][j] = work;// MATRIX(ap, mmax, j, rowa) = work;\r
-                               }\r
-                               is_++;\r
-                       }\r
-                       for (int i = k + 1; i < dimen; i++) {\r
-                               work = ap[i][k] / ap[k][k];// work = arMatrixDet_MATRIX_get(ap,i, k, rowa) /arMatrixDet_MATRIX_get(ap, k, k,rowa);\r
-                               for (int j = k + 1; j < dimen; j++) {\r
-                                       // MATRIX(ap, i, j, rowa) -= work * MATRIX(ap, k, j, rowa);\r
-                                       ap[i][j] -= work * ap[k][j];\r
-                               }\r
-                       }\r
-               }\r
-               for (int i = 0; i < dimen; i++) {\r
-                       det = ap[i][i];// det *= MATRIX(ap, i, i, rowa);\r
-               }\r
-               for (int i = 0; i < is_; i++) {\r
-                       det *= -1.0;\r
-               }\r
-               return det;\r
-       }\r
-\r
-       /* double arMatrixDet(ARMat *m); */\r
-       public static double arMatrixDet(NyARMat m) throws NyARException\r
-       {\r
-               NyARException.trap("動作未チェック/配列化未チェック");\r
-               if (m.row != m.clm) {\r
-                       return 0.0;\r
-               }\r
-               return Det_mdet(m.getArray(), m.row, m.clm);// return mdet(m->m, m->row,m->row);\r
-       }\r
 \r
        private final NyARVec wk_vecTridiagonalize_vec = new NyARVec(0);\r
 \r
@@ -1099,7 +900,7 @@ public class NyARMat
 \r
                for (int k = 0; k < dim - 2; k++) {\r
 \r
-                       a_vec_k = this.m[k];\r
+                       a_vec_k = this._m[k];\r
                        vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//double[]\r
                                                                                        // vec_array=vec.getArray();\r
                        NyARException.trap("未チェックパス");\r
@@ -1118,11 +919,11 @@ public class NyARMat
                                s = 0.0;\r
                                for (int j = k + 1; j < i; j++) {\r
                                        NyARException.trap("未チェックのパス");\r
-                                       s += this.m[j][i] * a_vec_k[j];// s += a_array[j][i] *vec.v[j];//s +=a.get(j*dim+i) *v.get(j);//s +=a->m[j*dim+i] * v[j];\r
+                                       s += this._m[j][i] * a_vec_k[j];// s += a_array[j][i] *vec.v[j];//s +=a.get(j*dim+i) *v.get(j);//s +=a->m[j*dim+i] * v[j];\r
                                }\r
                                for (int j = i; j < dim; j++) {\r
                                        NyARException.trap("未チェックのパス");\r
-                                       s += this.m[i][j] * a_vec_k[j];// s += a_array[i][j] *vec.v[j];//s +=a.get(i*dim+j) *v.get(j);//s +=a->m[i*dim+j] * v[j];\r
+                                       s += this._m[i][j] * a_vec_k[j];// s += a_array[i][j] *vec.v[j];//s +=a.get(i*dim+j) *v.get(j);//s +=a->m[i*dim+j] * v[j];\r
                                }\r
                                NyARException.trap("未チェックのパス");\r
                                d_vec[i] = s;// d.v[i]=s;//d->v[i] = s;\r
@@ -1131,7 +932,7 @@ public class NyARMat
                        // wv1.clm = wv2.clm = dim-k-1;\r
                        // wv1.v = &(v[k+1]);\r
                        // wv2.v = &(d->v[k+1]);\r
-                       a_vec_k = this.m[k];\r
+                       a_vec_k = this._m[k];\r
                        vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);\r
                        // vec_array=vec.getArray();\r
                        NyARException.trap("未チェックパス");\r
@@ -1143,34 +944,34 @@ public class NyARMat
                                q = d_vec[i];// d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
                                for (int j = i; j < dim; j++) {\r
                                        NyARException.trap("未チェックパス");\r
-                                       this.m[i][j] -= p * (d_vec[j] + q * a_vec_k[j]);// a.m[i][j]-=p*(d.v[j] +q*vec.v[j]);//a->m[i*dim+j] -=p*(d->v[j]) + q*v[j];\r
+                                       this._m[i][j] -= p * (d_vec[j] + q * a_vec_k[j]);// a.m[i][j]-=p*(d.v[j] +q*vec.v[j]);//a->m[i*dim+j] -=p*(d->v[j]) + q*v[j];\r
                                }\r
                        }\r
                }\r
 \r
                if (dim >= 2) {\r
-                       d_vec[dim - 2] = 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
-                       e_vec[dim - 2 + i_e_start] = 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
+                       d_vec[dim - 2] = 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
+                       e_vec[dim - 2 + i_e_start] = 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
                }\r
 \r
                if (dim >= 1) {\r
-                       d_vec[dim - 1] = 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
+                       d_vec[dim - 1] = 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
                NyARVec vec2 = this.wk_vecTridiagonalize_vec2;\r
                for (int k = dim - 1; k >= 0; k--) {\r
-                       a_vec_k = this.m[k];\r
+                       a_vec_k = this._m[k];\r
                        vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//v =a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
                        if (k < dim - 2) {\r
                                for (int i = k + 1; i < dim; i++) {\r
                                        // wv1.clm = wv2.clm = dim-k-1;\r
                                        // wv1.v = &(v[k+1]);\r
                                        // wv2.v = &(a->m[i*dim+k+1]);\r
-                                       vec2.setNewArray(this.m[i], clm);// vec2=this.getRowVec(i);\r
+                                       vec2.setNewArray(this._m[i], clm);// vec2=this.getRowVec(i);\r
 \r
                                        t = vec.vecInnerproduct(vec2, k + 1);\r
                                        for (int j = k + 1; j < dim; j++) {\r
                                                NyARException.trap("未チェックパス");\r
-                                               this.m[i][j] -= t * a_vec_k[j];// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]-= t * v[j];\r
+                                               this._m[i][j] -= t * a_vec_k[j];// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]-= t * v[j];\r
                                        }\r
                                }\r
                        }\r
index b8a2b5b..768706f 100644 (file)
@@ -45,13 +45,13 @@ public class NyARSquare
        public int direction;\r
        public NyARLinear[] line = new NyARLinear[4];\r
        public NyARDoublePoint2d[] sqvertex = new NyARDoublePoint2d[4];\r
-       public NyARIntPoint[] imvertex = new NyARIntPoint[4];\r
+       public NyARIntPoint2d[] imvertex = new NyARIntPoint2d[4];\r
        public NyARSquare()\r
        {\r
                this.direction=DIRECTION_UNKNOWN;\r
                for(int i=0;i<4;i++){\r
                        this.sqvertex[i]=new NyARDoublePoint2d();\r
-                       this.imvertex[i]=new NyARIntPoint();\r
+                       this.imvertex[i]=new NyARIntPoint2d();\r
                        this.line[i]=new NyARLinear();\r
                }\r
        }\r
index 09440bc..e34f9d1 100644 (file)
@@ -378,7 +378,7 @@ public class NyARSquareDetector implements INyARSquareDetector
                }\r
 \r
                final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
-               final NyARIntPoint[] l_imvertex = o_square.imvertex;\r
+               final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
                for (int i = 0; i < 4; i++) {\r
                        final NyARLinear l_line_i = l_line[i];\r
                        final NyARLinear l_line_2 = l_line[(i + 3) % 4];\r
index 8bc84d7..7c43f02 100644 (file)
@@ -156,121 +156,6 @@ public class NyARVec
                return -s;\r
        }\r
 \r
-       // /**\r
-       // * arVecTridiagonalize関数の代替品\r
-       // * a,d,e間で演算をしてる。何をどうしているかはさっぱりさっぱり\r
-       // * @param a\r
-       // * @param d\r
-       // * @param e\r
-       // * @param i_e_start\r
-       // * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
-       // * @return\r
-       // * @throws NyARException\r
-       // */\r
-       // public static void vecTridiagonalize(NyARMat a, NyARVec d, NyARVec e,int\r
-       // i_e_start) throws NyARException\r
-       // {\r
-       // NyARVec vec,vec2;\r
-       // double[][] a_array=a.getArray();\r
-       // double s, t, p, q;\r
-       // int dim;\r
-       //\r
-       // if(a.getClm()!=a.getRow()){\r
-       // throw new NyARException();\r
-       // }\r
-       // if(a.getClm() != d.clm){\r
-       // throw new NyARException();\r
-       // }\r
-       // if(a.getClm() != e.clm){\r
-       // throw new NyARException();\r
-       // }\r
-       // dim = a.getClm();\r
-       //\r
-       // for(int k = 0; k < dim-2; k++ ){\r
-       // vec=a.getRowVec(k);\r
-       // // double[] vec_array=vec.getArray();\r
-       // NyARException.trap("未チェックパス");\r
-       // d.v[k]=vec.v[k];//d.set(k,v.get(k)); //d->v[k] = v[k];\r
-       //\r
-       // //wv1.clm = dim-k-1;\r
-       // //wv1.v = &(v[k+1]);\r
-       // NyARException.trap("未チェックパス");\r
-       // e.v[k+i_e_start]=vec.vecHousehold(k+1);//e->v[k] = arVecHousehold(&wv1);\r
-       // if(e.v[k+i_e_start]== 0.0 ){\r
-       // continue;\r
-       // }\r
-       //\r
-       // for(int i = k+1; i < dim; i++ ){\r
-       // s = 0.0;\r
-       // for(int j = k+1; j < i; j++ ) {\r
-       // NyARException.trap("未チェックのパス");\r
-       // s += a_array[j][i] * vec.v[j];//s += a.get(j*dim+i) * v.get(j);//s +=\r
-       // a->m[j*dim+i] * v[j];\r
-       // }\r
-       // for(int j = i; j < dim; j++ ) {\r
-       // NyARException.trap("未チェックのパス");\r
-       // s += a_array[i][j] * vec.v[j];//s += a.get(i*dim+j) * v.get(j);//s +=\r
-       // a->m[i*dim+j] * v[j];\r
-       // }\r
-       // NyARException.trap("未チェックのパス");\r
-       // d.v[i]=s;//d->v[i] = s;\r
-       // }\r
-       //\r
-       //\r
-       // //wv1.clm = wv2.clm = dim-k-1;\r
-       // //wv1.v = &(v[k+1]);\r
-       // //wv2.v = &(d->v[k+1]);\r
-       // vec=a.getRowVec(k);\r
-       // // vec_array=vec.getArray();\r
-       // NyARException.trap("未チェックパス");\r
-       // t = vec.vecInnerproduct(d,k+1)/ 2;\r
-       // for(int i = dim-1; i > k; i-- ) {\r
-       // NyARException.trap("未チェックパス");\r
-       // p = vec.v[i];//p = v.get(i);//p = v[i];\r
-       // d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
-       // for(int j = i; j < dim; j++ ){\r
-       // NyARException.trap("未チェックパス");\r
-       // a_array[i][j]-=p*(d.v[j] + q*vec.v[j]);//a->m[i*dim+j] -= p*(d->v[j]) +\r
-       // q*v[j];\r
-       // }\r
-       // }\r
-       // }\r
-       //\r
-       // if( dim >= 2) {\r
-       // d.v[dim-2]=a_array[dim-2][dim-2];//d->v[dim-2] =\r
-       // a->m[(dim-2)*dim+(dim-2)];\r
-       // e.v[dim-2+i_e_start]=a_array[dim-2][dim-1];//e->v[dim-2] =\r
-       // a->m[(dim-2)*dim+(dim-1)];\r
-       // }\r
-       //\r
-       // if( dim >= 1 ){\r
-       // d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =\r
-       // a->m[(dim-1)*dim+(dim-1)];\r
-       // }\r
-       //\r
-       // for(int k = dim-1; k >= 0; k--) {\r
-       // vec=a.getRowVec(k);//v = a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
-       // if( k < dim-2 ) {\r
-       // for(int i = k+1; i < dim; i++ ){\r
-       // //wv1.clm = wv2.clm = dim-k-1;\r
-       // //wv1.v = &(v[k+1]);\r
-       // //wv2.v = &(a->m[i*dim+k+1]);\r
-       // vec2=a.getRowVec(i);\r
-       //\r
-       // t = vec.vecInnerproduct(vec2,k+1);\r
-       // for(int j = k+1; j < dim; j++ ){\r
-       // NyARException.trap("未チェックパス");\r
-       // a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]\r
-       // -= t * v[j];\r
-       // }\r
-       // }\r
-       // }\r
-       // for(int i = 0; i < dim; i++ ){\r
-       // vec.v[i]=0.0;//v.set(i,0.0);//v[i] = 0.0;\r
-       // }\r
-       // vec.v[k]=1;//v.set(k,1);//v[k] = 1;\r
-       // }\r
-       // }\r
        /**\r
         * 現在ラップしている配列を取り外して、新しい配列をラップします。\r
         * \r
index 5aba4a8..316b4e6 100644 (file)
@@ -58,7 +58,7 @@ public class NyARPca2d_MatrixPCA implements INyARPca2d
                        input_array[i][1]=i_y[i];\r
                }\r
                // 主成分分析\r
-               input.matrixPCA(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
+               input.pca(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
index 09078f9..9ee645f 100644 (file)
@@ -34,9 +34,8 @@ package jp.nyatla.nyartoolkit.core.pickup;
 import jp.nyatla.nyartoolkit.NyARException;\r
 import jp.nyatla.nyartoolkit.core.NyARSquare;\r
 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
-import jp.nyatla.nyartoolkit.core.raster.*;\r
 \r
-public interface INyARColorPatt extends INyARRaster\r
+public interface INyARColorPatt extends INyARRgbRaster\r
 {\r
        /**\r
         * ラスタイメージからi_square部分のカラーパターンを抽出して、thisメンバに格納します。\r
index f956958..2b6abcd 100644 (file)
@@ -36,6 +36,7 @@ import jp.nyatla.nyartoolkit.core.NyARMat;
 import jp.nyatla.nyartoolkit.core.NyARSquare;\r
 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
 import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
 /**\r
  * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
@@ -48,112 +49,91 @@ public class NyARColorPatt_O1 implements INyARColorPatt
        \r
        private int[] _patdata;\r
        private NyARBufferReader _buf_reader;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
 \r
        private NyARIntSize _size;\r
 \r
        public NyARColorPatt_O1(int i_width, int i_height)\r
        {\r
                //入力制限\r
-               assert i_width<=64;\r
-               assert i_height<=64;\r
+               assert i_width<=64 && i_height<=64;\r
                \r
                this._size=new NyARIntSize(i_width,i_height);\r
                this._patdata = new int[i_height*i_width];\r
                this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
                return;\r
        }\r
 \r
-       public int getWidth()\r
+       public final int getWidth()\r
        {\r
                return this._size.w;\r
        }\r
-       public int getHeight()\r
+       public final int getHeight()\r
        {\r
                return this._size.h;\r
        }\r
-       public NyARIntSize getSize()\r
+       public final NyARIntSize getSize()\r
        {\r
                return  this._size;\r
        }\r
-       public INyARBufferReader getBufferReader()\r
+       public final INyARBufferReader getBufferReader()\r
        {\r
                return this._buf_reader;\r
        }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
 \r
-       private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
-\r
-       private final NyARMat wk_get_cpara_b = new NyARMat(8, 1);\r
-\r
-       private final NyARMat wk_get_cpara_c = new NyARMat(8, 1);\r
-\r
-       /**\r
-        * \r
-        * @param world\r
-        * @param vertex\r
-        * @param para\r
-        *            [3x3]\r
-        * @throws NyARException\r
-        */\r
-       private boolean get_cpara(double world[][], double vertex[][], double[] para)throws NyARException\r
+       private final NyARMat __get_cpara_a = new NyARMat(8, 8);\r
+       private final NyARMat __get_cpara_b = new NyARMat(8, 1);\r
+       private final double[][] __get__cpara_world = {{ 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
+       \r
+       final protected boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
        {\r
-               NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+               double[][] world = this.__get__cpara_world;\r
+               NyARMat a = __get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
                double[][] a_array = a.getArray();\r
-               NyARMat b = wk_get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+               NyARMat b = __get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
                double[][] b_array = b.getArray();\r
-               double[] a_pt0, a_pt1, world_pti;\r
+               double[] a_pt0, a_pt1;\r
+               double[] world_pti;\r
 \r
                for (int i = 0; i < 4; i++) {\r
                        a_pt0 = a_array[i * 2];\r
                        a_pt1 = a_array[i * 2 + 1];\r
                        world_pti = world[i];\r
 \r
-                       a_pt0[0] = world_pti[0];// a->m[i*16+0] = world[i][0];\r
-                       a_pt0[1] = world_pti[1];// a->m[i*16+1] = world[i][1];\r
+                       a_pt0[0] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
+                       a_pt0[1] = (double) world_pti[1];// a->m[i*16+1] = world[i][1];\r
                        a_pt0[2] = 1.0;// a->m[i*16+2] = 1.0;\r
                        a_pt0[3] = 0.0;// a->m[i*16+3] = 0.0;\r
                        a_pt0[4] = 0.0;// a->m[i*16+4] = 0.0;\r
                        a_pt0[5] = 0.0;// a->m[i*16+5] = 0.0;\r
-                       a_pt0[6] = -world_pti[0] * vertex[i][0];// a->m[i*16+6] =-world[i][0] *vertex[i][0];\r
-                       a_pt0[7] = -world_pti[1] * vertex[i][0];// a->m[i*16+7] =-world[i][1] *vertex[i][0];\r
+                       a_pt0[6] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
+                       a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// a->m[i*16+7]=-world[i][1]*vertex[i][0];\r
                        a_pt1[0] = 0.0;// a->m[i*16+8] = 0.0;\r
                        a_pt1[1] = 0.0;// a->m[i*16+9] = 0.0;\r
                        a_pt1[2] = 0.0;// a->m[i*16+10] = 0.0;\r
-                       a_pt1[3] = world_pti[0];// a->m[i*16+11] = world[i][0];\r
-                       a_pt1[4] = world_pti[1];// a->m[i*16+12] = world[i][1];\r
+                       a_pt1[3] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
+                       a_pt1[4] = (double) world_pti[1];// a->m[i*16+12] = world[i][1];\r
                        a_pt1[5] = 1.0;// a->m[i*16+13] = 1.0;\r
-                       a_pt1[6] = -world_pti[0] * vertex[i][1];// a->m[i*16+14] =-world[i][0] *vertex[i][1];\r
-                       a_pt1[7] = -world_pti[1] * vertex[i][1];// a->m[i*16+15] =-world[i][1] *vertex[i][1];\r
-                       b_array[i * 2 + 0][0] = vertex[i][0];// b->m[i*2+0] =vertex[i][0];\r
-                       b_array[i * 2 + 1][0] = vertex[i][1];// b->m[i*2+1] =vertex[i][1];\r
+                       a_pt1[6] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
+                       a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
+                       b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
+                       b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// b->m[i*2+1] =vertex[i][1];\r
                }\r
                if (!a.matrixSelfInv()) {\r
-                       return false;// 逆行列を求められないので失敗\r
+                       return false;\r
                }\r
-               NyARMat c = wk_get_cpara_c;// 次処理で結果を受け取るので、初期化不要//new NyARMat( 8, 1 );\r
-               double[][] c_array = c.getArray();\r
 \r
-               c.matrixMul(a, b);\r
-               for (int i = 0; i < 2; i++) {\r
-                       para[i * 3 + 0] = c_array[i * 3 + 0][0];// para[i][0] = c->m[i*3+0];\r
-                       para[i * 3 + 1] = c_array[i * 3 + 1][0];// para[i][1] = c->m[i*3+1];\r
-                       para[i * 3 + 2] = c_array[i * 3 + 2][0];// para[i][2] = c->m[i*3+2];\r
-               }\r
-               para[2 * 3 + 0] = c_array[2 * 3 + 0][0];// para[2][0] = c->m[2*3+0];\r
-               para[2 * 3 + 1] = c_array[2 * 3 + 1][0];// para[2][1] = c->m[2*3+1];\r
-               para[2 * 3 + 2] = 1.0;// para[2][2] = 1.0;\r
+               o_para.matrixMul(a, b);\r
                return true;\r
-       }\r
-\r
-       private final double[][] wk_pickFromRaster_local = new double[4][2];\r
-\r
-       private final double[] wk_pickFromRaster_para = new double[9];// [3][3];\r
-\r
-       private final double[][] wk_pickFromRaster_world = {// double world[4][2];\r
-       { 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
-\r
-\r
-       private final int[] wk_pickFromRaster_rgb_tmp = new int[3];\r
-\r
+       }       \r
+       private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+       private final NyARMat __pickFromRaster_cpara_c = new NyARMat(8, 1);\r
+       \r
        /**\r
         * imageから、i_markerの位置にあるパターンを切り出して、保持します。 Optimize:STEP[769->]\r
         * \r
@@ -164,48 +144,37 @@ public class NyARColorPatt_O1 implements INyARColorPatt
         */\r
        public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
        {\r
-               int lx1, lx2, ly1, ly2;\r
-\r
-               int img_x = image.getWidth();\r
-               int img_y = image.getHeight();\r
-\r
-               double xdiv2_reciprocal; // [tp]\r
-               double ydiv2_reciprocal; // [tp]\r
-\r
-               // int[] x_coord=i_marker.x_coord;\r
-               // int[] y_coord=i_marker.y_coord;\r
-               // int[] vertex=i_marker.mkvertex;\r
-               double[][] local = wk_pickFromRaster_local;// double local[4][2];\r
-               //\r
-               for (int i = 0; i < 4; i++) {\r
-                       local[i][0] = i_square.imvertex[i].x;\r
-                       local[i][1] = i_square.imvertex[i].y;\r
-               }\r
+               final NyARIntPoint2d[] local = i_square.imvertex;\r
 \r
-               double[][] world = wk_pickFromRaster_world;\r
-               /*\r
-                * world[0][0] = 100.0; world[0][1] = 100.0; world[1][0] = 100.0 + 10.0;\r
-                * world[1][1] = 100.0; world[2][0] = 100.0 + 10.0; world[2][1] = 100.0 +\r
-                * 10.0; world[3][0] = 100.0; world[3][1] = 100.0 + 10.0;\r
-                */\r
-               double[] para = wk_pickFromRaster_para; // double para[3][3];\r
                // パターンの切り出しに失敗することもある。\r
-               if (!get_cpara(world, local, para)) {\r
+               NyARMat cpara = this.__pickFromRaster_cpara_c;\r
+               if (!get_cpara(i_square.imvertex, cpara)) {\r
                        return false;\r
                }\r
-               lx1 = (int) ((local[0][0] - local[1][0]) * (local[0][0] - local[1][0]) + (local[0][1] - local[1][1])* (local[0][1] - local[1][1]));\r
-               lx2 = (int) ((local[2][0] - local[3][0]) * (local[2][0] - local[3][0]) + (local[2][1] - local[3][1])* (local[2][1] - local[3][1]));\r
-               ly1 = (int) ((local[1][0] - local[2][0]) * (local[1][0] - local[2][0]) + (local[1][1] - local[2][1])* (local[1][1] - local[2][1]));\r
-               ly2 = (int) ((local[3][0] - local[0][0]) * (local[3][0] - local[0][0]) + (local[3][1] - local[0][1])* (local[3][1] - local[0][1]));\r
+               final double[][] para=cpara.getArray();\r
+               final double para00=para[0*3+0][0];\r
+               final double para01=para[0*3+1][0];\r
+               final double para02=para[0*3+2][0];\r
+               final double para10=para[1*3+0][0];\r
+               final double para11=para[1*3+1][0];\r
+               final double para12=para[1*3+2][0];\r
+               final double para20=para[2*3+0][0];\r
+               final double para21=para[2*3+1][0];\r
+               final double para22=1.0;\r
+               \r
+               int lx1 = (int) ((local[0].x - local[1].x) * (local[0].x - local[1].x) + (local[0].y - local[1].y)* (local[0].y - local[1].y));\r
+               int lx2 = (int) ((local[2].x - local[3].x) * (local[2].x - local[3].x) + (local[2].y - local[3].y)* (local[2].y - local[3].y));\r
+               int ly1 = (int) ((local[1].x - local[2].x) * (local[1].x - local[2].x) + (local[1].y - local[2].y)* (local[1].y - local[2].y));\r
+               int ly2 = (int) ((local[3].x - local[0].x) * (local[3].x - local[0].x) + (local[3].y - local[0].y)* (local[3].y - local[0].y));\r
                if (lx2 > lx1) {\r
                        lx1 = lx2;\r
                }\r
                if (ly2 > ly1) {\r
                        ly1 = ly2;\r
                }\r
+               \r
                int sample_pixel_x = this._size.w;\r
                int sample_pixel_y = this._size.h;\r
-\r
                while (sample_pixel_x * sample_pixel_x < lx1 / 4) {\r
                        sample_pixel_x *= 2;\r
                }\r
@@ -224,10 +193,13 @@ public class NyARColorPatt_O1 implements INyARColorPatt
                final int ydiv = sample_pixel_y / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
 \r
 \r
-               xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
-               ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
+               int img_x = image.getWidth();\r
+               int img_y = image.getHeight();\r
+\r
+               final double xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
+               final double ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
                int r,g,b;\r
-               int[] rgb_tmp = wk_pickFromRaster_rgb_tmp;\r
+               int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
 \r
                //ピクセルリーダーを取得\r
                INyARRgbPixelReader reader=image.getRgbPixelReader();\r
@@ -241,12 +213,12 @@ public class NyARColorPatt_O1 implements INyARColorPatt
                                        final double yw = 102.5 + 5.0 * (iy*ydiv+j + 0.5) * ydiv2_reciprocal;                                           \r
                                        for(int i=0;i<xdiv;i++){\r
                                                final double xw = 102.5 + 5.0 * (ix*xdiv+i + 0.5) * xdiv2_reciprocal;\r
-                                               final double d = para[2 * 3 + 0] * xw + para[2 * 3 + 1] * yw+ para[2 * 3 + 2];\r
+                                               final double d = para20 * xw + para21 * yw+ para22;\r
                                                if (d == 0) {\r
                                                        throw new NyARException();\r
                                                }\r
-                                               final int xc = (int) ((para[0 * 3 + 0] * xw + para[0 * 3 + 1] * yw + para[0 * 3 + 2]) / d);\r
-                                               final int yc = (int) ((para[1 * 3 + 0] * xw + para[1 * 3 + 1] * yw + para[1 * 3 + 2]) / d);\r
+                                               final int xc = (int) ((para00 * xw + para01 * yw + para02) / d);\r
+                                               final int yc = (int) ((para10 * xw + para11 * yw + para12) / d);\r
        \r
                                                if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
                                                        reader.getPixel(xc, yc, rgb_tmp);\r
index dd4d743..bef1580 100644 (file)
@@ -49,12 +49,16 @@ public class NyARColorPatt_O3 implements INyARColorPatt
        private int[] _patdata;\r
        private NyARBufferReader _buf_reader;\r
        private NyARIntSize _size;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private double _edge_percent;\r
        \r
        public NyARColorPatt_O3(int i_width, int i_height)\r
        {\r
                this._size=new NyARIntSize(i_width,i_height);\r
                this._patdata = new int[i_height*i_width];\r
                this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               this._edge_percent=50.0/100;\r
        }\r
        public int getWidth()\r
        {\r
@@ -72,10 +76,13 @@ public class NyARColorPatt_O3 implements INyARColorPatt
        {\r
                return this._buf_reader;\r
        }\r
-\r
+       public INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
        private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
-\r
        private final NyARMat wk_get_cpara_b = new NyARMat(8, 1);\r
+       private final NyARMat wk_pickFromRaster_cpara = new NyARMat(8, 1);\r
 \r
        /**\r
         * @param world\r
@@ -83,7 +90,7 @@ public class NyARColorPatt_O3 implements INyARColorPatt
         * @param o_para\r
         * @throws NyARException\r
         */\r
-       private boolean get_cpara(final NyARIntPoint[] i_vertex, NyARMat o_para)throws NyARException\r
+       private boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
        {\r
                int[][] world = this.wk_pickFromRaster_world;\r
                NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
@@ -130,7 +137,6 @@ public class NyARColorPatt_O3 implements INyARColorPatt
        { 100, 100 }, { 100 + 10, 100 }, { 100 + 10, 100 + 10 }, { 100, 100 + 10 } };\r
 \r
 \r
-       private final NyARMat wk_pickFromRaster_cpara = new NyARMat(8, 1);\r
 \r
        /**\r
         * imageから、i_markerの位置にあるパターンを切り出して、保持します。 Optimize:STEP[769->750]\r
@@ -142,7 +148,7 @@ public class NyARColorPatt_O3 implements INyARColorPatt
        public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
        {\r
                NyARMat cpara = this.wk_pickFromRaster_cpara;\r
-               NyARIntPoint[] local = i_square.imvertex;\r
+               NyARIntPoint2d[] local = i_square.imvertex;\r
                // xdiv2,ydiv2の計算\r
                int xdiv2, ydiv2;\r
                int l1, l2;\r
@@ -247,19 +253,18 @@ public class NyARColorPatt_O3 implements INyARColorPatt
                int[] rgb_set = this.__updateExtpat_rgbset;\r
 \r
                \r
-               \r
                for(int iy=this._size.h-1;iy>=0;iy--){\r
                        for(int ix=pat_size_w-1;ix>=0;ix--){\r
                                //xw,ywマップを作成\r
                                reciprocal= 1.0 / i_xdiv2;\r
                                for(i=xdiv-1;i>=0;i--){\r
-                                       xw[i]=102.5 + 5.0 * (ix*xdiv+i + 0.5) * reciprocal;\r
+                                       xw[i]=100 + 10.0 * (ix*xdiv+i + 0.5) * reciprocal;\r
                                }\r
                                reciprocal= 1.0 / i_ydiv2;\r
                                for(i=ydiv-1;i>=0;i--){\r
-                                       yw[i]=102.5 + 5.0 * (iy*ydiv+i + 0.5) * reciprocal;\r
+                                       yw[i]=100 + 10.0 * (iy*ydiv+i + 0.5) * reciprocal;\r
                                }\r
-                               //xc,ycマップを作成\r
+                               //1ピクセルを構成するピクセル座標の集合をxc,yc配列に取得\r
                                int number_of_pix=0;\r
                                for(i=ydiv-1;i>=0;i--)\r
                                {\r
@@ -282,7 +287,7 @@ public class NyARColorPatt_O3 implements INyARColorPatt
                                                number_of_pix++;\r
                                        }\r
                                }\r
-                               //ã\83\94ã\82¯ã\82»ã\83«å\8f\96å¾\97ã\81¨ã\83\94ã\82¯ã\82»ã\83«å\80¤ã\81®è¨\88ç®\97\r
+                               //\83\94ã\82¯ã\82»ã\83«å\88\86ã\81®é\85\8då\88\97ã\82\92å\8f\96å¾\97\r
                                reader.getPixelSet(xc,yc,number_of_pix, rgb_set);\r
                                r=g=b=0;\r
                                for(i=number_of_pix*3-1;i>=0;i-=3){\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective.java b/trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_Perspective.java
new file mode 100644 (file)
index 0000000..971aeed
--- /dev/null
@@ -0,0 +1,189 @@
+/* \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.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.NyARPerspectiveParamGenerator_O1;\r
+\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_Perspective implements INyARColorPatt\r
+{\r
+       private int[] _patdata;\r
+       private NyARBufferReader _buf_reader;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private NyARIntSize _size;\r
+       NyARPerspectiveParamGenerator_O1 _perspective_gen;\r
+       private static final int LOCAL_LT=1;\r
+       private NyARIntPoint2d _pickup_lt=new NyARIntPoint2d(); \r
+       /**\r
+        * 例えば、64\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        */\r
+       public NyARColorPatt_Perspective(int i_width, int i_height)\r
+       {\r
+               //入力制限\r
+               assert i_width>2 && i_height>2;\r
+               \r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               setEdgeSize(0,0);\r
+               return;\r
+       }\r
+       /**\r
+        * 例えば、64\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        * @param i_edge_percentage\r
+        * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+        */\r
+       public NyARColorPatt_Perspective(int i_width, int i_height,int i_edge_percentage)\r
+       {\r
+               //入力制限\r
+               assert i_width>2 && i_height>2;\r
+               \r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               setEdgeSizeByPercent(i_edge_percentage,i_edge_percentage);\r
+               return;\r
+       }       \r
+       /**\r
+        * 矩形領域のエッジサイズを指定します。\r
+        * エッジの計算方法は以下の通りです。\r
+        * 1.マーカ全体を(i_x_edge*2+width)x(i_y_edge*2+height)の解像度でパラメタを計算します。\r
+        * 2.ピクセルの取得開始位置を(i_x_edge/2,i_y_edge/2)へ移動します。\r
+        * 3.開始位置から、width x height個のピクセルを取得します。\r
+        * \r
+        * ARToolKit標準マーカの場合は、width/2,height/2を指定してください。\r
+        * @param i_x_edge\r
+        * @param i_y_edge\r
+        */\r
+       public void setEdgeSize(int i_x_edge,int i_y_edge)\r
+       {\r
+               assert(i_x_edge>=0);\r
+               assert(i_y_edge>=0);\r
+               //Perspectiveパラメタ計算器を作成\r
+               this._perspective_gen=new NyARPerspectiveParamGenerator_O1(LOCAL_LT,LOCAL_LT,i_x_edge*2+this._size.w,i_y_edge*2+this._size.h);\r
+               //ピックアップ開始位置を計算\r
+               this._pickup_lt.x=i_x_edge+LOCAL_LT;\r
+               this._pickup_lt.y=i_y_edge+LOCAL_LT;\r
+               return;\r
+       }\r
+       public void setEdgeSizeByPercent(int i_x_percent,int i_y_percent)\r
+       {\r
+               assert(i_x_percent>=0);\r
+               assert(i_y_percent>=0);\r
+               setEdgeSize(this._size.w*i_x_percent/50,this._size.h*i_y_percent/50);\r
+               return;\r
+       }\r
+\r
+       \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public final INyARBufferReader getBufferReader()\r
+       {\r
+               return this._buf_reader;\r
+       }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+       /**\r
+        * \r
+        * @param image\r
+        * @param i_marker\r
+        * @return 切り出しに失敗した\r
+        * @throws Exception\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+       {\r
+               //遠近法のパラメータを計算\r
+               double[] cpara = new double[8];\r
+               if (!this._perspective_gen.getParam(i_square.imvertex, cpara)) {\r
+                       return false;\r
+               }\r
+               \r
+               int img_x = image.getWidth();\r
+               int img_y = image.getHeight();\r
+\r
+               int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
+\r
+               //ピクセルリーダーを取得\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+\r
+               for(int iy=0;iy<this._size.h;iy++){\r
+                       for(int ix=0;ix<this._size.w;ix++){\r
+                               //1ピクセルを作成\r
+                               int cx=this._pickup_lt.x+ix;\r
+                               int cy=this._pickup_lt.y+iy;\r
+                               final double d=cpara[6]*cx+cpara[7]*cy+1.0;\r
+                               final int x=(int)((cpara[0]*cx+cpara[1]*cy+cpara[2])/d);\r
+                               final int y=(int)((cpara[3]*cx+cpara[4]*cy+cpara[5])/d);\r
+                               if (x >= 0 && x < img_x && y >= 0 && y < img_y) {\r
+                                       reader.getPixel(x, y, rgb_tmp);\r
+                                       this._patdata[iy*this._size.w+ix]=(((rgb_tmp[0])&0xff)<<16)|(((rgb_tmp[1])&0xff)<<8)|(((rgb_tmp[2])&0xff));\r
+                               }\r
+                       }\r
+                       //ピクセル問い合わせ\r
+                       //ピクセルセット\r
+               }\r
+               return true;\r
+       }       \r
+}
\ No newline at end of file
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_PseudoAffine.java b/trunk/src/jp/nyatla/nyartoolkit/core/pickup/NyARColorPatt_PseudoAffine.java
new file mode 100644 (file)
index 0000000..6cae5bd
--- /dev/null
@@ -0,0 +1,168 @@
+/* \r
+ * PROJECT: NyARToolkit\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.pickup;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.utils.NyARDoubleMatrixProcessor;\r
+\r
+\r
+/**\r
+ * 疑似アフィン変換を使用して、ラスタ上の四角形から任意解像度\r
+ * の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_PseudoAffine implements INyARColorPatt\r
+{\r
+       private int[] _patdata;\r
+       private NyARBufferReader _buf_reader;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private NyARIntSize _size;\r
+               \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       \r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       \r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       \r
+       public final INyARBufferReader getBufferReader()\r
+       {\r
+               return this._buf_reader;\r
+       }\r
+       \r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+       /**\r
+        * @param i_width\r
+        * @param i_height\r
+        */\r
+       public NyARColorPatt_PseudoAffine(int i_width, int i_height)\r
+       {               \r
+               this._size=new NyARIntSize(i_width,i_height);\r
+               this._patdata = new int[i_height*i_width];\r
+               this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               //疑似アフィン変換のパラメタマトリクスを計算します。\r
+               //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。\r
+               final NyARDoubleMatrix44 mat=this._invmat;\r
+               mat.m00=0;\r
+               mat.m01=0;\r
+               mat.m02=0;\r
+               mat.m03=1.0;\r
+               mat.m10=0;\r
+               mat.m11=i_width-1;\r
+               mat.m12=0;\r
+               mat.m13=1.0;\r
+               mat.m20=(i_width-1)*(i_height-1);\r
+               mat.m21=i_width-1;\r
+               mat.m22=i_height-1;\r
+               mat.m23=1.0;\r
+               mat.m30=0;\r
+               mat.m31=0;\r
+               mat.m32=i_height-1;\r
+               mat.m33=1.0;\r
+               NyARDoubleMatrixProcessor.inverse(mat,mat);\r
+               return;\r
+       }       \r
+\r
+       /**\r
+        * 変換行列と頂点座標から、パラメータを計算\r
+        * o_paramの[0..3]にはXのパラメタ、[4..7]にはYのパラメタを格納する。\r
+        * @param i_vertex\r
+        * @param pa\r
+        * @param pb\r
+        */\r
+       private void calcPara(NyARIntPoint2d[] i_vertex,double[] o_cparam)\r
+       {\r
+               final NyARDoubleMatrix44 invmat=this._invmat;\r
+               double v1,v2,v4;\r
+               //変換行列とベクトルの積から、変換パラメタを計算する。\r
+               v1=i_vertex[0].x;\r
+               v2=i_vertex[1].x;\r
+               v4=i_vertex[3].x;\r
+               \r
+               o_cparam[0]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].x+invmat.m03*v4;\r
+               o_cparam[1]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+               o_cparam[2]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+               o_cparam[3]=v1;//m30は1.0で、m31,m32,m33は0\r
+               \r
+               v1=i_vertex[0].y;\r
+               v2=i_vertex[1].y;\r
+               v4=i_vertex[3].y;\r
+\r
+               o_cparam[4]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].y+invmat.m03*v4;\r
+               o_cparam[5]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+               o_cparam[6]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+               o_cparam[7]=v1;//m30は1.0で、m31,m32,m33は0\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 疑似アフィン変換の変換パラメタ\r
+        */\r
+       private double[] _convparam=new double[8];\r
+       \r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+       {\r
+               final double[] conv_param=this._convparam;\r
+           int rx2,ry2;\r
+               rx2=this._size.w;\r
+               ry2=this._size.h;\r
+               int[] rgb_tmp=new int[3];\r
+\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               // 変形先領域の頂点を取得\r
+\r
+               //変換行列から現在の座標系への変換パラメタを作成\r
+               calcPara(i_square.imvertex,conv_param);// 変換パラメータを求める\r
+               for(int y=0;y<ry2;y++){\r
+                       for(int x=0;x<rx2;x++){\r
+                               final int ttx=(int)((conv_param[0]*x*y+conv_param[1]*x+conv_param[2]*y+conv_param[3])+0.5);\r
+                               final int tty=(int)((conv_param[4]*x*y+conv_param[5]*x+conv_param[6]*y+conv_param[7])+0.5);\r
+                               reader.getPixel((int)ttx,(int)tty,rgb_tmp);\r
+                               this._patdata[x+y*rx2]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2];                             \r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+}
\ No newline at end of file
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_GLAY_8.java b/trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_GLAY_8.java
new file mode 100644 (file)
index 0000000..ca4d80c
--- /dev/null
@@ -0,0 +1,63 @@
+/* \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.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbPixelReader_INT1D_GLAY_8 implements INyARRgbPixelReader\r
+{\r
+       protected int[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_INT1D_GLAY_8(int[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               o_rgb[0] = o_rgb[1]=o_rgb[2]=this._ref_buf[i_x + i_y * this._size.w];\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               final int width = this._size.w;\r
+               final int[] ref_buf = this._ref_buf;\r
+               for (int i = i_num - 1; i >= 0; i--){\r
+                       o_rgb[i * 3 + 0] = o_rgb[i * 3 + 1]=o_rgb[i * 3 + 2]=ref_buf[i_x[i] + i_y[i] * width];\r
+               }\r
+               return;\r
+       }\r
+}\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_X8R8G8B8_32.java b/trunk/src/jp/nyatla/nyartoolkit/core/rasterreader/NyARRgbPixelReader_INT1D_X8R8G8B8_32.java
new file mode 100644 (file)
index 0000000..e3e5ebb
--- /dev/null
@@ -0,0 +1,69 @@
+/* \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.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbPixelReader_INT1D_X8R8G8B8_32 implements INyARRgbPixelReader\r
+{\r
+       protected int[] _ref_buf;\r
+\r
+       private NyARIntSize _size;\r
+\r
+       public NyARRgbPixelReader_INT1D_X8R8G8B8_32(int[] i_buf, NyARIntSize i_size)\r
+       {\r
+               this._ref_buf = i_buf;\r
+               this._size = i_size;\r
+       }\r
+\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+       {\r
+               final int rgb= this._ref_buf[i_x + i_y * this._size.w];\r
+               o_rgb[0] = (rgb>>16)&0xff;// R\r
+               o_rgb[1] = (rgb>>8)&0xff;// G\r
+               o_rgb[2] = rgb&0xff;// B\r
+               return;\r
+       }\r
+\r
+       public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+       {\r
+               final int width = this._size.w;\r
+               final int[] ref_buf = this._ref_buf;\r
+               for (int i = i_num - 1; i >= 0; i--){\r
+                       int rgb=ref_buf[i_x[i] + i_y[i] * width];\r
+                       o_rgb[i * 3 + 0] = (rgb>>16)&0xff;// R\r
+                       o_rgb[i * 3 + 1] = (rgb>>8)&0xff;// G\r
+                       o_rgb[i * 3 + 2] = rgb&0xff;// B\r
+               }\r
+               return;\r
+       }\r
+}\r
index 888db14..357c106 100644 (file)
@@ -237,7 +237,7 @@ public class NyARTransMat implements INyARTransMat
                o_result.m22 = i_rot.m22;\r
                o_result.m23 = i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z + i_trans.z;\r
 \r
-               o_result.angle.copyFrom(i_rot.refAngle());\r
+               o_result.angle.setValue(i_rot.refAngle());\r
                o_result.has_value = true;\r
                return;\r
        }       \r
index d3af858..bf5ca7b 100644 (file)
@@ -177,7 +177,7 @@ public class NyARRotTransOptimize_Base implements INyARRotTransOptimize
                double err, minerr = 0;\r
                int i,i2;\r
                int best_idx=0;\r
-               angle.copyFrom(io_rot.refAngle());// arGetAngle( rot, &a, &b, &c );\r
+               angle.setValue(io_rot.refAngle());// arGetAngle( rot, &a, &b, &c );\r
                factor = 10.0 * Math.PI / 180.0;\r
                for (int j = 0; j < 10; j++){\r
                        minerr = 1000000000.0;\r
index 7cc4b44..05ff1e2 100644 (file)
@@ -31,6 +31,7 @@
  */\r
 package jp.nyatla.nyartoolkit.core.types;\r
 \r
+\r
 public class NyARDoublePoint2d\r
 {\r
        public double x;\r
@@ -49,14 +50,60 @@ public class NyARDoublePoint2d
                }\r
                return ret;\r
        }\r
+       public static NyARDoublePoint2d[][] create2dArray(int i_length_x,int i_length_y)\r
+       {\r
+               NyARDoublePoint2d[][] ret=new NyARDoublePoint2d[i_length_y][i_length_x];\r
+               for(int i=0;i<i_length_y;i++)\r
+               {\r
+                       for(int i2=0;i2<i_length_x;i2++)\r
+                       {\r
+                               ret[i][i2]=new NyARDoublePoint2d();\r
+                       }\r
+               }\r
+               return ret;\r
+       }\r
        public NyARDoublePoint2d()\r
        {\r
                this.x=0;\r
                this.y=0;\r
+               return;\r
        }       \r
        public NyARDoublePoint2d(double i_x,double i_y)\r
        {\r
                this.x=i_x;\r
                this.y=i_y;\r
+               return;\r
+       }\r
+       public NyARDoublePoint2d(NyARDoublePoint2d i_src)\r
+       {\r
+               this.x=i_src.x;\r
+               this.y=i_src.y;\r
+               return;\r
+       }\r
+       public NyARDoublePoint2d(NyARIntPoint2d i_src)\r
+       {\r
+               this.x=(double)i_src.x;\r
+               this.y=(double)i_src.y;\r
+               return;\r
+       }\r
+       public void setValue(NyARDoublePoint2d i_src)\r
+       {\r
+               this.x=i_src.x;\r
+               this.y=i_src.y;\r
+               return;\r
+       }\r
+       public void setValue(NyARIntPoint2d i_src)\r
+       {\r
+               this.x=(double)i_src.x;\r
+               this.y=(double)i_src.y;\r
+               return;\r
+       }\r
+       /**\r
+        * 格納値をベクトルとして、距離を返します。\r
+        * @return\r
+        */\r
+       public double dist()\r
+       {\r
+               return Math.sqrt(this.x*this.x+this.y+this.y);\r
        }\r
 }\r
index 2b02281..b9740d1 100644 (file)
@@ -50,7 +50,7 @@ public class NyARDoublePoint3d
                }\r
                return ret;\r
        }\r
-       public void copyFrom(final NyARDoublePoint3d i_in)\r
+       public void setValue(final NyARDoublePoint3d i_in)\r
        {\r
                this.x=i_in.x;\r
                this.y=i_in.y;\r
index 7ac8d4a..999eb50 100644 (file)
  * \r
  */\r
 package jp.nyatla.nyartoolkit.core.types;\r
-\r
-public class NyARIntPoint\r
+/**\r
+ * @deprecated このクラスは名称変更のため、削除されます。\r
+ * @see NyARIntPoint2d\r
+ */\r
+public class NyARIntPoint extends NyARIntPoint2d\r
 {\r
-       public int x;\r
-\r
-       public int y;\r
        /**\r
         * 配列ファクトリ\r
         * @param i_number\r
@@ -50,13 +50,4 @@ public class NyARIntPoint
                }\r
                return ret;\r
        }\r
-       public static void copyArray(final NyARIntPoint[] i_from,NyARIntPoint[] i_to)\r
-       {\r
-               for(int i=i_from.length-1;i>=0;i--)\r
-               {\r
-                       i_to[i].x=i_from[i].x;\r
-                       i_to[i].y=i_from[i].y;\r
-               }\r
-               return;\r
-       }\r
 }\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint2d.java b/trunk/src/jp/nyatla/nyartoolkit/core/types/NyARIntPoint2d.java
new file mode 100644 (file)
index 0000000..d5a497a
--- /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;\r
+\r
+public class NyARIntPoint2d\r
+{\r
+       public int x;\r
+\r
+       public int y;\r
+       /**\r
+        * 配列ファクトリ\r
+        * @param i_number\r
+        * @return\r
+        */\r
+       public static NyARIntPoint2d[] createArray(int i_number)\r
+       {\r
+               NyARIntPoint2d[] ret=new NyARIntPoint2d[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARIntPoint2d();\r
+               }\r
+               return ret;\r
+       }\r
+       public static void copyArray(final NyARIntPoint2d[] i_from,NyARIntPoint2d[] i_to)\r
+       {\r
+               for(int i=i_from.length-1;i>=0;i--)\r
+               {\r
+                       i_to[i].x=i_from[i].x;\r
+                       i_to[i].y=i_from[i].y;\r
+               }\r
+               return;\r
+       }\r
+}\r
index 5595ab2..9c0727b 100644 (file)
@@ -31,6 +31,7 @@
  */\r
 package jp.nyatla.nyartoolkit.core.types.matrix;\r
 \r
+import jp.nyatla.nyartoolkit.*;\r
 \r
 public class NyARDoubleMatrix33 implements INyARDoubleMatrix\r
 {\r
index f87ec7c..a719b2e 100644 (file)
@@ -76,5 +76,5 @@ public class NyARDoubleMatrix34 implements INyARDoubleMatrix
                o_value[10]=this.m22;\r
                o_value[11]=this.m23;\r
                return;\r
-       }       \r
+       }\r
 }\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix44.java b/trunk/src/jp/nyatla/nyartoolkit/core/types/matrix/NyARDoubleMatrix44.java
new file mode 100644 (file)
index 0000000..1ef0e15
--- /dev/null
@@ -0,0 +1,77 @@
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+\r
+public class NyARDoubleMatrix44 implements INyARDoubleMatrix\r
+{\r
+       public double m00;\r
+       public double m01;\r
+       public double m02;\r
+       public double m03;\r
+       public double m10;\r
+       public double m11;\r
+       public double m12;\r
+       public double m13;\r
+       public double m20;\r
+       public double m21;\r
+       public double m22;\r
+       public double m23;\r
+       public double m30;\r
+       public double m31;\r
+       public double m32;\r
+       public double m33;\r
+       public static NyARDoubleMatrix44[] createArray(int i_number)\r
+       {\r
+               NyARDoubleMatrix44[] ret=new NyARDoubleMatrix44[i_number];\r
+               for(int i=0;i<i_number;i++)\r
+               {\r
+                       ret[i]=new NyARDoubleMatrix44();\r
+               }\r
+               return ret;\r
+       }\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.m02=i_value[ 2];\r
+               this.m03=i_value[ 3];\r
+               this.m10=i_value[ 4];\r
+               this.m11=i_value[ 5];\r
+               this.m12=i_value[ 6];\r
+               this.m13=i_value[ 7];\r
+               this.m20=i_value[ 8];\r
+               this.m21=i_value[ 9];\r
+               this.m22=i_value[10];\r
+               this.m23=i_value[11];\r
+               this.m30=i_value[12];\r
+               this.m31=i_value[13];\r
+               this.m32=i_value[14];\r
+               this.m33=i_value[15];\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[ 2]=this.m02;\r
+               o_value[ 3]=this.m03;\r
+               o_value[ 4]=this.m10;\r
+               o_value[ 5]=this.m11;\r
+               o_value[ 6]=this.m12;\r
+               o_value[ 7]=this.m13;\r
+               o_value[ 8]=this.m20;\r
+               o_value[ 9]=this.m21;\r
+               o_value[10]=this.m22;\r
+               o_value[11]=this.m23;\r
+               o_value[12]=this.m30;\r
+               o_value[13]=this.m31;\r
+               o_value[14]=this.m32;\r
+               o_value[15]=this.m33;\r
+               return;\r
+       }\r
+}\r
index 40c9dec..f59a04c 100644 (file)
@@ -39,14 +39,14 @@ public class NyARIntPointStack extends NyObjectStack
 {\r
        public NyARIntPointStack(int i_length)\r
        {\r
-               super(new NyARIntPoint[i_length]);\r
+               super(new NyARIntPoint2d[i_length]);\r
 \r
        }\r
 \r
        protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)\r
        {\r
                for (int i = i_start; i < i_end; i++) {\r
-                       i_buffer[i] = new NyARIntPoint();\r
+                       i_buffer[i] = new NyARIntPoint2d();\r
                }\r
        }\r
 \r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARDoubleMatrixProcessor.java b/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARDoubleMatrixProcessor.java
new file mode 100644 (file)
index 0000000..7f88329
--- /dev/null
@@ -0,0 +1,161 @@
+/* \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-2009 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.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;\r
+\r
+public class NyARDoubleMatrixProcessor\r
+{\r
+       /**\r
+        * i_srcの逆行列を計算して、thisへ格納します。\r
+        * @param i_src\r
+        * @return\r
+        */\r
+       public static boolean inverse(NyARDoubleMatrix22 i_src,NyARDoubleMatrix22 o_dest)\r
+       {\r
+               final double a11,a12,a21,a22;\r
+               a11=i_src.m00;\r
+               a12=i_src.m01;\r
+               a21=i_src.m10;\r
+               a22=i_src.m11;\r
+               double det=a11*a22-a12*a21;\r
+               if(det==0){\r
+                       return false;\r
+               }\r
+               det=1/det;\r
+               o_dest.m00=a22*det;\r
+               o_dest.m01=-a12*det;\r
+               o_dest.m10=a21*det;\r
+               o_dest.m11=-a11*det;\r
+               return true;\r
+       }       \r
+       public static boolean inverse(NyARDoubleMatrix33 i_src,NyARDoubleMatrix33 o_dest) throws NyARException\r
+       {\r
+               /*i_srcの逆行列をthisへ格納するコードを書くこと。*/\r
+               NyARException.notImplement();\r
+               return false;\r
+       }\r
+       /**\r
+        * i_srcの逆行列を計算して、結果をo_destへセットします。\r
+        * @param i_src\r
+        * @return\r
+        */\r
+       public static boolean inverse(NyARDoubleMatrix44 i_src,NyARDoubleMatrix44 o_dest)\r
+       {\r
+               final double a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44;\r
+               final double b11,b12,b13,b14,b21,b22,b23,b24,b31,b32,b33,b34,b41,b42,b43,b44;   \r
+               double t1,t2,t3,t4,t5,t6;\r
+               a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;a14=i_src.m03;\r
+               a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;a24=i_src.m13;\r
+               a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;a34=i_src.m23;\r
+               a41=i_src.m30;a42=i_src.m31;a43=i_src.m32;a44=i_src.m33;\r
+               \r
+               t1=a33*a44-a34*a43;\r
+               t2=a34*a42-a32*a44;\r
+               t3=a32*a43-a33*a42;\r
+               t4=a34*a41-a31*a44;\r
+               t5=a31*a43-a33*a41;\r
+               t6=a31*a42-a32*a41;\r
+               \r
+               b11=a22*t1+a23*t2+a24*t3;\r
+               b21=-(a23*t4+a24*t5+a21*t1);\r
+               b31=a24*t6-a21*t2+a22*t4;\r
+               b41=-(a21*t3-a22*t5+a23*t6);\r
+               \r
+               t1=a43*a14-a44*a13;\r
+               t2=a44*a12-a42*a14;\r
+               t3=a42*a13-a43*a12;\r
+               t4=a44*a11-a41*a14;\r
+               t5=a41*a13-a43*a11;\r
+               t6=a41*a12-a42*a11;\r
+\r
+               b12=-(a32*t1+a33*t2+a34*t3);\r
+               b22=a33*t4+a34*t5+a31*t1;\r
+               b32=-(a34*t6-a31*t2+a32*t4);\r
+               b42=a31*t3-a32*t5+a33*t6;\r
+               \r
+               t1=a13*a24-a14*a23;\r
+               t2=a14*a22-a12*a24;\r
+               t3=a12*a23-a13*a22;\r
+               t4=a14*a21-a11*a24;\r
+               t5=a11*a23-a13*a21;\r
+               t6=a11*a22-a12*a21;\r
+\r
+               b13=a42*t1+a43*t2+a44*t3;\r
+               b23=-(a43*t4+a44*t5+a41*t1);\r
+               b33=a44*t6-a41*t2+a42*t4;\r
+               b43=-(a41*t3-a42*t5+a43*t6);\r
+\r
+               t1=a23*a34-a24*a33;\r
+               t2=a24*a32-a22*a34;\r
+               t3=a22*a33-a23*a32;\r
+               t4=a24*a31-a21*a34;             \r
+               t5=a21*a33-a23*a31;\r
+               t6=a21*a32-a22*a31;\r
+\r
+               b14=-(a12*t1+a13*t2+a14*t3);\r
+               b24=a13*t4+a14*t5+a11*t1;\r
+               b34=-(a14*t6-a11*t2+a12*t4);\r
+               b44=a11*t3-a12*t5+a13*t6;\r
+               \r
+               double det_1=(a11*b11+a21*b12+a31*b13+a41*b14);\r
+               if(det_1==0){\r
+                       return false;\r
+               }\r
+               det_1=1/det_1;\r
+\r
+               o_dest.m00=b11*det_1;\r
+               o_dest.m01=b12*det_1;\r
+               o_dest.m02=b13*det_1;\r
+               o_dest.m03=b14*det_1;\r
+               \r
+               o_dest.m10=b21*det_1;\r
+               o_dest.m11=b22*det_1;\r
+               o_dest.m12=b23*det_1;\r
+               o_dest.m13=b24*det_1;\r
+               \r
+               o_dest.m20=b31*det_1;\r
+               o_dest.m21=b32*det_1;\r
+               o_dest.m22=b33*det_1;\r
+               o_dest.m23=b34*det_1;\r
+               \r
+               o_dest.m30=b41*det_1;\r
+               o_dest.m31=b42*det_1;\r
+               o_dest.m32=b43*det_1;\r
+               o_dest.m33=b44*det_1;\r
+               \r
+               return true;\r
+       }\r
+}\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator.java b/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator.java
new file mode 100644 (file)
index 0000000..cf8fc14
--- /dev/null
@@ -0,0 +1,103 @@
+/* \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-2009 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.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * 遠近法を用いたPerspectiveパラメータを計算するクラスです。\r
+ *\r
+ */\r
+public class NyARPerspectiveParamGenerator\r
+{\r
+       protected int _local_x;\r
+       protected int _local_y;\r
+       protected int _width;\r
+       protected int _height;\r
+       public NyARPerspectiveParamGenerator(int i_local_x,int i_local_y,int i_width, int i_height)\r
+       {\r
+               this._height=i_height;\r
+               this._width=i_width;\r
+               this._local_x=i_local_x;\r
+               this._local_y=i_local_y;\r
+               return;\r
+       }\r
+       public boolean getParam(final NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+       {\r
+               double[][] la1,la2;\r
+               double[] ra1,ra2;\r
+               double ltx=this._local_x;\r
+               double lty=this._local_y;\r
+               double rbx=ltx+this._width;\r
+               double rby=lty+this._height;\r
+               la1=new double[4][5];\r
+               la2=new double[4][5];\r
+               ra1=new double[4];\r
+               ra2=new double[4];\r
+               //A,B,C,(GH)の方程式\r
+               la1[0][0]=ltx;  la1[0][1]=lty;  la1[0][2]=1;    la1[0][3]=-ltx*i_vertex[0].x;   la1[0][4]=-lty*i_vertex[0].x;\r
+               la1[1][0]=rbx;  la1[1][1]=lty;  la1[1][2]=1;    la1[1][3]=-rbx*i_vertex[1].x;   la1[1][4]=-lty*i_vertex[1].x;\r
+               la1[2][0]=rbx;  la1[2][1]=rby;  la1[2][2]=1;    la1[2][3]=-rbx*i_vertex[2].x;   la1[2][4]=-rby*i_vertex[2].x;\r
+               la1[3][0]=ltx;  la1[3][1]=rby;  la1[3][2]=1;    la1[3][3]=-ltx*i_vertex[3].x;   la1[3][4]=-rby*i_vertex[3].x;\r
+               ra1[0]=i_vertex[0].x;ra1[1]=i_vertex[1].x;ra1[2]=i_vertex[2].x;ra1[3]=i_vertex[3].x;\r
+               NyARSystemOfLinearEquationsProcessor.doGaussianElimination(la1,ra1,5,4);\r
+\r
+               //D,E,F,(GH)の方程式\r
+               la2[0][0]=ltx;  la2[0][1]=lty;  la2[0][2]=1;    la2[0][3]=-ltx*i_vertex[0].y;   la2[0][4]=-lty*i_vertex[0].y;\r
+               la2[1][0]=rbx;  la2[1][1]=lty;  la2[1][2]=1;    la2[1][3]=-rbx*i_vertex[1].y;   la2[1][4]=-lty*i_vertex[1].y;\r
+               la2[2][0]=rbx;  la2[2][1]=rby;  la2[2][2]=1;    la2[2][3]=-rbx*i_vertex[2].y;   la2[2][4]=-rby*i_vertex[2].y;\r
+               la2[3][0]=ltx;  la2[3][1]=rby;  la2[3][2]=1;    la2[3][3]=-ltx*i_vertex[3].y;   la2[3][4]=-rby*i_vertex[3].y;\r
+               ra2[0]=i_vertex[0].y;ra2[1]=i_vertex[1].y;ra2[2]=i_vertex[2].y;ra2[3]=i_vertex[3].y;\r
+               NyARSystemOfLinearEquationsProcessor.doGaussianElimination(la2,ra2,5,4);\r
+               //GHを計算\r
+               double A,B,C,D,E,F,G,H;\r
+               H=(ra2[3]-ra1[3])/(la2[3][4]-la1[3][4]);\r
+               G=ra2[3]-la2[3][4]*H;\r
+               //残りを計算\r
+               F=ra2[2]-H*la2[2][4]-G*la2[2][3];\r
+               E=ra2[1]-H*la2[1][4]-G*la2[1][3]-F*la2[1][2];\r
+               D=ra2[0]-H*la2[0][4]-G*la2[0][3]-F*la2[0][2]-E*la2[0][1];\r
+               C=ra1[2]-H*la1[2][4]-G*la1[2][3];\r
+               B=ra1[1]-H*la1[1][4]-G*la1[1][3]-C*la1[1][2];\r
+               A=ra1[0]-H*la1[0][4]-G*la1[0][3]-C*la1[0][2]-B*la1[0][1];\r
+               o_param[0]=A;\r
+               o_param[1]=B;\r
+               o_param[2]=C;\r
+               o_param[3]=D;\r
+               o_param[4]=E;\r
+               o_param[5]=F;\r
+               o_param[6]=G;\r
+               o_param[7]=H;\r
+               return true;\r
+       }\r
+}\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_O1.java b/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARPerspectiveParamGenerator_O1.java
new file mode 100644 (file)
index 0000000..5c43b8b
--- /dev/null
@@ -0,0 +1,102 @@
+/* \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-2009 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.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * NyARPerspectiveParamGeneratorを最適化したクラスです。\r
+ */\r
+public class NyARPerspectiveParamGenerator_O1 extends NyARPerspectiveParamGenerator\r
+{\r
+       public NyARPerspectiveParamGenerator_O1(int i_local_x,int i_local_y,int i_width, int i_height)\r
+       {\r
+               super(i_local_x,i_local_y,i_width,i_height);\r
+               this._height=i_height;\r
+               this._width=i_width;\r
+               this._local_x=i_local_x;\r
+               this._local_y=i_local_y;\r
+               return;\r
+       }\r
+       final public boolean getParam(final NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+       {\r
+               double G,H;\r
+               double w1,w2,w3,w4;\r
+               final double x0=i_vertex[0].x;\r
+               final double x1=i_vertex[1].x;\r
+               final double x2=i_vertex[2].x;\r
+               final double x3=i_vertex[3].x;\r
+               final double y0=i_vertex[0].y;\r
+               final double y1=i_vertex[1].y;\r
+               final double y2=i_vertex[2].y;\r
+               final double y3=i_vertex[3].y;\r
+               final double ltx=this._local_x;\r
+               final double lty=this._local_y;\r
+               final double rbx=ltx+this._width;\r
+               final double rby=lty+this._height;\r
+\r
+               \r
+               w1=-y3+y0;\r
+               w2= y2-y1;\r
+               final double la2_33=ltx*w1+rbx*w2;//これが0になるのはまずい。\r
+               final double la2_34=(rby*(-y3+y2)+lty*(y0-y1))/la2_33;\r
+               final double ra2_3 =(-w1-w2)/la2_33;\r
+               \r
+               w1=-x3+x0;\r
+               w2=x2-x1;\r
+               final double la1_33=ltx*w1+rbx*w2;//これが0になるのはまずい。\r
+               \r
+               //GHを計算\r
+               H=(ra2_3-((-w1-w2)/la1_33))/(la2_34-((rby*(-x3+x2)+lty*(x0-x1))/la1_33));\r
+               G=ra2_3-la2_34*H;\r
+               o_param[7]=H;\r
+               o_param[6]=G;\r
+\r
+               //残りを計算\r
+               w3=rby-lty;\r
+               w4=rbx-ltx;\r
+               w1=(y2-y1-H*(-rby*y2+lty*y1)-G*(-rbx*y2+rbx*y1))/w3;\r
+               w2=(y1-y0-H*(-lty*y1+lty*y0)-G*(-rbx*y1+ltx*y0))/w4;\r
+               o_param[5]=y0*(1+H*lty+G*ltx)-w1*lty-w2*ltx;\r
+               o_param[4]=w1;\r
+               o_param[3]=w2;\r
+               \r
+               \r
+               w1=(x2-x1-H*(-rby*x2+lty*x1)-G*(-rbx*x2+rbx*x1))/w3;\r
+               w2=(x1-x0-H*(-lty*x1+lty*x0)-G*(-rbx*x1+ltx*x0))/w4;\r
+               o_param[2]=x0*(1+H*lty+G*ltx)-w1*lty-w2*ltx;\r
+               o_param[1]=w1;\r
+               o_param[0]=w2;\r
+               return true;\r
+       }\r
+}\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARSystemOfLinearEquationsProcessor.java b/trunk/src/jp/nyatla/nyartoolkit/core/utils/NyARSystemOfLinearEquationsProcessor.java
new file mode 100644 (file)
index 0000000..4d05447
--- /dev/null
@@ -0,0 +1,150 @@
+/* \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-2009 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.utils;\r
+\r
+/**\r
+ * 連立方程式を解くためのプロセッサクラスです。\r
+ *\r
+ */\r
+public class NyARSystemOfLinearEquationsProcessor\r
+{\r
+       /**\r
+        * i_reftとi_rightの整合性を確認します。\r
+        * @param i_left\r
+        * @param i_right\r
+        * @return\r
+        */\r
+       private static boolean isValid2dArray(double[][] i_left,double[] i_right)\r
+       {               \r
+               final int sm=i_left.length;\r
+               final int sn=i_left[0].length;\r
+               if(i_left.length!=sm){\r
+                       return false;\r
+               }\r
+               if(i_right.length!=sm){\r
+                       return false;\r
+               }\r
+               for(int i=1;i<sm;i++){\r
+                       if(i_left[i].length!=sn){\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * [i_left_src]=[i_right_src]の式にガウスの消去法を実行して、[x][x]の要素が1になるように基本変形します。\r
+        * i_mとi_nが等しくない時は、最終行までの[x][x]要素までを1になるように変形します。\r
+        * @param i_left\r
+        * 連立方程式の左辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+        * @param i_right\r
+        * 連立方程式の右辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+        * @param i_n\r
+        * 連立方程式の係数の数を指定します。\r
+        * @param i_m\r
+        * 連立方程式の数を指定します。\r
+        * @return\r
+        * 最終行まで基本変形ができてばtrueを返します。\r
+        */\r
+       public static boolean doGaussianElimination(double[][] i_left,double[] i_right,int i_n,int i_m)\r
+       {\r
+               //整合性を確認する.\r
+               assert isValid2dArray(i_left,i_right);\r
+               \r
+\r
+               //1行目以降\r
+               for(int solve_row=0;solve_row<i_m;solve_row++)\r
+               {\r
+                       {//ピボット操作\r
+                               int pivod=solve_row;\r
+                               double pivod_value=Math.abs(i_left[pivod][pivod]);\r
+                               for(int i=solve_row+1;i<i_m;i++){\r
+                                       final double pivod_2=Math.abs(i_left[i][pivod]);\r
+                                       if(pivod_value<Math.abs(pivod_2)){\r
+                                               pivod=i;\r
+                                               pivod_value=pivod_2;\r
+                                       }\r
+                               }\r
+                               if(solve_row!=pivod){\r
+                                       //行の入れ替え(Cの時はポインタテーブル使って!)\r
+                                       final double[] t=i_left[solve_row];\r
+                                       i_left[solve_row]=i_left[pivod];\r
+                                       i_left[pivod]=t;\r
+                                       final double t2=i_right[solve_row];\r
+                                       i_right[solve_row]=i_right[pivod];\r
+                                       i_right[pivod]=t2;\r
+                               }\r
+                       }\r
+                       final double[] dest_l_n=i_left[solve_row];\r
+                       final double dest_l_nn=i_left[solve_row][solve_row];\r
+                       if(dest_l_nn==0.0){\r
+                               //選択後の対角要素が0になってしまったら失敗する。\r
+                               return false;\r
+                       }                       \r
+\r
+                       //消去計算(0 - solve_row-1項までの消去)\r
+                       for(int i=0;i<solve_row;i++){\r
+                               double s=dest_l_n[i];\r
+                               for(int i2=0;i2<i_n;i2++)\r
+                               {\r
+                                       final double p=i_left[i][i2]*s;\r
+                                       dest_l_n[i2]=dest_l_n[i2]-p;\r
+                               }\r
+                               final double p=i_right[i]*s;\r
+                               i_right[solve_row]=i_right[solve_row]-p;\r
+                               \r
+                       }\r
+                       //消去法の実行(割り算)\r
+                       final double d=dest_l_n[solve_row];\r
+                       for(int i2=0;i2<solve_row;i2++){\r
+                               dest_l_n[i2]=0;\r
+                       }\r
+                       if(d!=1.0){\r
+                               dest_l_n[solve_row]=1.0;\r
+                               for(int i=solve_row+1;i<i_n;i++){\r
+                                       dest_l_n[i]/=d;\r
+                               }\r
+                               i_right[solve_row]/=d;\r
+                       }\r
+               }\r
+               return true;    \r
+       }\r
+       /**\r
+        * i_leftとi_rightの連立方程式を解いて、i_left,i_right内容を更新します。\r
+        * i_right[n]の内容が、i_left[x][n]番目の係数の解になります。\r
+        * @return\r
+        * 方程式が解ければtrueを返します。\r
+        */\r
+       public static boolean solve(double[][] i_left,double[] i_right,int i_number_of_system)\r
+       {\r
+               return doGaussianElimination(i_left,i_right,i_number_of_system,i_number_of_system);\r
+       }\r
+}\r
index e04cc79..bab45c6 100644 (file)
@@ -1,3 +1,34 @@
+/* \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.core2.types.matrix;\r
 \r
 public class NyARI64Matrix22\r
index 4e332e0..e7ec9fc 100644 (file)
@@ -42,7 +42,6 @@ import jp.nyatla.nyartoolkit.core.transmat.*;
 import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
 import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
 import jp.nyatla.nyartoolkit.core.types.*;\r
-import java.util.*;\r
 \r
 /**\r
  * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
@@ -97,7 +96,8 @@ public class NyARCustomSingleDetectMarker
                this._marker_width = i_marker_width;\r
                //パターンピックアップを作成\r
 //             this._patt = new NyARColorPatt_O1(i_code.getWidth(), i_code.getHeight());\r
-               this._patt = new NyARColorPatt_O3(i_code.getWidth(), i_code.getHeight());\r
+//             this._patt = new NyARColorPatt_O3(i_code.getWidth(), i_code.getHeight());\r
+               this._patt = new NyARColorPatt_Perspective(i_code.getWidth(), i_code.getHeight(),25);\r
                //取得パターンの差分データ器を作成\r
                this._deviation_data=new NyARMatchPattDeviationColorData(i_code.getWidth(),i_code.getHeight());\r
                //i_code用の評価器を作成\r
@@ -199,9 +199,9 @@ public class NyARCustomSingleDetectMarker
         * @param o_point\r
         * 4要素以上の配列を指定して下さい。先頭の4要素に値がコピーされます。\r
         */\r
-       public void getSquarePosition(NyARIntPoint[] o_point)\r
+       public void getSquarePosition(NyARIntPoint2d[] o_point)\r
        {\r
-               NyARIntPoint.copyArray(this._detected_square.imvertex,o_point);\r
+               NyARIntPoint2d.copyArray(this._detected_square.imvertex,o_point);\r
                return;\r
        }\r
        /**\r
@@ -210,7 +210,7 @@ public class NyARCustomSingleDetectMarker
         * 外部でデータをストックする場合は、getSquarePositionで複製して下さい。\r
         * @return\r
         */\r
-       public NyARIntPoint[] refSquarePosition()\r
+       public NyARIntPoint2d[] refSquarePosition()\r
        {\r
                return this._detected_square.imvertex;\r
        }\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerData.java b/trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerData.java
new file mode 100644 (file)
index 0000000..987edf8
--- /dev/null
@@ -0,0 +1,45 @@
+/* \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-2009 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.nyidmarker;\r
+/**\r
+ * IDマーカの値を格納するクラスです。\r
+ * クラスは、未整形のマーカデータを格納しています。\r
+ *\r
+ */\r
+public class NyARIdMarkerData\r
+{\r
+       public int model;\r
+       public int ctrl_domain;\r
+       public int ctrl_mask;\r
+       public int check;\r
+       public int[] data=new int[16];\r
+}
\ No newline at end of file
diff --git a/trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerParam.java b/trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerParam.java
new file mode 100644 (file)
index 0000000..f969595
--- /dev/null
@@ -0,0 +1,43 @@
+/* \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-2009 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.nyidmarker;\r
+\r
+/**\r
+ * マーカを抽出した時のパラメータを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARIdMarkerParam\r
+{\r
+       public int direction;\r
+       public int threshold; \r
+       \r
+}\r
diff --git a/trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerPickup.java b/trunk/src/jp/nyatla/nyartoolkit/nyidmarker/NyARIdMarkerPickup.java
new file mode 100644 (file)
index 0000000..3ee5d1e
--- /dev/null
@@ -0,0 +1,1080 @@
+/* \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-2009 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.nyidmarker;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス\r
+ *\r
+ */\r
+class PerspectivePixelReader\r
+{\r
+       private NyARPerspectiveParamGenerator _param_gen=new NyARPerspectiveParamGenerator_O1(1,1,100,100);\r
+       private double[] _cparam=new double[8];\r
+\r
+       public PerspectivePixelReader()\r
+       {\r
+               return;\r
+       }\r
+       private INyARRgbRaster _raster;\r
+       public void setSourceRaster(INyARRgbRaster i_raster)\r
+       {\r
+               this._raster=i_raster;\r
+               return;\r
+       }\r
+       public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
+       {\r
+               return this._param_gen.getParam(i_vertex, this._cparam);\r
+       }\r
+\r
+       /**\r
+        * 矩形からピクセルを切り出します\r
+        * @param i_lt_x\r
+        * @param i_lt_y\r
+        * @param i_step_x\r
+        * @param i_step_y\r
+        * @param i_width\r
+        * @param i_height\r
+        * @param i_out_st\r
+        * o_pixelへの格納場所の先頭インデクス\r
+        * @param o_pixel\r
+        * @throws NyARException\r
+        */\r
+       private void rectPixels(int i_lt_x,int i_lt_y,int i_step_x,int i_step_y,int i_width,int i_height,int i_out_st,int[] o_pixel)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               int out_index=i_out_st;\r
+\r
+               for(int i=0;i<i_height;i++){\r
+                       //1列分のピクセルのインデックス値を計算する。\r
+                       int cy0=1+i*i_step_y+i_lt_y;\r
+                       double cpy0_12=cpara[1]*cy0+cpara[2];\r
+                       double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       double cpy0_7=cpara[7]*cy0+1.0;                 \r
+                       int pt=0;\r
+                       for(int i2=0;i2<i_width;i2++)\r
+                       {\r
+                               int cx0=1+i2*i_step_x+i_lt_x;\r
+\r
+                               double cp6_0=cpara[6]*cx0;\r
+                               double cpx0_0=cpara[0]*cx0;\r
+                               double cpx3_0=cpara[3]*cx0;\r
+                               \r
+                               final double d=cp6_0+cpy0_7;\r
+                               ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+                               pt++;\r
+                       }\r
+                       //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+                       reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);\r
+                       //グレースケールにしながら、line→mapへの転写\r
+                       for(int i2=0;i2<i_width;i2++){\r
+                               int index=i2*3;\r
+                               o_pixel[out_index]=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2])/3;\r
+                               out_index++;\r
+                       }                       \r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * i_freqにあるゼロクロス点の周期が、等間隔か調べます。\r
+        * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなします。\r
+        * @param i_freq\r
+        * @param i_width\r
+        */\r
+       private static boolean checkFreqWidth(int[] i_freq,int i_width)\r
+       {\r
+               int c=i_freq[1]-i_freq[0];\r
+               final int count=i_width*2-1;\r
+               for(int i=1;i<count;i++){\r
+                       final int n=i_freq[i+1]-i_freq[i];\r
+                       final int v=n*100/c;\r
+                       if(v>150 || v<50){\r
+                               return false;\r
+                       }\r
+                       c=n;\r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * i_freq_count_tableとi_freq_tableの内容を調査し、最も大きな周波数成分を返します。\r
+        * @param i_freq_count_table\r
+        * @param i_freq_table\r
+        * @param o_freq_table\r
+        * @return\r
+        * 見つかれば0以上、密辛ければ0未満\r
+        */\r
+       private static int getMaxFreq(int[] i_freq_count_table,int[] i_freq_table,int[] o_freq_table)\r
+       {\r
+               //一番成分の大きいものを得る\r
+               int index=-1;\r
+               int max=0;\r
+               for(int i=0;i<MAX_FREQ;i++){\r
+                       if(max<i_freq_count_table[i]){\r
+                               index=i;\r
+                               max=i_freq_count_table[i];\r
+                       }\r
+               }               \r
+               if(index==-1){\r
+                       return -1;\r
+               }\r
+               /*周波数インデクスを計算*/\r
+               final int st=(index-1)*index;\r
+               for(int i=0;i<index*2;i++)\r
+               {\r
+                       o_freq_table[i]=i_freq_table[st+i]*FRQ_STEP/max;\r
+               }\r
+               return index;\r
+       }\r
+               \r
+       \r
+       //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
+       private static int FRQ_EDGE=5;\r
+       private static int FRQ_STEP=2;\r
+       private static int FRQ_POINTS=(100-(FRQ_EDGE*2))/FRQ_STEP;\r
+       \r
+\r
+       private static int MIN_FREQ=3;\r
+       private static int MAX_FREQ=10;\r
+       private static int FREQ_SAMPLE_NUM=4;\r
+       private static int MAX_DATA_BITS=MAX_FREQ+MAX_FREQ-1;\r
+\r
+       private final int[] _ref_x=new int[108];\r
+       private final int[] _ref_y=new int[108];\r
+       //(model+1)*4*3とTHRESHOLD_PIXEL*3のどちらか大きい方\r
+       private int[] _pixcel_temp=new int[108*3];\r
+       \r
+       private final int[] _freq_count_table=new int[MAX_FREQ];\r
+       private final int[] _freq_table=new int[(MAX_FREQ*2-1)*MAX_FREQ*2/2];\r
+\r
+       /**\r
+        * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。\r
+        * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを\r
+        * 検出した場合、関数は失敗します。\r
+        * \r
+        * @param i_y1\r
+        * @param i_y2\r
+        * @param i_th_h\r
+        * @param i_th_l\r
+        * @param o_edge_index\r
+        * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。\r
+        * [FRQ_POINTS]以上の配列を指定してください。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public int getRowFrequency(int i_y1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+       {\r
+               //3,4,5,6,7,8,9,10\r
+               final int[] freq_count_table=this._freq_count_table;\r
+               //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列\r
+               final int freq_table[]=this._freq_table;\r
+               //初期化\r
+               final double[] cpara=this._cparam;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               for(int i=0;i<10;i++){\r
+                       freq_count_table[i]=0;\r
+               }\r
+               for(int i=0;i<110;i++){\r
+                       freq_table[i]=0;\r
+               }\r
+               final double cpara_0=cpara[0];\r
+               final double cpara_3=cpara[3];\r
+               final double cpara_6=cpara[6];\r
+               \r
+               //10-20ピクセル目からタイミングパターンを検出\r
+               for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+                       //2行分のピクセルインデックスを計算\r
+                       final double cy0=1+i_y1+i;\r
+                       final double cpy0_12=cpara[1]*cy0+cpara[2];\r
+                       final double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       final double cpy0_7=cpara[7]*cy0+1.0;                   \r
+\r
+\r
+                       int pt=0;\r
+                       for(int i2=0;i2<FRQ_POINTS;i2++)\r
+                       {\r
+                               double d;\r
+                               final double cx0=1+i2*FRQ_STEP+FRQ_EDGE;                        \r
+                               d=(cpara_6*cx0)+cpy0_7;\r
+                               ref_x[pt]=(int)((cpara_0*cx0+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpara_3*cx0+cpy0_45)/d);\r
+                               pt++;\r
+                       }\r
+                       \r
+                       //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+                       reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+\r
+                       //o_edge_indexを一時的に破壊して調査する\r
+                       final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);                   \r
+                       \r
+                       //周期は3-10であること\r
+                       if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+                               continue;\r
+                       }\r
+                       //周期は等間隔であること\r
+                       if(!checkFreqWidth(o_edge_index,freq_t)){\r
+                               continue;\r
+                       }\r
+                       //検出カウンタを追加\r
+                       freq_count_table[freq_t]++;\r
+                       final int table_st=(freq_t-1)*freq_t;\r
+                       for(int i2=0;i2<freq_t*2;i2++){\r
+                               freq_table[table_st+i2]+=o_edge_index[i2];\r
+                       }\r
+               }\r
+               return getMaxFreq(freq_count_table,freq_table,o_edge_index);\r
+       }\r
+       \r
+       public int getColFrequency(int i_x1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110\r
+               final int[] freq_count_table=this._freq_count_table;\r
+               final int freq_table[]=this._freq_table;\r
+               //初期化\r
+               for(int i=0;i<10;i++){\r
+                       freq_count_table[i]=0;\r
+               }\r
+               for(int i=0;i<110;i++){\r
+                       freq_table[i]=0;\r
+               }\r
+               final double cpara7=cpara[7];\r
+               final double cpara4=cpara[4];\r
+               final double cpara1=cpara[1];\r
+               //基準点から4ピクセルを参照パターンとして抽出\r
+               for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+\r
+                       int cx0;\r
+                       cx0=1+i+i_x1;\r
+                       final double cp6_0=cpara[6]*cx0;\r
+                       final double cpx0_0=cpara[0]*cx0+cpara[2];\r
+                       final double cpx3_0=cpara[3]*cx0+cpara[5];\r
+                       \r
+                       int pt=0;\r
+                       for(int i2=0;i2<FRQ_POINTS;i2++)\r
+                       {\r
+                               double d;\r
+                               int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
+                               \r
+                               d=cp6_0+cpara7*cy+1.0;\r
+                               ref_x[pt]=(int)((cpx0_0+cpara1*cy)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpara4*cy)/d);\r
+                               pt++;\r
+                       }               \r
+               \r
+                       //ピクセルを取得(入力画像を多様化するならここを調整すること)\r
+                       reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+                       \r
+                       final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+                       //周期は3-10であること\r
+                       if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+                               continue;\r
+                       }\r
+                       //周期は等間隔であること\r
+                       if(!checkFreqWidth(o_edge_index,freq_t)){\r
+                               continue;\r
+                       }\r
+                       //検出カウンタを追加\r
+                       freq_count_table[freq_t]++;\r
+                       final int table_st=(freq_t-1)*freq_t;\r
+                       for(int i2=0;i2<freq_t*2;i2++){\r
+                               freq_table[table_st+i2]+=o_edge_index[i2];\r
+                       }\r
+               }\r
+               return getMaxFreq(freq_count_table,freq_table,o_edge_index);            \r
+       }\r
+\r
+       /**\r
+        * デバックすんだらstaticにしておk\r
+        * @param i_pixcels\r
+        * @param i_th_h\r
+        * @param i_th_l\r
+        * @param o_edge_index\r
+        * @return\r
+        */\r
+       private static int getFreqInfo(int[] i_pixcels,int i_th_h,int i_th_l,int[] o_edge_index)\r
+       {\r
+               //トークンを解析して、周波数を計算\r
+               int i=0;\r
+               int frq_l2h=0;\r
+               int frq_h2l=0;\r
+               while(i<FRQ_POINTS){\r
+                       //L->Hトークンを検出する\r
+                       while(i<FRQ_POINTS){\r
+                               final int index=i*3;\r
+                               final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+                               if(pix>i_th_h){\r
+                                       //トークン発見\r
+                                       o_edge_index[frq_l2h+frq_h2l]=i;\r
+                                       frq_l2h++;\r
+                                       break;\r
+                               }\r
+                               i++;\r
+                       }\r
+                       i++;\r
+                       //L->Hトークンを検出する\r
+                       while(i<FRQ_POINTS){\r
+                               final int index=i*3;\r
+                               final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+                               if(pix<=i_th_l){\r
+                                       //トークン発見\r
+                                       o_edge_index[frq_l2h+frq_h2l]=i;\r
+                                       frq_h2l++;\r
+                                       break;\r
+                               }\r
+                               i++;\r
+                       }\r
+                       i++;\r
+               }\r
+               return frq_l2h==frq_h2l?frq_l2h:-1;                     \r
+       }\r
+\r
+       private final static int THRESHOLD_EDGE=10;\r
+       private final static int THRESHOLD_STEP=2;\r
+       private final static int THRESHOLD_WIDTH=10;\r
+       private final static int THRESHOLD_PIXEL=THRESHOLD_WIDTH/THRESHOLD_STEP;\r
+       private final static int THRESHOLD_SAMPLE=THRESHOLD_PIXEL*THRESHOLD_PIXEL;\r
+       private final static int THRESHOLD_SAMPLE_LT=THRESHOLD_EDGE;\r
+       private final static int THRESHOLD_SAMPLE_RB=100-THRESHOLD_WIDTH-THRESHOLD_EDGE;\r
+       \r
+       public static class TThreshold{\r
+               public int th_h;\r
+               public int th_l;\r
+               public int th;\r
+               public int lt_x;\r
+               public int lt_y;\r
+               public int rb_x;\r
+               public int rb_y;\r
+       }       \r
+\r
+       class THighAndLow{\r
+               int h;\r
+               int l;\r
+       }\r
+       /**\r
+        * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。\r
+        * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。\r
+        * @param i_pixcel\r
+        * @param i_initial\r
+        * @param i_out\r
+        */\r
+       private void getPtailHighAndLow(int[] i_pixcel,THighAndLow i_out)\r
+       {\r
+               int h3,h2,h1,h0,l3,l2,l1,l0;\r
+               h3=h2=h1=h0=l3=l2=l1=l0=i_pixcel[0];\r
+               \r
+               for(int i=i_pixcel.length-1;i>=1;i--){\r
+                       final int pix=i_pixcel[i];\r
+                       if(h0<pix){\r
+                               if(h1<pix){\r
+                                       if(h2<pix){\r
+                                               if(h3<pix){\r
+                                                       h0=h1;\r
+                                                       h1=h2;\r
+                                                       h2=h3;\r
+                                                       h3=pix;\r
+                                               }else{\r
+                                                       h0=h1;\r
+                                                       h1=h2;\r
+                                                       h2=pix;\r
+                                               }\r
+                                       }else{\r
+                                               h0=h1;\r
+                                               h1=pix;\r
+                                       }\r
+                               }else{\r
+                                       h0=pix;\r
+                               }\r
+                       }\r
+                       if(l0>pix){\r
+                               if(l1>pix){\r
+                                       if(l2>pix){\r
+                                               if(l3>pix){\r
+                                                       l0=l1;\r
+                                                       l1=l2;\r
+                                                       l2=l3;\r
+                                                       l3=pix;\r
+                                               }else{\r
+                                                       l0=l1;\r
+                                                       l1=l2;\r
+                                                       l2=pix;\r
+                                               }\r
+                                       }else{\r
+                                               l0=l1;\r
+                                               l1=pix;\r
+                                       }\r
+                               }else{\r
+                                       l0=pix;\r
+                               }\r
+                       }\r
+               }\r
+               i_out.l=(l0+l1+l2+l3)/4;\r
+               i_out.h=(h0+h1+h2+h3)/4;\r
+               return;\r
+       }\r
+       private THighAndLow __detectThresholdValue_hl=new THighAndLow();\r
+       private NyARIntPoint2d __detectThresholdValue_tpt=new NyARIntPoint2d();\r
+       private int[] _th_pixels=new int[THRESHOLD_SAMPLE*4];\r
+       /**\r
+        * 指定した場所のピクセル値を調査して、閾値を計算して返します。\r
+        * @param i_reader\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public void detectThresholdValue(INyARRgbPixelReader i_reader,int i_x,int i_y,TThreshold o_threshold)throws NyARException\r
+       {\r
+               final int[] th_pixels=this._th_pixels;\r
+\r
+               //左上のピックアップ領域からピクセルを得る(00-24)\r
+               rectPixels(THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,0,th_pixels);\r
+               \r
+               //左下のピックアップ領域からピクセルを得る(25-49)\r
+               rectPixels(THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE,th_pixels);\r
+               \r
+               //右上のピックアップ領域からピクセルを得る(50-74)\r
+               rectPixels(THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*2,th_pixels);\r
+\r
+               //右下のピックアップ領域からピクセルを得る(75-99)\r
+               rectPixels(THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*3,th_pixels);\r
+\r
+               final THighAndLow hl=this.__detectThresholdValue_hl;\r
+               //Ptailで求めたピクセル平均\r
+               getPtailHighAndLow(th_pixels,hl);\r
+\r
+\r
+               \r
+               //閾値中心\r
+               int th=(hl.h+hl.l)/2;\r
+               //ヒステリシス(差分の20%)\r
+               int th_sub=(hl.h-hl.l)/5;\r
+               \r
+               o_threshold.th=th;\r
+               o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値\r
+               o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値\r
+\r
+               //エッジを計算(明点重心)\r
+               int lt_x,lt_y,lb_x,lb_y,rt_x,rt_y,rb_x,rb_y;\r
+               final NyARIntPoint2d tpt=this.__detectThresholdValue_tpt;\r
+               //LT\r
+               if(getHighPixelCenter(0,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       lt_x=tpt.x*THRESHOLD_STEP;\r
+                       lt_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       lt_x=11;\r
+                       lt_y=11;\r
+               }\r
+               //LB\r
+               if(getHighPixelCenter(THRESHOLD_SAMPLE*1,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       lb_x=tpt.x*THRESHOLD_STEP;\r
+                       lb_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       lb_x=11;\r
+                       lb_y=-1;\r
+               }\r
+               //RT\r
+               if(getHighPixelCenter(THRESHOLD_SAMPLE*2,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       rt_x=tpt.x*THRESHOLD_STEP;\r
+                       rt_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       rt_x=-1;\r
+                       rt_y=11;\r
+               }\r
+               //RB\r
+               if(getHighPixelCenter(THRESHOLD_SAMPLE*3,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+                       rb_x=tpt.x*THRESHOLD_STEP;\r
+                       rb_y=tpt.y*THRESHOLD_STEP;\r
+               }else{\r
+                       rb_x=-1;\r
+                       rb_y=-1;\r
+               }\r
+               //トラッキング開始位置の決定\r
+               o_threshold.lt_x=(lt_x+lb_x)/2+THRESHOLD_SAMPLE_LT-1;\r
+               o_threshold.rb_x=(rt_x+rb_x)/2+THRESHOLD_SAMPLE_RB+1;\r
+               o_threshold.lt_y=(lt_y+rt_y)/2+THRESHOLD_SAMPLE_LT-1;\r
+               o_threshold.rb_y=(lb_y+rb_y)/2+THRESHOLD_SAMPLE_RB+1;\r
+               return;\r
+       }\r
+\r
+       private boolean getHighPixelCenter(int i_st,final int[] i_pixels,int i_width,int i_height,int i_th,NyARIntPoint2d o_point)\r
+       {\r
+               int rp=i_st;\r
+               int pos_x=0;\r
+               int pos_y=0;\r
+               int number_of_pos=0;\r
+               for(int i=0;i<i_height;i++){\r
+                       for(int i2=0;i2<i_width;i2++){\r
+                               if(i_pixels[rp++]>i_th){\r
+                                       pos_x+=i2;\r
+                                       pos_y+=i;\r
+                                       number_of_pos++;\r
+                               }\r
+                       }\r
+               }\r
+               if(number_of_pos>0){\r
+                       pos_x/=number_of_pos;\r
+                       pos_y/=number_of_pos;\r
+               }else{\r
+                       return false;\r
+               }\r
+               o_point.x=pos_x;\r
+               o_point.y=pos_y;\r
+               return true;\r
+       }\r
+       private int[] __detectDataBitsIndex_freq_index1=new int[FRQ_POINTS];\r
+       private int[] __detectDataBitsIndex_freq_index2=new int[FRQ_POINTS];\r
+       private int detectDataBitsIndex(PerspectivePixelReader.TThreshold i_th,double[] o_index_row,double[] o_index_col) throws NyARException\r
+       {\r
+               //周波数を測定\r
+               final int freq_index1[]=this.__detectDataBitsIndex_freq_index1;\r
+               final int freq_index2[]=this.__detectDataBitsIndex_freq_index2;\r
+               \r
+               \r
+               int frq_t=getRowFrequency(i_th.lt_y,i_th.th_h,i_th.th_l,freq_index1);\r
+               int frq_b=getRowFrequency(i_th.rb_y,i_th.th_h,i_th.th_l,freq_index2);\r
+               //周波数はまとも?\r
+               if((frq_t<0 && frq_b<0) || frq_t==frq_b){\r
+                       return -1;\r
+               }\r
+               //タイミングパターンからインデクスを作成\r
+               int freq_h,freq_v;\r
+               int[] index;\r
+               if(frq_t>frq_b){\r
+                       freq_h=frq_t;\r
+                       index=freq_index1;\r
+               }else{\r
+                       freq_h=frq_b;\r
+                       index=freq_index2;\r
+               }\r
+               for(int i=0;i<freq_h+freq_h-1;i++){\r
+                       o_index_row[i*2]=((index[i+1]-index[i])*2/5+index[i])+FRQ_EDGE;\r
+                       o_index_row[i*2+1]=((index[i+1]-index[i])*3/5+index[i])+FRQ_EDGE;\r
+               }               \r
+               \r
+               \r
+               int frq_l=getColFrequency(i_th.lt_x,i_th.th_h,i_th.th_l,freq_index1);\r
+               int frq_r=getColFrequency(i_th.rb_x,i_th.th_h,i_th.th_l,freq_index2);\r
+               //周波数はまとも?\r
+               if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
+                       return -1;\r
+               }\r
+               //タイミングパターンからインデクスを作成\r
+               if(frq_l>frq_r){\r
+                       freq_v=frq_l;\r
+                       index=freq_index1;\r
+               }else{\r
+                       freq_v=frq_r;\r
+                       index=freq_index2;\r
+               }\r
+               //同じ周期?\r
+               if(freq_v!=freq_h){\r
+                       return -1;\r
+               }\r
+               \r
+               for(int i=0;i<freq_v+freq_v-1;i++){\r
+                       final int w=index[i];\r
+                       final int w2=index[i+1]-w;\r
+                       o_index_col[i*2]=((w2)*2/5+w)+FRQ_EDGE;\r
+                       o_index_col[i*2+1]=((w2)*3/5+w)+FRQ_EDGE;\r
+               }               \r
+               //Lv4以上は無理\r
+               if(freq_v>MAX_FREQ){\r
+                       return -1;\r
+               }\r
+               return freq_v;\r
+               \r
+       }\r
+       private double[] __readDataBits_index_bit_x=new double[MAX_DATA_BITS*2];\r
+       private double[] __readDataBits_index_bit_y=new double[MAX_DATA_BITS*2];\r
+       \r
+       public boolean readDataBits(PerspectivePixelReader.TThreshold i_th,MarkerPattEncoder o_bitbuffer)throws NyARException\r
+       {\r
+               final double[] index_x=this.__readDataBits_index_bit_x;\r
+               final double[] index_y=this.__readDataBits_index_bit_y;\r
+               //読み出し位置を取得\r
+               final int size=detectDataBitsIndex(i_th,index_x,index_y);\r
+               final int resolution=size+size-1;\r
+               if(size<0){\r
+                       return false;\r
+               }\r
+               if(!o_bitbuffer.initEncoder(size-1)){\r
+                       return false;\r
+               }               \r
+               \r
+               final double[] cpara=this._cparam;\r
+               final int[] ref_x=this._ref_x;\r
+               final int[] ref_y=this._ref_y;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               \r
+               final double cpara_0=cpara[0];\r
+               final double cpara_1=cpara[1];\r
+               final double cpara_3=cpara[3];\r
+               final double cpara_6=cpara[6];\r
+               \r
+               \r
+               final int th=i_th.th;\r
+               int p=0;\r
+               int pt2=0;\r
+               for(int i=0;i<resolution;i++){\r
+                       //1列分のピクセルのインデックス値を計算する。\r
+                       double cy0=1+index_y[i*2+0];\r
+                       double cy1=1+index_y[i*2+1];                    \r
+                       double cpy0_12=cpara_1*cy0+cpara[2];\r
+                       double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       double cpy0_7=cpara[7]*cy0+1.0;\r
+                       double cpy1_12=cpara_1*cy1+cpara[2];\r
+                       double cpy1_45=cpara[4]*cy1+cpara[5];\r
+                       double cpy1_7=cpara[7]*cy1+1.0;\r
+                       \r
+                       int pt=0;\r
+                       for(int i2=0;i2<resolution;i2++)\r
+                       {                       \r
+\r
+                               double d;\r
+                               double cx0=1+index_x[i2*2+0];\r
+                               double cx1=1+index_x[i2*2+1];\r
+\r
+                               double cp6_0=cpara_6*cx0;\r
+                               double cpx0_0=cpara_0*cx0;\r
+                               double cpx3_0=cpara_3*cx0;\r
+\r
+                               double cp6_1=cpara_6*cx1;\r
+                               double cpx0_1=cpara_0*cx1;\r
+                               double cpx3_1=cpara_3*cx1;\r
+                               \r
+                               d=cp6_0+cpy0_7;\r
+                               ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+                               this.vertex_x[pt2]=ref_x[pt];\r
+                               this.vertex_y[pt2++]=ref_y[pt];\r
+                               pt++;\r
+\r
+                               d=cp6_0+cpy1_7;\r
+                               ref_x[pt]=(int)((cpx0_0+cpy1_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpy1_45)/d);\r
+                               this.vertex_x[pt2]=ref_x[pt];\r
+                               this.vertex_y[pt2++]=ref_y[pt];\r
+                               pt++;\r
+\r
+                               d=cp6_1+cpy0_7;\r
+                               ref_x[pt]=(int)((cpx0_1+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_1+cpy0_45)/d);\r
+                               this.vertex_x[pt2]=ref_x[pt];\r
+                               this.vertex_y[pt2++]=ref_y[pt];\r
+                               pt++;\r
+\r
+                               d=cp6_1+cpy1_7;\r
+                               ref_x[pt]=(int)((cpx0_1+cpy1_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_1+cpy1_45)/d);\r
+                               this.vertex_x[pt2]=ref_x[pt];\r
+                               this.vertex_y[pt2++]=ref_y[pt];\r
+                               pt++;\r
+                       }\r
+                       //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+                       reader.getPixelSet(ref_x,ref_y,resolution*4,pixcel_temp);\r
+                       //グレースケールにしながら、line→mapへの転写\r
+                       for(int i2=0;i2<resolution;i2++){\r
+                               int index=i2*3*4;\r
+                               int pixel=(     pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+\r
+                                                       pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
+                                                       pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
+                                                       pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
+                               o_bitbuffer.setBitByBitIndex(p,pixel>th?1:0);\r
+                               p++;\r
+                       }\r
+               }\r
+/*             \r
+               for(int i=0;i<225*4;i++){\r
+                       this.vertex_x[i]=0;\r
+                       this.vertex_y[i]=0;\r
+               }\r
+               for(int i=0;i<(resolution)*2;i++){\r
+                       for(int i2=0;i2<(resolution)*2;i2++){\r
+                               this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2];\r
+                               this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i];\r
+                               \r
+                       }\r
+               }\r
+*/             return true;\r
+       }\r
+       int[] vertex_x;\r
+       int[] vertex_y;\r
+       public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
+       {\r
+               if (!this._param_gen.getParam(i_vertex,this._cparam)) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
+}\r
+class MarkerPattDecoder\r
+{\r
+       public void decode(int model,int domain,int mask)\r
+       {\r
+               \r
+       }\r
+}\r
+/**\r
+ * マーカパターンのエンコーダです。\r
+ *\r
+ */\r
+class MarkerPattEncoder\r
+{\r
+       private final static int[] _bit_table_3={\r
+               25,     26,     27,     28,     29,     30,     31,\r
+               48,     9,      10,     11,     12,     13,     32,\r
+               47,     24,     1,      2,      3,      14,     33,\r
+               46,     23,     8,      0,      4,      15,     34,\r
+               45,     22,     7,      6,      5,      16,     35,\r
+               44,     21,     20,     19,     18,     17,     36,\r
+               43,     42,     41,     40,     39,     38,     37\r
+               };      \r
+       private final static int[] _bit_table_2={\r
+               9,      10,     11,     12,     13,\r
+               24,     1,      2,      3,      14,\r
+               23,     8,      0,      4,      15,\r
+               22,     7,      6,      5,      16,\r
+               21,     20,     19,     18,     17};\r
+       private final static int[][] _bit_tables={\r
+               _bit_table_2,_bit_table_3,null,null,null,null,null,\r
+       };\r
+       /**\r
+        * RECT(0):[0]=(0)\r
+        * RECT(1):[1]=(1-8)\r
+        * RECT(2):[2]=(9-16),[3]=(17-24)\r
+        * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)\r
+        */\r
+       int[] _bit_table;\r
+       int[] _bits=new int[16];\r
+       int[] _work=new int[16];\r
+       int _model;\r
+       public void setBitByBitIndex(int i_index_no,int i_value)\r
+       {\r
+               assert i_value==0 || i_value==1;\r
+               final int bit_no=this._bit_table[i_index_no];\r
+               if(bit_no==0){\r
+                       this._bits[0]=i_value;\r
+               }else{\r
+                       int bidx=(bit_no-1)/8+1;\r
+                       int sidx=(bit_no-1)%8;\r
+                       this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+               }\r
+               return;\r
+       }\r
+       \r
+       public void setBit(int i_bit_no,int i_value)\r
+       {\r
+               assert i_value==0 || i_value==1;\r
+               if(i_bit_no==0){\r
+                       this._bits[0]=i_value;\r
+               }else{\r
+                       int bidx=(i_bit_no-1)/8+1;\r
+                       int sidx=(i_bit_no-1)%8;\r
+                       this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+               }\r
+               return;\r
+       }\r
+       public int getBit(int i_bit_no)\r
+       {\r
+               if(i_bit_no==0){\r
+                       return this._bits[0];\r
+               }else{\r
+                       int bidx=(i_bit_no-1)/8+1;\r
+                       int sidx=(i_bit_no-1)%8;\r
+                       return (this._bits[bidx]>>(sidx))&(0x01);\r
+               }\r
+       }\r
+       public int getModel()\r
+       {\r
+               return this._model;\r
+       }\r
+       private static int getControlValue(int i_model,int[] i_data)\r
+       {\r
+               int v;\r
+               switch(i_model){\r
+               case 2:\r
+                       v=(i_data[2] & 0x0e)>>1;\r
+                       return v>=5?v-1:v;\r
+               case 3:\r
+                       v=(i_data[4] & 0x3e)>>1;\r
+                       return v>=21?v-1:v;\r
+               case 4:\r
+               case 5:\r
+               case 6:\r
+               case 7:\r
+               }\r
+               return -1;\r
+       }\r
+       public static int getCheckValue(int i_model,int[] i_data)\r
+       {\r
+               int v;\r
+               switch(i_model){\r
+               case 2:\r
+                       v=(i_data[2] & 0xe0)>>5;\r
+                       return v>5?v-1:v;\r
+               case 3:\r
+                       v=((i_data[4] & 0x80)>>7) |((i_data[5] & 0x0f)<<1);\r
+                       return v>21?v-1:v;\r
+               case 4:\r
+               case 5:\r
+               case 6:\r
+               case 7:\r
+               }\r
+               return -1;\r
+       }\r
+       public boolean initEncoder(int i_model)\r
+       {\r
+               if(i_model>3 || i_model<2){\r
+                       //Lv4以降に対応する時は、この制限を変える。\r
+                       return false;\r
+               }\r
+               this._bit_table=_bit_tables[i_model-2];\r
+               this._model=i_model;\r
+               return true;\r
+       }\r
+       private int getDirection()\r
+       {\r
+               int l,t,r,b;\r
+               int timing_pat;\r
+               switch(this._model){\r
+               case 2:\r
+                       //トラッキングセルを得る\r
+                       t=this._bits[2] & 0x1f;\r
+                       r=((this._bits[2] & 0xf0)>>4)|((this._bits[3]&0x01)<<4);\r
+                       b=this._bits[3] & 0x1f;\r
+                       l=((this._bits[3] & 0xf0)>>4)|((this._bits[2]&0x01)<<4);\r
+                       timing_pat=0x15;\r
+                       break;\r
+               case 3:\r
+                       t=this._bits[4] & 0x7f;\r
+                       r=((this._bits[4] & 0xc0)>>6)|((this._bits[5] & 0x1f)<<2);\r
+                       b=((this._bits[5] & 0xf0)>>4)|(this._bits[6]&0x07<<4);\r
+                       l=((this._bits[7] & 0xfc)>>2)|((this._bits[4] & 0x01)<<7);\r
+                       timing_pat=0x55;\r
+                       break;\r
+               default:\r
+                       return -3;\r
+               }\r
+               //タイミングパターンの比較\r
+               if(t==timing_pat){\r
+                       if(r==timing_pat){\r
+                               return (b!=timing_pat && l!=timing_pat)?2:-2;\r
+                       }else if(l==timing_pat){\r
+                               return (b!=timing_pat && r!=timing_pat)?3:-2;\r
+                       }\r
+               }else if(b==timing_pat){\r
+                       if(r==timing_pat){\r
+                               return (t!=timing_pat && l!=timing_pat)?1:-2;\r
+                       }else if(l==timing_pat){\r
+                               return (t!=timing_pat && r!=timing_pat)?0:-2;\r
+                       }\r
+               }\r
+               return -1;\r
+       }\r
+       /**\r
+        * 格納しているマーカパターンをエンコードして、マーカデータを返します。\r
+        * @param o_out\r
+        * @return\r
+        * 成功すればマーカの方位を返却します。失敗すると-1を返します。\r
+        */\r
+\r
+       public int encode(NyARIdMarkerData o_out)\r
+       {\r
+               final int d=getDirection();\r
+               if(d<0){\r
+                       return -1;\r
+               }\r
+               //回転ビットの取得\r
+               getRotatedBits(d,o_out.data);\r
+               final int model=this._model;\r
+               //周辺ビットの取得\r
+               o_out.model=model;\r
+               int control_bits=getControlValue(model,o_out.data);\r
+               o_out.check=getCheckValue(model,o_out.data);\r
+               o_out.ctrl_mask=control_bits%5;\r
+               o_out.ctrl_domain=control_bits/5;\r
+               if(o_out.ctrl_domain!=0 || o_out.ctrl_mask!=0){\r
+                       return -1;\r
+               }\r
+               //マスク解除処理を実装すること\r
+               return d;\r
+       }\r
+       private void getRotatedBits(int i_direction,int[] o_out)\r
+       {\r
+               int sl=i_direction*2;\r
+               int sr=8-sl;\r
+\r
+               int w1;\r
+               //RECT1\r
+               w1=this._bits[1];\r
+               this._bits[1]=(w1<<sl)|(w1>>sr);\r
+               \r
+               //RECT2\r
+               sl=i_direction*4;\r
+               sr=16-sl;\r
+               w1=this._bits[2]|(this._bits[3]<<8);\r
+               w1=(w1<<sl)|(w1>>sr);\r
+               o_out[2]=w1 & 0xff;\r
+               o_out[3]=(w1>>8) & 0xff;\r
+\r
+               if(this._model<2){\r
+                       return;\r
+               }\r
+\r
+               //RECT3\r
+               sl=i_direction*6;\r
+               sr=24-sl;                       \r
+               w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);\r
+               w1=(w1<<sl)|(w1>>sr);\r
+               o_out[4]=w1 & 0xff;\r
+               o_out[5]=(w1>>8) & 0xff;\r
+               o_out[6]=(w1>>16) & 0xff;\r
+               \r
+               if(this._model<3){\r
+                       return;\r
+               }\r
+               //RECT4(Lv4以降はここの制限を変える)\r
+//             shiftLeft(this._bits,7,3,i_direction*8);\r
+//             if(this._model<4){\r
+//                     return;\r
+//             }\r
+               return;\r
+       }\r
+       public void shiftLeft(int[] i_pack,int i_start,int i_length,int i_ls)\r
+       {\r
+               int[] work=this._work;\r
+               //端数シフト\r
+               final int mod_shift=i_ls%8;\r
+               for(int i=i_length-1;i>=1;i--){\r
+                       work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));\r
+               }\r
+               work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));\r
+               //バイトシフト\r
+               final int byte_shift=(i_ls/8)%i_length;\r
+               for(int i=i_length-1;i>=0;i--){\r
+                       i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];\r
+               }\r
+               return;\r
+       }       \r
+}\r
+/**\r
+ * ラスタ画像の任意矩形から、NyARIdMarkerDataを抽出します。\r
+ *\r
+ */\r
+public class NyARIdMarkerPickup\r
+{\r
+       PerspectivePixelReader _perspective_reader;\r
+\r
+\r
+       public NyARIdMarkerPickup()\r
+       {\r
+               this._perspective_reader=new PerspectivePixelReader();\r
+               return;\r
+       }       \r
+       \r
+       \r
+\r
+       public int[] vertex_x=new int[225*4];\r
+       public int[] vertex_y=new int[225*4];\r
+       public int[] vertex2_x=new int[400];\r
+       public int[] vertex2_y=new int[400];\r
+\r
+\r
+\r
+       /**\r
+        * i_imageから、idマーカを読みだします。\r
+        * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。\r
+        * @param image\r
+        * @param i_square\r
+        * @param o_data\r
+        * @param o_param\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square,NyARIdMarkerData o_data,NyARIdMarkerParam o_param)throws NyARException\r
+       {\r
+               this._perspective_reader.setSourceRaster(image);\r
+               \r
+               //遠近法のパラメータを計算\r
+               if(!this._perspective_reader.setSourceSquare(i_square.imvertex)){\r
+                       return false;\r
+               };\r
+               \r
+               final INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+\r
+\r
+               PerspectivePixelReader.TThreshold th=new PerspectivePixelReader.TThreshold();\r
+               MarkerPattEncoder encoder=new MarkerPattEncoder();\r
+               //マーカパラメータを取得\r
+               this._perspective_reader.detectThresholdValue(reader,10,10,th);\r
+\r
+       \r
+               this._perspective_reader.vertex_x=this.vertex_x;\r
+               this._perspective_reader.vertex_y=this.vertex_y;\r
+\r
+               this._perspective_reader.readDataBits(th, encoder);\r
+               final int d=encoder.encode(o_data);\r
+               if(d<0){\r
+                       return false;\r
+               }\r
+               o_param.direction=d;\r
+               o_param.threshold=th.th;\r
+               \r
+               return true;\r
+       }\r
+}\r
index 70ae433..acaea76 100644 (file)
@@ -35,7 +35,8 @@ import jp.nyatla.nyartoolkit.core.transmat.*;
 import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
 import jp.nyatla.nyartoolkit.core.types.*;\r
 \r
-/**このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
+/**\r
+ * このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
  * マーカの出現・移動・消滅を、イベントで通知することができます。\r
  * クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを\r
  * 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。\r
@@ -43,7 +44,7 @@ import jp.nyatla.nyartoolkit.core.types.*;
  * イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。\r
  * マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。\r
  * 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave\r
- * イベントがコールされます。\r
+ * イベントが発生します。\r
  * \r
  */\r
 public abstract class SingleARMarkerProcesser\r
index 5798a73..913781c 100644 (file)
@@ -1,12 +1,6 @@
 /* \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
index e4fa0da..c4cb00d 100644 (file)
@@ -1,12 +1,6 @@
 /* \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
index 734e754..64a6af2 100644 (file)
@@ -1,12 +1,6 @@
 /* \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
diff --git a/trunk/src/jp/nyatla/utils/j2se/BufferedImageSink.java b/trunk/src/jp/nyatla/utils/j2se/BufferedImageSink.java
new file mode 100644 (file)
index 0000000..b28064b
--- /dev/null
@@ -0,0 +1,30 @@
+package jp.nyatla.utils.j2se;\r
+\r
+import java.awt.image.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+public class BufferedImageSink extends BufferedImage\r
+{\r
+       public BufferedImageSink(int i_width,int i_height)\r
+       {\r
+               super(i_width,i_height,TYPE_INT_RGB);\r
+       }\r
+       public void sinkFromRaster(INyARRgbRaster i_in) throws NyARException\r
+       {\r
+               assert i_in.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
+               \r
+               //thisへ転写\r
+               INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
+               int[] rgb=new int[3];\r
+\r
+               for(int y=this.getHeight()-1;y>=0;y--){\r
+                       for(int x=this.getWidth()-1;x>=0;x--){\r
+                               reader.getPixel(x,y,rgb);\r
+                               this.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+}\r
index f8e065d..15b7f76 100644 (file)
@@ -222,7 +222,7 @@ public class LabelingBufferdImage extends BufferedImage
        public void overlayData(NyARIntPointStack i_stack)\r
        {\r
                int count = i_stack.getLength();\r
-               NyARIntPoint[] items = (NyARIntPoint[])i_stack.getArray();\r
+               NyARIntPoint2d[] items = (NyARIntPoint2d[])i_stack.getArray();\r
                Graphics g = this.getGraphics();\r
                for (int i = 0; i < count; i++) {\r
                        int x = items[i].x;\r
diff --git a/trunk/test/jp/nyatla/nyartoolkit/dev/CopyOfNyARColorPatt_NyIdMarker.java b/trunk/test/jp/nyatla/nyartoolkit/dev/CopyOfNyARColorPatt_NyIdMarker.java
new file mode 100644 (file)
index 0000000..48ca278
--- /dev/null
@@ -0,0 +1,1119 @@
+/* \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.dev;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelingLabel;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.MarkerPattEncoder;\r
+import jp.nyatla.nyartoolkit.nyidmarker.PerspectivePixelReader;\r
+\r
+\r
+\r
+/**\r
+ * 1区間にある1個のエッジ位置を推定するクラスです。\r
+ *\r
+ */\r
+class NyARSingleEdgeFinder2\r
+{\r
+       public static class TEdgeInfo\r
+       {\r
+               double point;   //検出したエッジの位置\r
+               int sub;                //エッジの差分\r
+       }       \r
+       private int[] _work;\r
+       private int _width;\r
+       private int _height;\r
+       public NyARSingleEdgeFinder2(int i_width,int i_height)\r
+       {\r
+               this._work=new int[(i_width>i_height?i_width:i_height)+1];\r
+               this._work[this._work.length-1]=0;\r
+               this._width=i_width;\r
+               this._height=i_height;\r
+               return;\r
+       }\r
+       /**\r
+        * この関数は、一区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+        * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+        * 検出方向は左→右の順です\r
+        * @param i_pixcel\r
+        * @param i_start\r
+        * @param i_length\r
+        * @param o_out\r
+        * @return\r
+        */\r
+       public boolean scanSingleEdgeLeftToRight(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int length=this._width-1;\r
+               int p=i_y*this._width;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p+1]-i_pixcel[p];\r
+                       p++;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }\r
+       /**\r
+        * 線分内のエッジを検出します。\r
+        * この関数は、1区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+        * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+        * 検出方向は右→左の順です\r
+        * @param i_pixcel\r
+        * @param i_start\r
+        * @param i_length\r
+        * @param o_out\r
+        * @return\r
+        */\r
+       public boolean scanSingleEdgeRightToLeft(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int length=this._width-1;\r
+               int p=(i_y+1)*this._width-1;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p-1]-i_pixcel[p];\r
+                       p--;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }       \r
+       public boolean scanSingleEdgeTopToBottom(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int step=this._width;\r
+               final int length=this._height-1;\r
+               int p=i_x;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p+step]-i_pixcel[p];\r
+                       p+=step;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }\r
+       public boolean scanSingleEdgeBottomToTop(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int step=this._width;\r
+               final int length=this._height-1;\r
+               int p=i_x+step*length;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixcel[p-step]-i_pixcel[p];\r
+                       p-=step;\r
+               }\r
+               return scanSingleEdge(temp,length,o_out);\r
+       }       \r
+       private boolean scanSingleEdge(int[] i_pixels,int i_length,TEdgeInfo o_out)\r
+       {\r
+               //微分(2回目)して、極値2か所を得る\r
+               int max_index,min_index;\r
+               int length=i_length-1;\r
+               max_index=min_index=0;\r
+               int max_value,min_value;\r
+               max_value=min_value=0;\r
+               for(int i2=0;i2<length;i2++){\r
+                       int t=i_pixels[i2+1]-i_pixels[i2];\r
+                       if(t>max_value){\r
+                               max_index=i2;\r
+                               max_value=t;\r
+                       }\r
+                       if(t<min_value){\r
+                               min_index=i2;\r
+                               min_value=t;\r
+                       }\r
+               }\r
+               //同符号である場合、範囲内にエッジはない\r
+               if(max_value*min_value>=0){\r
+                       return false;\r
+               }               \r
+               o_out.point=(max_index+min_index)/2.0;\r
+               o_out.sub=max_value-min_value;\r
+               return true;\r
+       }\r
+       public int scanEdgeLeftToRight(int[] i_pixel,int i_y,int i_noise_th,double[] o_edge_index)\r
+       {\r
+               final int[] temp=this._work;\r
+               //1回微分(0-8)\r
+               final int length=this._width-1;\r
+               int p=i_y*this._width;\r
+               for(int i2=0;i2<length;i2++){\r
+                       temp[i2]=i_pixel[p+1]-i_pixel[p];\r
+                       p++;\r
+               }\r
+               //0終端させるために1要素を後続に追加\r
+               return scanEdge(temp,length+1,i_noise_th,o_edge_index);\r
+       }\r
+       private int scanEdge(int[] i_pixels,int i_length,int i_noise_th,double[] o_out)\r
+       {\r
+               int points=0;\r
+               final int length=i_length;\r
+               //エッジ1区間を抜き出す\r
+               for(int i2=0;i2<length;i2++){\r
+                       int t=i_pixels[i2];\r
+                       if(t>i_noise_th){\r
+                               int st=i2;\r
+                               i2++;\r
+                               for(;i2<length;i2++){\r
+                                       t=i_pixels[i2];\r
+                                       if(t<=0){\r
+                                               //(st - i2で1区間)\r
+                                               //エッジ位置は区間の中央にする。\r
+                                               o_out[points]=(st+i2)/2.0;\r
+                                               points++;\r
+                                               if(t<0){\r
+                                                       //マイナスであれば、0を補完する\r
+                                                       i2--;\r
+                                                       i_pixels[i2]=0;\r
+                                               }\r
+                                               break;\r
+                                       }\r
+\r
+                               }\r
+                       }else if(t<-i_noise_th){\r
+                               int st=i2;\r
+                               i2++;\r
+                               for(;i2<length;i2++){\r
+                                       t=i_pixels[i2];\r
+                                       if(t>=0){\r
+                                               //(st - i2で1区間)\r
+                                               //エッジ位置は区間の中央にする。\r
+                                               o_out[points]=(st+i2)/2.0;\r
+                                               points++;\r
+                                               if(t>0){\r
+                                                       //プラスであれば、0を補完する\r
+                                                       i2--;\r
+                                                       i_pixels[i2]=0;\r
+                                               }\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               return points;\r
+       }       \r
+       /**\r
+        * 指定した配列をノイズパターンとして、ノイズ値を計算します。\r
+        * このノイズ値は、scanEdgeのノイズ値として使用できます。\r
+        * @param i_pixels\r
+        * @param i_length\r
+        * @return\r
+        */\r
+       public int getNoiseValue(int[] i_pixels,int i_length)\r
+       {\r
+               //1回微分して、その最大値と最小値を計算\r
+               int length=i_length-1;\r
+               int max_value,min_value;\r
+               max_value=min_value=0;\r
+               for(int i2=0;i2<length;i2++){\r
+                       int t=i_pixels[i2+1]-i_pixels[i2];\r
+                       if(t>max_value){\r
+                               max_value=t;\r
+                       }\r
+                       if(t<min_value){\r
+                               min_value=t;\r
+                       }\r
+               }\r
+               return (-min_value>max_value)?-min_value:max_value;\r
+       }       \r
+}\r
+\r
+class MarkerEncoder2\r
+{\r
+       private final static int[] _bit_table_3={\r
+               25,     26,     27,     28,     29,     30,     31,\r
+               48,     9,      10,     11,     12,     13,     32,\r
+               47,     24,     1,      2,      3,      14,     33,\r
+               46,     23,     8,      0,      4,      15,     34,\r
+               45,     22,     7,      6,      5,      16,     35,\r
+               44,     21,     20,     19,     18,     17,     36,\r
+               43,     42,     41,     40,     39,     38,     37\r
+               };      \r
+       private final static int[] _bit_table_2={\r
+               9,      10,     11,     12,     13,\r
+               24,     1,      2,      3,      14,\r
+               23,     8,      0,      4,      15,\r
+               22,     7,      6,      5,      16,\r
+               21,     20,     19,     18,     17};\r
+       private final static int[][] _bit_tables={\r
+               _bit_table_2,_bit_table_3\r
+       };\r
+       /**\r
+        * RECT(0):[0]=(0)\r
+        * RECT(1):[1]=(1-8)\r
+        * RECT(2):[2]=(9-16),[3]=(17-24)\r
+        * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)\r
+        */\r
+       int[] _bit_table;\r
+       int[] _bits=new int[16];\r
+       int[] _work=new int[16];\r
+       int _model;\r
+       public void setBitByBitIndex(int i_index_no,int i_value)\r
+       {\r
+               assert i_value==0 || i_value==1;\r
+               final int bit_no=this._bit_table[i_index_no];\r
+               if(bit_no==0){\r
+                       this._bits[0]=i_value;\r
+               }else{\r
+                       int bidx=(bit_no-1)/8+1;\r
+                       int sidx=(bit_no-1)%8;\r
+                       this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+               }\r
+               return;\r
+       }\r
+       \r
+       public void setBit(int i_bit_no,int i_value)\r
+       {\r
+               assert i_value==0 || i_value==1;\r
+               if(i_bit_no==0){\r
+                       this._bits[0]=i_value;\r
+               }else{\r
+                       int bidx=(i_bit_no-1)/8+1;\r
+                       int sidx=(i_bit_no-1)%8;\r
+                       this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+               }\r
+               return;\r
+       }\r
+       public int getBit(int i_bit_no)\r
+       {\r
+               if(i_bit_no==0){\r
+                       return this._bits[0];\r
+               }else{\r
+                       int bidx=(i_bit_no-1)/8+1;\r
+                       int sidx=(i_bit_no-1)%8;\r
+                       return (this._bits[bidx]>>(sidx))&(0x01);\r
+               }\r
+       }\r
+       public boolean initEncoder(int i_model)\r
+       {\r
+               if(i_model>=4 || i_model<2){\r
+                       //Lv4以降に対応する時は、この制限を変える。\r
+                       return false;\r
+               }\r
+               this._bit_table=_bit_tables[i_model-2];\r
+               this._model=i_model;\r
+               return true;\r
+       }\r
+       private int getDirection()\r
+       {\r
+               int l,t,r,b;\r
+               switch(this._model){\r
+               case 2:\r
+                       //トラッキングセルを得る\r
+                       t=this._bits[2] & 0x07;\r
+                       r=(this._bits[2] & 0x70)>>4;\r
+                       b=this._bits[3] & 0x07;\r
+                       l=(this._bits[3] & 0x70)>>4;\r
+                       break;\r
+               case 3:\r
+               default:\r
+                       return -3;\r
+               }\r
+               //101であるかを確認\r
+               if(t==0x05){\r
+                       if(r==0x05){\r
+                               return (b!=0x05 && l!=0x05)?2:-2;\r
+                       }else if(l==0x05){\r
+                               return (b!=0x05 && r!=0x05)?3:-2;\r
+                       }\r
+               }else if(b==0x05){\r
+                       if(r==0x05){\r
+                               return (t!=0x05 && l!=0x05)?1:-2;\r
+                       }else if(l==0x05){\r
+                               return (t!=0x05 && r!=0x05)?0:-2;\r
+                       }\r
+               }\r
+               return -1;\r
+       }\r
+\r
+       public boolean encode()\r
+       {\r
+               int d=getDirection();\r
+               if(d<0){\r
+                       return false;\r
+               }\r
+               //回転操作\r
+               \r
+               rotateDirection(d);\r
+               //デコード\r
+               \r
+               return true;\r
+       }\r
+       private void rotateDirection(int i_direction)\r
+       {\r
+               int sl=i_direction*2;\r
+               int sr=8-sl;\r
+\r
+               int w1;\r
+               //RECT1\r
+               w1=this._bits[1];\r
+               this._bits[1]=(w1<<sl)|(w1>>sr);\r
+               \r
+               //RECT2\r
+               sl=i_direction*4;\r
+               sr=16-sl;\r
+               w1=this._bits[2]|(this._bits[3]<<8);\r
+               w1=(w1<<sl)|(w1>>sr);\r
+               this._bits[2]=w1 & 0xff;\r
+               this._bits[3]=(w1>>8) & 0xff;\r
+\r
+               if(this._model<2){\r
+                       return;\r
+               }\r
+\r
+               //RECT3\r
+               sl=i_direction*6;\r
+               sr=24-sl;                       \r
+               w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);\r
+               w1=(w1<<sl)|(w1>>sr);\r
+               this._bits[4]=w1 & 0xff;\r
+               this._bits[5]=(w1>>8) & 0xff;\r
+               this._bits[6]=(w1>>16) & 0xff;\r
+               \r
+               if(this._model<3){\r
+                       return;\r
+               }\r
+               //RECT4(Lv4以降はここの制限を変える)\r
+//             shiftLeft(this._bits,7,3,i_direction*);\r
+\r
+               return;\r
+       }\r
+       public void shiftLeft(int[] i_pack,int i_start,int i_length,int i_ls)\r
+       {\r
+               int[] work=this._work;\r
+               //端数シフト\r
+               final int mod_shift=i_ls%8;\r
+               for(int i=i_length-1;i>=1;i--){\r
+                       work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));\r
+               }\r
+               work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));\r
+               //バイトシフト\r
+               final int byte_shift=(i_ls/8)%i_length;\r
+               for(int i=i_length-1;i>=0;i--){\r
+                       i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];\r
+               }\r
+               return;\r
+       }\r
+\r
+       \r
+}\r
+\r
+\r
+/**\r
+ * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス\r
+ *\r
+ */\r
+class PerspectivePixelReader2 extends NyARPerspectiveParamGenerator_O1\r
+{\r
+       private double[] _cparam=new double[8];\r
+\r
+       public PerspectivePixelReader2(int i_local_x,int i_local_y,int i_width, int i_height)\r
+       {\r
+               super(i_local_x,i_local_y,i_width,i_height);\r
+               this._temp1=new int[i_width];\r
+               this._temp2=new int[i_width];\r
+               this._pixcel_temp=new int[i_width*3];\r
+\r
+               return;\r
+       }\r
+       private int[] _temp1;\r
+       private int[] _temp2;\r
+       private int[] _pixcel_temp;\r
+       private INyARRgbRaster _raster;\r
+       public void setSourceRaster(INyARRgbRaster i_raster)\r
+       {\r
+               this._raster=i_raster;\r
+               return;\r
+       }\r
+       public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
+       {\r
+               return this.getParam(i_vertex, this._cparam);\r
+       }\r
+       public void rectPixels(int i_lt_x,int i_lt_y,int i_width,int i_height,int[] o_pixcel)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._temp1;\r
+               final int[] ref_y=this._temp2;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               int out_index=0;\r
+\r
+               for(int i=0;i<i_height;i++){\r
+                       //1列分のピクセルのインデックス値を計算する。\r
+                       int cy0=1+i+i_lt_y;\r
+                       double cpy0_12=cpara[1]*cy0+cpara[2];\r
+                       double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       double cpy0_7=cpara[7]*cy0+1.0;                 \r
+                       int pt=0;\r
+                       for(int i2=0;i2<i_width;i2++)\r
+                       {\r
+                               int cx0=1+i2+i_lt_x;\r
+\r
+                               double cp6_0=cpara[6]*cx0;\r
+                               double cpx0_0=cpara[0]*cx0;\r
+                               double cpx3_0=cpara[3]*cx0;\r
+                               \r
+                               final double d=cp6_0+cpy0_7;\r
+                               ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+                               pt++;\r
+                       }\r
+                       //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+                       reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);\r
+                       //グレースケールにしながら、line→mapへの転写\r
+                       for(int i2=0;i2<i_width;i2++){\r
+                               int index=i2*3;\r
+                               o_pixcel[out_index]=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2])/3;\r
+                               out_index++;\r
+                       }                       \r
+               }\r
+               return;\r
+       }\r
+\r
+\r
+               \r
+       \r
+       //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
+       private static int FRQ_STEP=2;\r
+       private static int FRQ_POINTS=45;\r
+       public static int FRQ_EDGE=5;\r
+\r
+       \r
+       /**\r
+        * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。\r
+        * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを\r
+        * 検出した場合、関数は失敗します。\r
+        * \r
+        * @param i_y1\r
+        * @param i_y2\r
+        * @param i_th_h\r
+        * @param i_th_l\r
+        * @param o_edge_index\r
+        * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。\r
+        * [FRQ_POINTS]以上の配列を指定してください。\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public int getRowFrequency(int i_y1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._temp1;\r
+               final int[] ref_y=this._temp2;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+\r
+               //2行分のピクセルインデックスを計算\r
+               int cy0=1+i_y1;\r
+               double cpy0_12=cpara[1]*cy0+cpara[2];\r
+               double cpy0_45=cpara[4]*cy0+cpara[5];\r
+               double cpy0_7=cpara[7]*cy0+1.0;                 \r
+\r
+\r
+               int pt=0;\r
+               for(int i2=0;i2<FRQ_POINTS;i2++)\r
+               {\r
+                       double d;\r
+                       final int cx0=1+i2*FRQ_STEP+FRQ_EDGE;                   \r
+                       d=(cpara[6]*cx0)+cpy0_7;\r
+                       ref_x[pt]=(int)((cpara[0]*cx0+cpy0_12)/d);\r
+                       ref_y[pt]=(int)((cpara[3]*cx0+cpy0_45)/d);\r
+                       pt++;\r
+               }\r
+               \r
+               //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+               reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+               return getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+       }\r
+       public int getColFrequency(int i_x1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+       {\r
+               final double[] cpara=this._cparam;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] ref_x=this._temp1;\r
+               final int[] ref_y=this._temp2;\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+\r
+               final int cx0=1+i_x1;\r
+               final double cp6_0=cpara[6]*cx0;\r
+               final double cpx0_0=cpara[0]*cx0;\r
+               final double cpx3_0=cpara[3]*cx0;\r
+\r
+               int pt=0;\r
+               for(int i2=0;i2<FRQ_POINTS;i2++)\r
+               {\r
+                       double d;\r
+                       int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
+                       double cpy_12=cpara[1]*cy+cpara[2];\r
+                       double cpy_45=cpara[4]*cy+cpara[5];\r
+                       double cpy_7=cpara[7]*cy+1.0;   \r
+                       \r
+                       d=cp6_0+cpy_7;\r
+                       ref_x[pt]=(int)((cpx0_0+cpy_12)/d);\r
+                       ref_y[pt]=(int)((cpx3_0+cpy_45)/d);\r
+                       pt++;\r
+                       \r
+               }               \r
+       \r
+               //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+               reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+               return getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+       }\r
+\r
+       /**\r
+        * デバックすんだらstaticにしておk\r
+        * @param i_pixcels\r
+        * @param i_th_h\r
+        * @param i_th_l\r
+        * @param o_edge_index\r
+        * @return\r
+        */\r
+       private int getFreqInfo(int[] i_pixcels,int i_th_h,int i_th_l,int[] o_edge_index)\r
+       {\r
+               //トークンを解析して、周波数を計算\r
+               int i=0;\r
+               int frq_l2h=0;\r
+               int frq_h2l=0;\r
+               while(i<FRQ_POINTS){\r
+                       //L->Hトークンを検出する\r
+                       while(i<FRQ_POINTS){\r
+                               final int index=i*3;\r
+                               final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+                               if(pix>i_th_h){\r
+                                       //トークン発見\r
+                                       o_edge_index[frq_l2h+frq_h2l]=i;\r
+                                       frq_l2h++;\r
+                                       break;\r
+                               }\r
+                               i++;\r
+                       }\r
+                       i++;\r
+                       //L->Hトークンを検出する\r
+                       while(i<FRQ_POINTS){\r
+                               final int index=i*3;\r
+                               final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+                               if(pix<=i_th_l){\r
+                                       //トークン発見\r
+                                       o_edge_index[frq_l2h+frq_h2l]=i;\r
+                                       frq_h2l++;\r
+                                       break;\r
+                               }\r
+                               i++;\r
+                       }\r
+                       i++;\r
+               }\r
+               return frq_l2h==frq_h2l?frq_l2h:-1;                     \r
+       }\r
+\r
+\r
+\r
+       public boolean readDataBits(double[] i_index_x,double[] i_index_y,int i_size,int i_th,MarkerPattEncoder o_bitbuffer)throws NyARException\r
+       {\r
+               \r
+               assert i_size*4<this._width;\r
+               \r
+               final double[] cpara=this._cparam;\r
+\r
+               final int[] ref_x=this._temp1;\r
+               final int[] ref_y=this._temp2;\r
+               final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+               final int[] pixcel_temp=this._pixcel_temp;\r
+               \r
+               int p=0;\r
+               for(int i=0;i<i_size;i++){\r
+                       //1列分のピクセルのインデックス値を計算する。\r
+                       double cy0=1+i_index_y[i*2+0];\r
+                       double cy1=1+i_index_y[i*2+1];                  \r
+                       double cpy0_12=cpara[1]*cy0+cpara[2];\r
+                       double cpy0_45=cpara[4]*cy0+cpara[5];\r
+                       double cpy0_7=cpara[7]*cy0+1.0;\r
+                       double cpy1_12=cpara[1]*cy1+cpara[2];\r
+                       double cpy1_45=cpara[4]*cy1+cpara[5];\r
+                       double cpy1_7=cpara[7]*cy1+1.0;\r
+                       \r
+                       int pt=0;\r
+                       for(int i2=0;i2<i_size;i2++)\r
+                       {                       \r
+\r
+                               double d;\r
+                               double cx0=1+i_index_x[i2*2+0];\r
+                               double cx1=1+i_index_x[i2*2+1];\r
+\r
+                               double cp6_0=cpara[6]*cx0;\r
+                               double cp6_1=cpara[6]*cx1;\r
+                               double cpx0_0=cpara[0]*cx0;\r
+                               double cpx3_0=cpara[3]*cx0;\r
+                               \r
+                               d=cp6_0+cpy0_7;\r
+                               ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+                               pt++;\r
+\r
+                               d=cp6_0+cpy1_7;\r
+                               ref_x[pt]=(int)((cpx0_0+cpy1_12)/d);\r
+                               ref_y[pt]=(int)((cpx3_0+cpy1_45)/d);\r
+                               pt++;\r
+\r
+                               d=cp6_1+cpy0_7;\r
+                               ref_x[pt]=(int)((cpara[0]*cx1+cpy0_12)/d);\r
+                               ref_y[pt]=(int)((cpara[3]*cx1+cpy0_45)/d);\r
+                               pt++;\r
+\r
+                               d=cp6_1+cpy1_7;\r
+                               ref_x[pt]=(int)((cpara[0]*cx1+cpy1_12)/d);\r
+                               ref_y[pt]=(int)((cpara[3]*cx1+cpy1_45)/d);\r
+                               pt++;\r
+                       }\r
+                       //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+                       reader.getPixelSet(ref_x,ref_y,i_size*4,pixcel_temp);\r
+                       //グレースケールにしながら、line→mapへの転写\r
+                       for(int i2=0;i2<i_size;i2++){\r
+                               int index=i2*3*4;\r
+                               int pixel=(     pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+\r
+                                                       pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
+                                                       pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
+                                                       pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
+                               o_bitbuffer.setBitByBitIndex(p,pixel>i_th?1:0);\r
+                               p++;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+       \r
+       public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
+       {\r
+               if (!getParam(i_vertex,this._cparam)) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+}\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正付きのINyARColorPatt\r
+ *\r
+ */\r
+public class CopyOfNyARColorPatt_NyIdMarker implements INyARColorPatt\r
+{\r
+       private int[] _patdata;\r
+       private NyARBufferReader _buf_reader;\r
+       private NyARRgbPixelReader_INT1D_GLAY_8 _pixelreader;\r
+       private NyARIntSize _size;\r
+       PerspectivePixelReader2 _perspective_gen;\r
+       private static final int LOCAL_LT=1;\r
+       /**\r
+        * 例えば、64\r
+        * @param i_width\r
+        * 取得画像の解像度幅\r
+        * @param i_height\r
+        * 取得画像の解像度高さ\r
+        * @param i_edge_percentage\r
+        * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+        */\r
+       public CopyOfNyARColorPatt_NyIdMarker(int i_model)\r
+       {\r
+               //入力制限\r
+               assert i_model==2;\r
+               int resolution=i_model*2+1;\r
+               this._size=new NyARIntSize(resolution,resolution);\r
+               this._patdata = new int[resolution*resolution];\r
+               this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_GLAY_8);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_GLAY_8(this._patdata,this._size);\r
+               this._perspective_gen=new PerspectivePixelReader2(LOCAL_LT,LOCAL_LT,100,100);\r
+               return;\r
+       }       \r
+       \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       public final INyARBufferReader getBufferReader()\r
+       {\r
+               return this._buf_reader;\r
+       }\r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       \r
+\r
+       public int[] vertex_x=new int[49*4];\r
+       public int[] vertex_y=new int[49*4];\r
+       public int[] vertex2_x=new int[400];\r
+       public int[] vertex2_y=new int[400];\r
+       public int[] line1=new int[45];\r
+       public int[] line2=new int[45];\r
+       public int[] sv=new int[4];\r
+       private int[] temp_pixcel=new int[144];\r
+//     private NyARSingleEdgeFinder _edge_finder=new NyARSingleEdgeFinder(12,12);\r
+\r
+\r
+       /**\r
+        * マーカパラメータを格納する構造体\r
+        */\r
+       private class TMarkerParam{\r
+               int threshold;\r
+               int model;\r
+               private double[] index_x=new double[25*2];\r
+               private double[] index_y=new double[25*2];\r
+       }\r
+       /**\r
+        * 周期が等間隔か調べる。\r
+        * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなす。\r
+        * @param i_freq\r
+        * @param i_width\r
+        */\r
+       private boolean checkFreqWidth(int[] i_freq,int i_width)\r
+       {\r
+               int c=i_freq[1]-i_freq[0];\r
+               for(int i=1;i<i_width*2-1;i++){\r
+                       final int n=i_freq[i+1]-i_freq[i];\r
+                       final int v=n*100/c;\r
+                       if(v>150 || v<50){\r
+                               return false;\r
+                       }\r
+                       c=n;\r
+               }\r
+               return true;\r
+       }\r
+       private static int MIN_FREQ=3;\r
+       private static int MAX_FREQ=10;\r
+       \r
+       private int getRowFreq(int i_y,int i_th_h,int i_th_l,int[] o_freq_index)throws NyARException\r
+       {\r
+               //3,4,5,6,7,8,9,10\r
+               int freq_index1[]=new int[45];\r
+               int freq_count_table[]=new int[10];\r
+               //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列\r
+               int freq_table[][]=new int[10][20];\r
+               //初期化\r
+               \r
+               //10-20ピクセル目からタイミングパターンを検出\r
+               for(int i=i_y;i<i_y+10;i++){\r
+                       final int freq_t=this._perspective_gen.getRowFrequency(i,i_th_h,i_th_l,freq_index1);\r
+                       //周期は3-10であること\r
+                       if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+                               continue;\r
+                       }\r
+                       //周期は等間隔であること\r
+                       if(!checkFreqWidth(freq_index1,freq_t)){\r
+                               continue;\r
+                       }\r
+                       //検出カウンタを追加\r
+                       freq_count_table[freq_t]++;\r
+                       for(int i2=0;i2<freq_t*2;i2++){\r
+                               freq_table[freq_t][i2]+=freq_index1[i2];\r
+                       }\r
+               }\r
+               //一番成分の大きいものを得る\r
+               int index=-1;\r
+               int max=0;\r
+               for(int i=0;i<MAX_FREQ;i++){\r
+                       if(max<freq_count_table[i]){\r
+                               index=i;\r
+                               max=freq_count_table[i];\r
+                       }\r
+               }\r
+               /*周波数インデクスを計算*/\r
+               for(int i=0;i<index*2;i++)\r
+               {\r
+                       o_freq_index[i]=freq_table[index][i]/max;\r
+               }\r
+               return index;\r
+       }\r
+       private int getColFreq(int i_y,int i_th_h,int i_th_l,int[] o_freq_index)throws NyARException\r
+       {\r
+               //3,4,5,6,7,8,9,10\r
+               int freq_index1[]=new int[45];\r
+               int freq_count_table[]=new int[10];\r
+               int freq_table[][]=new int[10][20];\r
+               //初期化\r
+               \r
+               //10-20ピクセル目からタイミングパターンを検出\r
+               for(int i=i_y;i<i_y+10;i++){\r
+                       final int freq_t=this._perspective_gen.getColFrequency(i,i_th_h,i_th_l,freq_index1);\r
+                       //周期は3-10であること\r
+                       if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+                               continue;\r
+                       }\r
+                       //周期は等間隔であること\r
+                       if(!checkFreqWidth(freq_index1,freq_t)){\r
+                               continue;\r
+                       }\r
+                       //検出カウンタを追加\r
+                       freq_count_table[freq_t]++;\r
+                       for(int i2=0;i2<freq_t*2;i2++){\r
+                               freq_table[freq_t][i2]+=freq_index1[i2];\r
+                       }\r
+               }\r
+               //一番成分の大きいものを得る\r
+               int index=-1;\r
+               int max=0;\r
+               for(int i=0;i<MAX_FREQ;i++){\r
+                       if(max<freq_count_table[i]){\r
+                               index=i;\r
+                               max=freq_count_table[i];\r
+                       }\r
+               }\r
+               for(int i=0;i<10;i++){\r
+                       System.out.print(freq_count_table[i]+",");\r
+               }\r
+               System.out.println();\r
+               if(index==-1){\r
+                       return -1;\r
+               }\r
+               /*周波数インデクスを計算*/\r
+               for(int i=0;i<index*2;i++)\r
+               {\r
+                       o_freq_index[i]=freq_table[index][i]/max;\r
+               }\r
+               return index;\r
+       }\r
+       private boolean detectMarkerParam(INyARRgbPixelReader i_reader,TMarkerParam o_param)throws NyARException\r
+       {\r
+               TThreshold th=new TThreshold();\r
+               \r
+               detectThresholdValue(i_reader,10,10,th);\r
+               //周波数測定(最も正しい周波数を検出する)\r
+\r
+               \r
+\r
+\r
+               //左上,右下から、12x12(抽出範囲は10x10)の調査用矩形を抽出\r
+\r
+\r
+               \r
+               //周波数を測定\r
+               int freq_index1[]=new int[45];\r
+               int freq_index2[]=new int[45];\r
+               int frq_t=getRowFreq(10,th.th_h,th.th_l,freq_index1);\r
+               int frq_b=getRowFreq(80,th.th_h,th.th_l,freq_index2);\r
+               //周波数はまとも?\r
+               if((frq_t<0 && frq_b<0) || frq_t==frq_b){\r
+                       System.out.print("FRQ_R");\r
+                       return false;\r
+               }\r
+               //タイミングパターンからインデクスを作成\r
+               int freq;\r
+               int[] index;\r
+               if(frq_t>frq_b){\r
+                       freq=frq_t;\r
+                       index=freq_index1;\r
+               }else{\r
+                       freq=frq_b;\r
+                       index=freq_index2;\r
+               }\r
+               for(int i=0;i<freq*2-1;i++){\r
+                       o_param.index_x[i*2]=((index[i+1]-index[i])*2/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+                       o_param.index_x[i*2+1]=((index[i+1]-index[i])*3/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+               }\r
+               int frq_l=getColFreq(10,th.th_h,th.th_l,freq_index1);\r
+               int frq_r=getColFreq(80,th.th_h,th.th_l,freq_index2);           \r
+               //周波数はまとも?\r
+               if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
+                       System.out.print("FRQ_C");\r
+                       return false;\r
+               }\r
+               //タイミングパターンからインデクスを作成\r
+               if(frq_l>frq_r){\r
+                       freq=frq_l;\r
+                       index=freq_index1;\r
+               }else{\r
+                       freq=frq_r;\r
+                       index=freq_index2;\r
+               }\r
+               for(int i=0;i<freq*2-1;i++){\r
+                       o_param.index_y[i*2]=((index[i+1]-index[i])*2/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+                       o_param.index_y[i*2+1]=((index[i+1]-index[i])*3/5+index[i])*2+PerspectivePixelReader.FRQ_EDGE;\r
+               }\r
+\r
+               \r
+               \r
+               //Lv4以上は無理\r
+               if(freq>4){\r
+                       System.out.print("LVL_4");\r
+                       return false;\r
+               }\r
+               o_param.model=freq-1;\r
+               o_param.threshold=th.th;\r
+               return true;\r
+               \r
+       }\r
+       private class TThreshold{\r
+               public int th_h;\r
+               public int th_l;\r
+               public int th;\r
+       }\r
+       /**\r
+        * 指定した場所のピクセル値を調査して、閾値を計算して返します。\r
+        * @param i_reader\r
+        * @param i_x\r
+        * @param i_y\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       private void detectThresholdValue(INyARRgbPixelReader i_reader,int i_x,int i_y,TThreshold o_threshold)throws NyARException\r
+       {\r
+               final int[] temp_pixel=this.temp_pixcel;\r
+               //特定エリアから画素を得る\r
+               this._perspective_gen.rectPixels(i_x,i_y,10,10,temp_pixel);\r
+               //ソート\r
+               int len=100;\r
+               int h = len *13/10;\r
+               for(;;){\r
+                   int swaps = 0;\r
+                   for (int i = 0; i + h < len; i++) {\r
+                       if (temp_pixel[i + h] > temp_pixel[i]) {\r
+                           final int temp = temp_pixel[i + h];\r
+                           temp_pixel[i + h] = temp_pixel[i];\r
+                           temp_pixel[i] = temp;\r
+                           swaps++;\r
+                       }\r
+                   }\r
+                   if (h == 1) {\r
+                       if (swaps == 0){\r
+                               break;\r
+                       }\r
+                   }else{\r
+                       h=h*10/13;\r
+                   }\r
+               }\r
+               //値の大きい方と小さい方の各4点を取得\r
+               //4点の中間を閾値中心とする\r
+               final int th_l=temp_pixel[99]+temp_pixel[98]+temp_pixel[97]+temp_pixel[96];\r
+               final int th_h=temp_pixel[0]+temp_pixel[1]+temp_pixel[2]+temp_pixel[3];\r
+               int th_sub=(th_h-th_l)/(4*5);//ヒステリシス(20%)\r
+               int th=(th_h+th_l)/8;\r
+               o_threshold.th=th;\r
+               o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値\r
+               o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値\r
+               System.out.println(o_threshold.th+","+o_threshold.th_h+","+o_threshold.th_l);\r
+               return;\r
+       }       \r
+       \r
+\r
+       /**\r
+        * \r
+        * @param image\r
+        * @param i_marker\r
+        * @return 切り出しに失敗した\r
+        * @throws Exception\r
+        */\r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+       {\r
+               this._perspective_gen.setSourceRaster(image);\r
+               i_square.imvertex[0].x=149;\r
+               i_square.imvertex[0].y=179;\r
+               i_square.imvertex[0].x=27;\r
+               i_square.imvertex[0].y=96;\r
+               i_square.imvertex[0].x=152;\r
+               i_square.imvertex[0].y=29;\r
+               i_square.imvertex[0].x=280;\r
+               i_square.imvertex[0].y=72;\r
+               \r
+               //遠近法のパラメータを計算\r
+               if(!this._perspective_gen.setSourceSquare(i_square.imvertex)){\r
+                       return false;\r
+               };\r
+               \r
+               final INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+\r
+\r
+               TMarkerParam param=new TMarkerParam();\r
+               MarkerPattEncoder encoder=new MarkerPattEncoder();\r
+               //マーカパラメータを取得\r
+               if(!detectMarkerParam(reader,param))\r
+               {\r
+                       System.out.println("E");\r
+                       return false;\r
+               }               \r
+               final int resolution=(param.model*2)+1;\r
+               //Threshold検出\r
+\r
+               if(!encoder.initEncoder(param.model)){\r
+                       return false;\r
+               }\r
+               //int i_stx,int i_sty,int size_x,int size_y,int i_resolution,int i_th,\r
+               //this._perspective_gen.readDataBits(st_x,st_y,size_x,size_y,resolution, param.threshold, encoder);\r
+               this._perspective_gen.readDataBits(param.index_x,param.index_y,resolution, param.threshold, encoder);\r
+               encoder.encode();\r
+\r
+               for(int i=0;i<49*4;i++){\r
+                       this.vertex_x[i]=0;\r
+                       this.vertex_y[i]=0;\r
+               }\r
+               for(int i=0;i<resolution*2;i++){\r
+                       for(int i2=0;i2<resolution*2;i2++){\r
+                               this.vertex_x[i*resolution*2+i2]=(int)param.index_x[i2];\r
+                               this.vertex_y[i*resolution*2+i2]=(int)param.index_y[i];\r
+                               \r
+                       }\r
+               }\r
+\r
+               System.out.println(param.model);\r
+/*\r
+               //マップを作りなおす\r
+               for(int i=0;i<size*size;i++){\r
+                       this._patdata[i]=encoder.getBit(_role_table[i])==0?0:255;\r
+               }\r
+*/                     \r
+               \r
+               \r
+               return true;\r
+       }\r
+       public static void main(String[] args)\r
+       {\r
+               try {\r
+                       double[] a=new double[10];\r
+                       int[] d={\r
+                               //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9\r
+                                       0,0,0,0,0,0,0,1,5,1,2,0,0,0,1,2,5,2,1,0,\r
+                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
+                       NyARSingleEdgeFinder px=new NyARSingleEdgeFinder(20,2);\r
+                       System.out.print(px.scanEdgeLeftToRight(d,0,0,a));\r
+                       System.out.print("");\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }       \r
+}
\ No newline at end of file
index 785ba68..fafe75d 100644 (file)
@@ -553,7 +553,7 @@ class NyARQRCodeDetector implements INyARSquareDetector
                }
 
                final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
-               final NyARIntPoint[] l_imvertex = o_square.imvertex;
+               final NyARIntPoint2d[] 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];
diff --git a/trunk/test/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java b/trunk/test/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java
new file mode 100644 (file)
index 0000000..0bd3f73
--- /dev/null
@@ -0,0 +1,667 @@
+/* \r
+ * PROJECT: NyARToolkit\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.dev;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+\r
+\r
+class NyARDoubleLine2d\r
+{\r
+       double x,y;\r
+       void set(NyARDoublePoint2d i_point_a,NyARDoublePoint2d i_point_b)\r
+       {\r
+               this.x=i_point_a.x-i_point_b.x;\r
+               this.y=i_point_a.y-i_point_b.y;\r
+               return;\r
+       }\r
+       void add(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result)\r
+       {\r
+               o_result.x=this.x+i_param.x;\r
+               o_result.y=this.y+i_param.y;\r
+               return;\r
+       }\r
+       void sum(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result)\r
+       {\r
+               o_result.x=this.x-i_param.x;\r
+               o_result.y=this.y-i_param.y;\r
+               return;\r
+       }\r
+       /**\r
+        * i_paramとの外積を計算する。\r
+        * @param i_param\r
+        * @return\r
+        */\r
+       double cross(NyARDoubleLine2d i_param)\r
+       {\r
+               return this.x*i_param.y-this.y*i_param.x;\r
+       }\r
+       /**\r
+        * i_paramとの内積を計算する\r
+        * @param i_param\r
+        * @return\r
+        */\r
+       double dot(NyARDoubleLine2d i_param)\r
+       {\r
+               return this.x*i_param.x+this.y*i_param.y;\r
+       }\r
+       /**\r
+        * このベクトルの絶対値を計算する\r
+        * @param i_param\r
+        * @return\r
+        */\r
+       double dist()\r
+       {\r
+               return Math.sqrt(this.x*this.x+this.y*this.y);\r
+       }\r
+       \r
+       \r
+}\r
+\r
+\r
+class LineParam\r
+{\r
+       public double a;\r
+       public double b;\r
+       public static LineParam[] createArray(int i_length)\r
+       {\r
+               LineParam[] result=new LineParam[i_length];\r
+               for(int i=result.length-1;i>=0;i--){\r
+                       result[i]=new LineParam();\r
+               }\r
+               return result;\r
+       }\r
+}\r
+\r
+class Complex\r
+{\r
+       public double i;\r
+       public double r;\r
+       public Complex()\r
+       {\r
+       }\r
+       public Complex(double i_r,double i_i)\r
+       {\r
+               this.r=i_r;\r
+               this.i=i_i;\r
+       }\r
+       public void add(Complex i_v)\r
+       {\r
+               this.r+=i_v.r;\r
+               this.i+=i_v.i;\r
+       }\r
+       public void sub(Complex i_v)\r
+       {\r
+               this.r-=i_v.r;\r
+               this.i-=i_v.i;\r
+       }\r
+       public void sub(Complex i_v1,Complex i_v2)\r
+       {\r
+               this.r=i_v1.r-i_v2.r;\r
+               this.i=i_v1.i-i_v2.i;\r
+       }\r
+       \r
+       public void mul(Complex i_v)\r
+       {\r
+               double r,i;\r
+               r=this.r;\r
+               i=this.i;\r
+               final double d2=Math.sqrt(r*r+i*i);\r
+               final double s2=Math.acos(r/d2);\r
+               r=i_v.r;\r
+               i=i_v.i;\r
+               final double d1=Math.sqrt(r*r+i*i);\r
+               final double s1=Math.acos(r/d1);\r
+               \r
+               this.r=d1*d2*Math.cos(s2+s1);\r
+               this.i=d1*d2*Math.sin(s2+s1);\r
+               return;\r
+       }\r
+       public void div(Complex i_v)\r
+       {\r
+               double r,i;\r
+               r=this.r;\r
+               i=this.i;\r
+               final double d2=Math.sqrt(r*r+i*i);\r
+               final double s2=Math.acos(r/d2);\r
+               r=i_v.r;\r
+               i=i_v.i;\r
+               final double d1=Math.sqrt(r*r+i*i);\r
+               final double s1=Math.acos(r/d1);\r
+               \r
+               this.r=d2/d1*Math.cos(s2/s1);\r
+               this.i=d2/d1*Math.sin(s2/s1);\r
+               return;\r
+       }\r
+       public void pow(Complex i_v,double i_base)\r
+       {\r
+               double r,i;\r
+               r=i_v.r;\r
+               i=i_v.i;\r
+               double d=Math.sqrt(r*r+i*i);\r
+               final double s=Math.acos(r/d)*i_base;\r
+               d=Math.pow(d,i_base);\r
+               this.r=d*Math.cos(s);\r
+               this.i=d*Math.sin(s);\r
+       }\r
+       public void sqrt(Complex i_v)\r
+       {\r
+               double r,i;\r
+               r=i_v.r;\r
+               i=i_v.i;\r
+               double d=Math.sqrt(r*r+i*i);\r
+               final double s=Math.acos(r/d)*0.5;\r
+               d=Math.sqrt(d);\r
+               this.r=d*Math.cos(s);\r
+               this.i=d*Math.sin(s);\r
+       }\r
+       public double dist()\r
+       {\r
+               return Math.sqrt(this.r*this.r+this.i*this.i);\r
+       }\r
+       \r
+}\r
+\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_DiagonalRatio implements INyARColorPatt\r
+{\r
+       private int[] _patdata;\r
+       private NyARBufferReader _buf_reader;\r
+       private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+       private NyARIntSize _size;\r
+               \r
+       public final int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+       \r
+       public final int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+       \r
+       public final NyARIntSize getSize()\r
+       {\r
+               return  this._size;\r
+       }\r
+       \r
+       public final INyARBufferReader getBufferReader()\r
+       {\r
+               return this._buf_reader;\r
+       }\r
+       \r
+       public final INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._pixelreader;\r
+       }\r
+       NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+       /**\r
+        * @param i_width\r
+        * @param i_height\r
+        */\r
+       public NyARColorPatt_DiagonalRatio(int i_model)\r
+       {\r
+               int resolution=(1<<i_model)+1;\r
+               this._size=new NyARIntSize(resolution,resolution);\r
+               this._patdata = new int[resolution*resolution];\r
+               this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+               this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+               \r
+               this._vertex_map=NyARDoublePoint2d.create2dArray(this._size.h,this._size.w);\r
+\r
+               return;\r
+       }       \r
+       public NyARDoublePoint2d[][] _vertex_map;\r
+       public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+       {\r
+               NyARDoublePoint2d center=new NyARDoublePoint2d();\r
+               //中心を取得\r
+               solvCrossPoint(i_square.sqvertex[0],i_square.sqvertex[2],i_square.sqvertex[1],i_square.sqvertex[3],center);\r
+               \r
+               int[] rgb_tmp=new int[3];\r
+               INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+               //頂点マトリクスの計算(2=2分割,3=4分割,4=8分割)\r
+               NyARDoublePoint2d[][] vertex_map=this._vertex_map;\r
+               solvLinePointArray(center,this._size.h-1,i_square.sqvertex,vertex_map);\r
+               for(int i=0;i<this._size.h;i++){\r
+                       for(int i2=0;i2<this._size.w;i2++){\r
+                               if(vertex_map[i][i2].x>320||vertex_map[i][i2].y>240||vertex_map[i][i2].x<0||vertex_map[i][i2].y<0)\r
+                               {\r
+                                       //System.out.println(vertex_map[i][i2].x+","+vertex_map[i][i2].y);\r
+                                       this._patdata[i2+i*this._size.w]=0;\r
+                                       continue;\r
+                               }\r
+                               reader.getPixel((int)vertex_map[i][i2].x,(int)vertex_map[i][i2].y,rgb_tmp);\r
+                               this._patdata[i2+i*this._size.w]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2];                           \r
+                       }                       \r
+               }\r
+               return true;\r
+       }\r
+       /**\r
+        * 直線をscaleで2^n分割した配列を計算する。\r
+        * @param i_p1\r
+        * @param i_p2\r
+        * @param o_param\r
+        * @return\r
+        */\r
+       private void solvLinePointArray4(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+       {\r
+               //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+               //中心コピー\r
+               o_result[0][0].setValue(i_center);\r
+               \r
+               \r
+               //[0]->[1]のベクトルを計算\r
+               NyARDoublePoint2d vec01=new NyARDoublePoint2d();\r
+               NyARDoublePoint2d vec12=new NyARDoublePoint2d();\r
+               NyARDoublePoint2d vec03=new NyARDoublePoint2d();\r
+               NyARDoublePoint2d vec32=new NyARDoublePoint2d();\r
+               vec01.vecSub(i_vertex[1],i_vertex[0]);\r
+               vec12.vecSub(i_vertex[2],i_vertex[1]);\r
+               vec03.vecSub(i_vertex[3],i_vertex[0]);\r
+               vec32.vecSub(i_vertex[2],i_vertex[3]);\r
+\r
+               //中心点から[0]->[1]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d();\r
+               vec01_ep.vecAdd(vec01,i_center);\r
+               //中心点から[3]->[2]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d();\r
+               vec32_ep.vecAdd(vec32,i_center);                \r
+               //平均値\r
+               NyARDoublePoint2d cx_e=new NyARDoublePoint2d();\r
+               cx_e.x=(vec01_ep.x+vec32_ep.x)/2;\r
+               cx_e.y=(vec01_ep.y+vec32_ep.y)/2;\r
+               \r
+               //ベクトル[1]->[2]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]);\r
+               //ベクトル[3]->[0]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]);\r
+               \r
+\r
+               \r
+               //中心点から[1]->[2]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d();\r
+               vec12_ep.vecAdd(vec12,i_center);\r
+               //中心点から[0]->[3]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d();\r
+               vec03_ep.vecAdd(vec03,i_center);                \r
+               //平均値\r
+               NyARDoublePoint2d cx_e2=new NyARDoublePoint2d();\r
+               cx_e2.x=(vec12_ep.x+vec03_ep.x)/2;\r
+               cx_e2.y=(vec12_ep.y+vec03_ep.y)/2;\r
+               \r
+               //cx_e2とベクトル[0]->[1]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]);\r
+               //ベクトル[3]->[2]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]);\r
+               \r
+               \r
+               \r
+               \r
+               return;\r
+       }\r
+       private void solvLinePointArray(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+       {\r
+               //中心コピー\r
+               o_result[0][0].setValue(i_center);\r
+\r
+               //[0]+[1]+[c]\r
+               NyARDoublePoint2d vt=new NyARDoublePoint2d();\r
+               vt.x=(i_vertex[0].x+i_vertex[1].x)/2;\r
+               vt.y=(i_vertex[0].y+i_vertex[1].y)/2;\r
+               //[2]+[3]+[c]\r
+               NyARDoublePoint2d vb=new NyARDoublePoint2d();\r
+               vb.x=(i_vertex[2].x+i_vertex[3].x)/2;\r
+               vb.y=(i_vertex[2].y+i_vertex[3].y)/2;\r
+               \r
+               vt.vecSub(vb);\r
+               vt.vecAdd(i_center);\r
+\r
+               //[0][1]->[2][3]ベクトル\r
+               solvCrossPoint(vt,i_center,i_vertex[0],i_vertex[1],o_result[1][2]);\r
+               //[0][1]->[2][3]ベクトル:v[3][0]\r
+               solvCrossPoint(vt,i_center,i_vertex[3],i_vertex[2],o_result[1][0]);\r
+\r
+               \r
+               \r
+/*             \r
+               \r
+               //[0]->[1]のベクトルを計算\r
+               NyARDoublePoint2d vec01=new NyARDoublePoint2d();\r
+               NyARDoublePoint2d vec12=new NyARDoublePoint2d();\r
+               NyARDoublePoint2d vec03=new NyARDoublePoint2d();\r
+               NyARDoublePoint2d vec32=new NyARDoublePoint2d();\r
+               vec01.vecSub(i_vertex[1],i_vertex[0]);\r
+               vec12.vecSub(i_vertex[2],i_vertex[1]);\r
+               vec03.vecSub(i_vertex[3],i_vertex[0]);\r
+               vec32.vecSub(i_vertex[2],i_vertex[3]);\r
+\r
+               //中心点から[0]->[1]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d();\r
+               vec01_ep.vecSum(vec01,i_center);\r
+               //中心点から[3]->[2]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d();\r
+               vec32_ep.vecSum(vec32,i_center);                \r
+               //平均値\r
+               NyARDoublePoint2d cx_e=new NyARDoublePoint2d();\r
+               cx_e.x=(vec01_ep.x+vec32_ep.x)/2;\r
+               cx_e.y=(vec01_ep.y+vec32_ep.y)/2;\r
+               \r
+               //ベクトル[1]->[2]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]);\r
+               //ベクトル[3]->[0]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]);\r
+               \r
+\r
+               \r
+               //中心点から[1]->[2]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d();\r
+               vec12_ep.vecSum(vec12,i_center);\r
+               //中心点から[0]->[3]と平行なベクトルの終点を計算\r
+               NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d();\r
+               vec03_ep.vecSum(vec03,i_center);                \r
+               //平均値\r
+               NyARDoublePoint2d cx_e2=new NyARDoublePoint2d();\r
+               cx_e2.x=(vec12_ep.x+vec03_ep.x)/2;\r
+               cx_e2.y=(vec12_ep.y+vec03_ep.y)/2;\r
+               \r
+               //cx_e2とベクトル[0]->[1]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]);\r
+               //ベクトル[3]->[2]との交差点を計算\r
+               solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]);\r
+               \r
+               \r
+*/             \r
+               \r
+               return;\r
+       }\r
+       \r
+       \r
+       \r
+       private void solvLinePointArray3(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+       {\r
+               NyARDoublePoint2d scale=new NyARDoublePoint2d();\r
+               //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+               int d=i_div;\r
+               NyARDoublePoint2d[] r=o_result[d/2];\r
+               //対角線Aを計算\r
+               r[0].x=i_vertex[0].x;\r
+               r[0].y=i_vertex[0].y;\r
+               r[d].x=i_vertex[2].x;\r
+               r[d].y=i_vertex[2].y;\r
+               scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x);\r
+               scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y);\r
+\r
+               solvLinePointArray_b(scale,0,d,r);\r
+               //対角線上にコピー\r
+               for(int i=0;i<=d;i++){\r
+                       o_result[i][i].x=r[i].x;        \r
+                       o_result[i][i].y=r[i].y;\r
+               }\r
+               //対角線Bを計算\r
+               r[0].x=i_vertex[3].x;\r
+               r[0].y=i_vertex[3].y;\r
+               r[d].x=i_vertex[1].x;\r
+               r[d].y=i_vertex[1].y;\r
+               scale.x=(i_canter.x-i_vertex[3].x)/(i_vertex[1].x-i_vertex[3].x);\r
+               scale.y=(i_canter.y-i_vertex[3].y)/(i_vertex[1].y-i_vertex[3].y);\r
+               solvLinePointArray_b(scale,0,d,r);\r
+               //対角線上にコピー\r
+               for(int i=0;i<=d;i++){\r
+                       o_result[d-i][i].x=r[i].x;\r
+                       o_result[d-i][i].y=r[i].y;\r
+               }\r
+               //マップ作成\r
+               for(int i=0;i<=d;i++){\r
+                       final NyARDoublePoint2d y1=o_result[i][i];\r
+                       final NyARDoublePoint2d y2=o_result[d-i][i];\r
+                       if(i==d/2){\r
+                               continue;\r
+                       }\r
+                       for(int i2=0;i2<=d;i2++){\r
+                               if(i==i2){\r
+                                       continue;\r
+                               }\r
+                               if(i==d-i2){\r
+                                       continue;\r
+                               }\r
+                               if(i2==d/2){\r
+                                       continue;\r
+                               }\r
+                               final NyARDoublePoint2d x1=o_result[i2][i2];\r
+                               final NyARDoublePoint2d x2=o_result[i2][d-i2];\r
+                               solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]);\r
+                       }\r
+               }\r
+\r
+               return;\r
+       }       \r
+       /**\r
+        * 直線をscaleで2^n分割した配列を計算する。\r
+        * @param i_p1\r
+        * @param i_p2\r
+        * @param o_param\r
+        * @return\r
+        */\r
+       private void solvLinePointArray2(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+       {\r
+               NyARDoublePoint2d scale=new NyARDoublePoint2d();\r
+               //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+               int d=i_div;\r
+               NyARDoublePoint2d[] r=o_result[d/2];\r
+               //対角線Aを計算\r
+               r[0].x=i_vertex[0].x;\r
+               r[0].y=i_vertex[0].y;\r
+               r[d].x=i_vertex[2].x;\r
+               r[d].y=i_vertex[2].y;\r
+//             scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x);\r
+//             scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y);\r
+               double sx,kx,lx,sy,ky,ly;\r
+\r
+               sx=i_vertex[0].x;\r
+               kx=solvK(i_canter.x-sx,i_vertex[2].x-sx);\r
+               lx=solvL(kx,i_canter.x-sx);\r
+\r
+               sy=i_vertex[0].y;\r
+               ky=solvK(i_canter.y-sy,i_vertex[2].y-sy);\r
+               ly=solvL(kx,i_canter.y-sy);\r
+               \r
+               solvLinePointArray_b(scale,0,d,r);\r
+               //対角線上にコピー\r
+               for(int i=0;i<=d;i++){\r
+                       o_result[i][i].x=sx+kx*lx;\r
+                       o_result[i][i].y=sy+ky*ly;\r
+                       kx*=kx;\r
+                       ky*=ky;\r
+               }\r
+               \r
+               sx=i_vertex[3].x;\r
+               kx=solvK(i_canter.x-sx,i_vertex[1].x-sx);\r
+               lx=solvL(kx,i_canter.x-sx);\r
+\r
+               sy=i_vertex[3].y;\r
+               ky=solvK(i_canter.y-sy,i_vertex[1].y-sy);\r
+               ly=solvL(kx,i_canter.y-sy);\r
+               \r
+               solvLinePointArray_b(scale,0,d,r);\r
+               //対角線上にコピー\r
+               for(int i=0;i<=d;i++){\r
+                       o_result[d-i][i].x=sx+kx*lx;\r
+                       o_result[d-i][i].y=sy+ky*ly;\r
+                       kx*=kx;\r
+                       ky*=ky;\r
+               }\r
+               //マップ作成\r
+               for(int i=0;i<=d;i++){\r
+                       final NyARDoublePoint2d y1=o_result[i][i];\r
+                       final NyARDoublePoint2d y2=o_result[d-i][i];\r
+                       if(i==d/2){\r
+                               continue;\r
+                       }\r
+                       for(int i2=0;i2<=d;i2++){\r
+                               if(i==i2){\r
+                                       continue;\r
+                               }\r
+                               if(i==d-i2){\r
+                                       continue;\r
+                               }\r
+                               if(i2==d/2){\r
+                                       continue;\r
+                               }\r
+                               final NyARDoublePoint2d x1=o_result[i2][i2];\r
+                               final NyARDoublePoint2d x2=o_result[i2][d-i2];\r
+                               solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]);\r
+                       }\r
+               }\r
+\r
+               return;\r
+       }       \r
+\r
+       private void solvLinePointArray_b(NyARDoublePoint2d i_scale,int i_si,int i_ei,NyARDoublePoint2d[] o_result)\r
+       {\r
+               int ci=(i_ei-i_si)/2+i_si;\r
+               o_result[ci].x=i_scale.x*(o_result[i_ei].x-o_result[i_si].x)+o_result[i_si].x;\r
+               o_result[ci].y=i_scale.y*(o_result[i_ei].y-o_result[i_si].y)+o_result[i_si].y;\r
+               \r
+               if(ci-i_si==1){\r
+                       return;\r
+               }\r
+               solvLinePointArray_b(i_scale,i_si,ci,o_result);\r
+               solvLinePointArray_b(i_scale,ci,i_ei,o_result);\r
+               return;\r
+       }\r
+       \r
+       private void solvCrossPoint(NyARIntPoint2d i_p1,NyARIntPoint2d i_p2,NyARIntPoint2d i_p3,NyARIntPoint2d i_p4,NyARDoublePoint2d o_result)\r
+       {\r
+               NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2);\r
+               NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4);\r
+               va.vecSub(i_p1);\r
+               vb.vecSub(i_p3);\r
+               o_result.setValue(i_p3);\r
+               o_result.vecSub(i_p1);\r
+               va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va));\r
+               o_result.setValue(va);\r
+               o_result.vecAdd(i_p1);\r
+               return;\r
+               //V a=p2-p1;\r
+               //V b=p4-p3;\r
+               //return a1 + a * cross(b, b1-a1) / cross(b, a);\r
+       }\r
+       private void solvCrossPoint(NyARDoublePoint2d i_p1,NyARDoublePoint2d i_p2,NyARDoublePoint2d i_p3,NyARDoublePoint2d i_p4,NyARDoublePoint2d o_result)\r
+       {\r
+               NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2);\r
+               NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4);\r
+               va.vecSub(i_p1);\r
+               vb.vecSub(i_p3);\r
+               o_result.setValue(i_p3);\r
+               o_result.vecSub(i_p1);\r
+               va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va));\r
+               o_result.setValue(va);\r
+               o_result.vecAdd(i_p1);\r
+               return;\r
+               //V a=p2-p1;\r
+               //V b=p4-p3;\r
+               //return a1 + a * cross(b, b1-a1) / cross(b, a);\r
+       }       \r
+       double pow_1_3(double a)\r
+       {\r
+               double x = Math.pow(a, 1./3);\r
+               return (2*x+a/x/x)/3; // modifier\r
+       }\r
+       /*\r
+        * \r
+        * \r
+        * */\r
+       //(Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))-(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z))^(1/3)+(-((Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z)+Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))))^(1/3)-Z/(3*Z)\r
+       private double solvK(double mp,double vp)\r
+       {\r
+               double Z=mp/vp;\r
+               double a=(Z-1);\r
+               double b=(3.0*Z);\r
+               double c=(a*Z);\r
+               double d=(2.0*Z*Z);//(2*Z^2)\r
+               double e=(4.0*Z*Z);//(4*Z^2)\r
+               double f=((-Z)/b);\r
+               double g=(Z*f*f+Z*f*f*f-c/b+Z-1);//(Z*f^2+Z*f^3-c/b+Z-1)\r
+               double h=(3.0*Z*f*f-d/b+Z-1.0);//(3*Z*f^2-d/b+Z-1)\r
+               double i=(h/Z);\r
+               Complex j=new Complex(0,i*i*i/27.0+g*g/e);//(0,i*i*i/27.0+g*g/e);\r
+//             j.r=0;\r
+//             j.i=Math.sqrt(-i*i*i/27.0+g*g/e);\r
+//             j.sqrt(j);\r
+               Complex k=new Complex();\r
+               k.r=j.r-g/(2.0*Z);\r
+               k.i=j.i;\r
+               Complex l=new Complex();\r
+               l.r=-(g/(2.0*Z)+j.r);\r
+               l.i=-j.i;\r
+               \r
+               k.pow(k,1.0/3);\r
+               l.pow(l,1.0/3);\r
+               double fi=k.dist()+l.dist()-Z/b;\r
+               return fi;\r
+       }\r
+       private double solvL(double k,double mp)\r
+       {\r
+               return 100/(1+k*k+k*k*k+k);\r
+       }\r
+       \r
+       \r
+       public static void main(String[] args)\r
+       {\r
+\r
+               try {\r
+                       NyARColorPatt_DiagonalRatio t = new NyARColorPatt_DiagonalRatio(3);\r
+                       double k=t.solvK(60,100);\r
+                       double l=t.solvL(k,60);\r
+                       \r
+                       // t.Test_arGetVersion();\r
+                       NyARSquare s=new NyARSquare();\r
+                       s.sqvertex[0].x=10;\r
+                       s.sqvertex[0].y=10;\r
+                       s.sqvertex[1].x=90;\r
+                       s.sqvertex[1].y=0;\r
+                       s.sqvertex[2].x=100;\r
+                       s.sqvertex[2].y=100;\r
+                       s.sqvertex[3].x=0;\r
+                       s.sqvertex[3].y=100;\r
+                       //t.getLineCrossPoint(s);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/trunk/test/jp/nyatla/nyartoolkit/dev/PattPickupTest.java b/trunk/test/jp/nyatla/nyartoolkit/dev/PattPickupTest.java
new file mode 100644 (file)
index 0000000..7442139
--- /dev/null
@@ -0,0 +1,222 @@
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.Color;\r
+import java.awt.Frame;\r
+import java.awt.Graphics;\r
+import java.awt.Image;\r
+import java.awt.Insets;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.format.VideoFormat;\r
+import javax.media.util.BufferToImage;\r
+import java.awt.image.*;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyARIdMarkerPickup;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.utils.j2se.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+\r
+public class PattPickupTest extends Frame implements JmfCaptureListener\r
+{\r
+       private final String PARAM_FILE = "../Data/camera_para.dat";\r
+\r
+       private static final long serialVersionUID = -2110888320986446576L;\r
+\r
+       private JmfCaptureDevice _capture;\r
+\r
+       private JmfNyARRaster_RGB _capraster;\r
+\r
+       private NyARSquareDetector _detector;\r
+\r
+       protected INyARRasterFilter_RgbToBin _tobin_filter;\r
+\r
+       private NyARBinRaster _bin_raster;\r
+\r
+       private NyARSquareStack _stack = new NyARSquareStack(100);\r
+\r
+       public PattPickupTest() throws NyARException\r
+       {\r
+               setTitle("JmfCaptureTest");\r
+               Insets ins = this.getInsets();\r
+               this.setSize(640 + ins.left + ins.right, 480 + ins.top + ins.bottom);\r
+               JmfCaptureDeviceList dl = new JmfCaptureDeviceList();\r
+               this._capture = dl.getDevice(0);\r
+               if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB, 320, 240, 30.0f)) {\r
+                       if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV, 320, 240, 30.0f)) {\r
+                               throw new NyARException("キャプチャフォーマットが見つかりません。");\r
+                       }\r
+               }\r
+               NyARParam ar_param = new NyARParam();\r
+               ar_param.loadARParamFromFile(PARAM_FILE);\r
+               ar_param.changeScreenSize(320, 240);\r
+               this._capraster = new JmfNyARRaster_RGB(320, 240, this._capture.getCaptureFormat());\r
+               this._capture.setOnCapture(this);\r
+               this._detector = new NyARSquareDetector(ar_param.getDistortionFactor(), ar_param.getScreenSize());\r
+               this._bin_raster = new NyARBinRaster(320, 240);\r
+               this._tobin_filter = new NyARRasterFilter_ARToolkitThreshold(110);\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * 矩形の矩形っぽい点数を返す。\r
+        * \r
+        * @param i_sq\r
+        * @return\r
+        */\r
+       private int getSQPoint(NyARSquare i_sq)\r
+       {\r
+               int lx1 = i_sq.imvertex[0].x - i_sq.imvertex[2].x;\r
+               int ly1 = i_sq.imvertex[0].y - i_sq.imvertex[2].y;\r
+               int lx2 = i_sq.imvertex[1].x - i_sq.imvertex[3].x;\r
+               int ly2 = i_sq.imvertex[1].y - i_sq.imvertex[3].y;\r
+               return (int) Math.sqrt((lx1 * lx1) + (ly1 * ly1)) * (int) Math.sqrt(((lx2 * lx2) + (ly2 * ly2)));\r
+       }\r
+\r
+       private INyARColorPatt _patt1 = new NyARColorPatt_O3(64, 64);\r
+\r
+       private INyARColorPatt _patt2 = new NyARColorPatt_Perspective(100,100);\r
+\r
+       private NyARIdMarkerPickup _patt3 = new NyARIdMarkerPickup();\r
+\r
+       public void onUpdateBuffer(Buffer i_buffer)\r
+       {\r
+               try {\r
+                       Insets ins = this.getInsets();\r
+                       Graphics g = getGraphics();\r
+\r
+                       {// ピックアップ画像の表示\r
+                               // 矩形抽出\r
+                               this._capraster.setBuffer(i_buffer);\r
+                               this._tobin_filter.doFilter(this._capraster, this._bin_raster);\r
+                               this._detector.detectMarker(this._bin_raster, this._stack);\r
+\r
+                               int max_point = 0;\r
+                               NyARSquare t = null;\r
+                               // ど れ に し よ う か なー\r
+                               for (int i = this._stack.getLength() - 1; i >= 0; i--) {\r
+                                       NyARSquare sq = (NyARSquare) this._stack.getItem(i);\r
+                                       int wp = getSQPoint(sq);\r
+                                       if (wp < max_point) {\r
+                                               continue;\r
+                                       }\r
+                                       t = sq;\r
+                               }\r
+                               if (t != null) {\r
+\r
+                                       BufferedImageSink sink = new BufferedImageSink(this._patt1.getWidth(), this._patt1.getHeight());\r
+                                       BufferedImageSink sink2 = new BufferedImageSink(this._patt2.getWidth(), this._patt2.getHeight());\r
+//                                     BufferedImageSink sink3 = new BufferedImageSink(this._patt3.getWidth(), this._patt3.getHeight());\r
+                                       Graphics g1,g2,g3;\r
+                                       {// ARToolkit\r
+                                               // 一番それっぽいパターンを取得\r
+                                               this._patt1.pickFromRaster(this._capraster, t);\r
+                                               // パターンを書く\r
+                                               sink.sinkFromRaster(this._patt1);\r
+                                               g1=sink.getGraphics();\r
+                                               g1.setColor(Color.red);\r
+                                               g1.drawLine(this._patt1.getWidth()/2,0,this._patt1.getWidth()/2,this._patt1.getHeight());\r
+                                               g1.drawLine(0,this._patt1.getHeight()/2,this._patt1.getWidth(),this._patt1.getHeight()/2);\r
+                                       }\r
+                                       {// 疑似アフィン変換\r
+                                               // 一番それっぽいパターンを取得\r
+                                               this._patt2.pickFromRaster(this._capraster, t);\r
+                                               // パターンを書く\r
+                                               sink2.sinkFromRaster(this._patt2);\r
+                                               g2=sink2.getGraphics();\r
+                                               g2.setColor(Color.red);\r
+                                               g2.drawLine(this._patt1.getWidth()/2,0,this._patt1.getWidth()/2,this._patt1.getHeight());\r
+                                               g2.drawLine(0,this._patt1.getHeight()/2,this._patt1.getWidth(),this._patt1.getHeight()/2);\r
+                                       }\r
+                                       {// IDマーカ\r
+                                               NyARIdMarkerData data =new NyARIdMarkerData();\r
+                                               NyARIdMarkerParam param =new NyARIdMarkerParam();\r
+                                               \r
+                                               // 一番それっぽいパターンを取得\r
+                                               this._patt3.pickFromRaster(this._capraster, t,data,param);\r
+                                               System.out.println("model="+data.model);\r
+                                               System.out.println("domain="+data.ctrl_domain);\r
+                                               System.out.println("maskl="+data.ctrl_mask);\r
+                                               System.out.println("data= "+data.data[0]+","+data.data[1]+","+data.data[2]);\r
+                                               // パターンを書く\r
+/*                                             sink3.sinkFromRaster(this._patt3);\r
+                                               g3=sink.getGraphics();\r
+                                               g3.setColor(Color.red);\r
+                                               g2.drawRect(10,10,10,10);\r
+                                               g2.drawRect(80,10,10,10);\r
+                                               g2.drawRect(10,80,10,10);\r
+                                               g2.drawRect(80,80,10,10);*/\r
+//                                             g2.drawLine(this._patt3.sv[0]-1,this._patt3.sv[1],this._patt3.sv[0]+1,this._patt3.sv[1]);\r
+//                                             g2.drawLine(this._patt3.sv[0],this._patt3.sv[1]-1,this._patt3.sv[0],this._patt3.sv[1]+1);\r
+//                                             g2.drawLine(this._patt3.sv[2]-1,this._patt3.sv[3],this._patt3.sv[2]+1,this._patt3.sv[3]);\r
+//                                             g2.drawLine(this._patt3.sv[2],this._patt3.sv[3]-1,this._patt3.sv[2],this._patt3.sv[3]+1);\r
+                                               \r
+                                               BufferedImage img=new BufferedImage(45,256,     BufferedImage.TYPE_INT_RGB);\r
+\r
+                                               g.drawImage(img, ins.left, ins.top+240,45,256, null);\r
+/*\r
+                                               g2.setColor(Color.blue);\r
+                                               for (int i = 0; i < 225*4; i++) {\r
+                                                       g2.drawRect(this._patt3.vertex_x[i]-1,this._patt3.vertex_y[i]-1, 2, 2);\r
+                                               }\r
+*/                                             g2.setColor(Color.red);\r
+                                               for (int i = 0; i <4; i++) {\r
+                                                       g2.drawRect(this._patt3.vertex2_x[i]-1,this._patt3.vertex2_y[i]-1, 2, 2);\r
+                                               }\r
+                                       }\r
+                                       g.drawImage(sink, ins.left + 320, ins.top, 128, 128, null);\r
+                                       g.drawImage(sink2, ins.left + 320, ins.top + 128, 400, 400, null);\r
+//                                     g.drawImage(sink3, ins.left + 100, ins.top + 240, this._patt3.getWidth() * 10, this._patt3.getHeight() * 10, null);\r
+                               }\r
+\r
+                               {// 撮影画像\r
+                                       BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());\r
+                                       Image img = b2i.createImage(i_buffer);\r
+                                       g.drawImage(img, ins.left, ins.top, this);\r
+                                       g.setColor(Color.blue);\r
+                                       for (int i = 0; i < 225*4; i++) {\r
+                                               g.drawRect(ins.left+this._patt3.vertex_x[i]-1,ins.top+this._patt3.vertex_y[i]-1, 2, 2);\r
+                                       }\r
+                               \r
+                               }\r
+                               /*\r
+                                * { //輪郭パターン NyARSquare s=new NyARSquare(); for(int i=0;i<4;i++){ s.imvertex[i].x=(int)t.sqvertex[i].x; s.imvertex[i].y=(int)t.sqvertex[i].y; }\r
+                                * //一番それっぽいパターンを取得 this._patt1.pickFromRaster(this._capraster,s); //パターンを書く BufferedImageSink sink=new\r
+                                * BufferedImageSink(this._patt1.getWidth(),this._patt1.getHeight()); sink.sinkFromRaster(this._patt1);\r
+                                * g.drawImage(sink,ins.left+320,ins.top+128,128,128,null); }\r
+                                */\r
+                               {// 信号取得テスト\r
+\r
+                               }\r
+                       }\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public void startCapture()\r
+       {\r
+               try {\r
+                       this._capture.start();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public static void main(String[] args)\r
+       {\r
+               try {\r
+                       PattPickupTest mainwin = new PattPickupTest();\r
+                       mainwin.setVisible(true);\r
+                       mainwin.startCapture();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/trunk/test/jp/nyatla/nyartoolkit/dev/Solver.java b/trunk/test/jp/nyatla/nyartoolkit/dev/Solver.java
new file mode 100644 (file)
index 0000000..a063c6a
--- /dev/null
@@ -0,0 +1,144 @@
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+\r
+\r
+public class Solver\r
+{\r
+       public String[][] _data=new String[4][6];\r
+       public String[] _temp=new String[6];\r
+       public Solver()\r
+       {\r
+               this._data[0][0]="a";\r
+               this._data[0][1]="b";\r
+               this._data[0][2]="c";\r
+               this._data[0][3]="d";\r
+               this._data[0][4]="e";\r
+               this._data[0][5]="1";\r
+               \r
+               this._data[1][0]="f";\r
+               this._data[1][1]="g";\r
+               this._data[1][2]="h";\r
+               this._data[1][3]="i";\r
+               this._data[1][4]="j";\r
+               this._data[1][5]="1";\r
+               \r
+               this._data[2][0]="k";\r
+               this._data[2][1]="l";\r
+               this._data[2][2]="m";\r
+               this._data[2][3]="n";\r
+               this._data[2][4]="o";\r
+               this._data[2][5]="1";\r
+\r
+               this._data[3][0]="p";\r
+               this._data[3][1]="q";\r
+               this._data[3][2]="r";\r
+               this._data[3][3]="s";\r
+               this._data[3][4]="t";\r
+               this._data[3][5]="1";\r
+       }\r
+       public void dump()\r
+       {\r
+               for(int i=0;i<this._data.length;i++){\r
+                       for(int i2=0;i2<this._data[i].length;i2++){\r
+                               System.out.print(this._data[i][i2]+" , ");\r
+                       }                       \r
+                       System.out.println(" ");\r
+               }\r
+       }\r
+       public boolean isSingle(String i_str)\r
+       {\r
+               int c=0;\r
+               for(int i=0;i<i_str.length();i++){\r
+                       if(i_str.charAt(i)=='('){\r
+                               c++;\r
+                       }\r
+                       if(i_str.charAt(i)==')'){\r
+                               c--;\r
+                               if(c==0 && i!=i_str.length()-1){\r
+                                       return false;//括弧必要\r
+                               }\r
+                       }\r
+               }\r
+               return true;//括弧不要\r
+       }\r
+       \r
+       public void div(int i_r,String i_e,String[] o_row) throws Exception\r
+       {\r
+               if(i_e=="0"){\r
+                       throw new Exception();                  \r
+               }else if(i_e=="1"){\r
+                       return;\r
+               }\r
+               String[] l=this._data[i_r];\r
+               for(int i=0;i<o_row.length;i++){\r
+                       if(l[i]==i_e){\r
+                               o_row[i]="1";\r
+                       }else if(l[i]=="0"){\r
+                               o_row[i]="0";\r
+                       }else{\r
+                               String s1=isSingle(l[i])?l[i]:"("+l[i]+")";\r
+                               String s2=isSingle(i_e)?i_e:"("+i_e+")";\r
+                               o_row[i]="("+s1+"/"+s2+")";\r
+                       }\r
+               }\r
+       }\r
+       public void mul(int i_r,String i_e,String[] o_row)\r
+       {\r
+               String[] l=this._data[i_r];\r
+               if(i_e=="0"){\r
+                       for(int i=0;i<o_row.length;i++){\r
+                               o_row[i]="0";\r
+                       }\r
+               }else if(i_e=="1"){\r
+                       return;\r
+               }else{\r
+                       for(int i=0;i<o_row.length;i++){\r
+                               if(l[i]=="0"){\r
+                                       o_row[i]="0";\r
+                               }else if(l[i]=="1"){\r
+                                       o_row[i]=i_e;\r
+                               }else{\r
+                                       String s1=isSingle(l[i])?l[i]:"("+l[i]+")";\r
+                                       String s2=isSingle(i_e)?i_e:"("+i_e+")";\r
+                                       o_row[i]="("+s1+"*"+s2+")";\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       public void subRow(int i_r1,String[] i_r,String[] o_row)\r
+       {\r
+               String[] l1=this._data[i_r1];\r
+               String[] l2=i_r;\r
+               for(int i=0;i<o_row.length;i++){\r
+                       if(l1[i]=="0"){\r
+                               o_row[i]=l2[i];\r
+                       }else if(l2[i]=="0"){\r
+                               o_row[i]=l1[i];\r
+                       }else if(l2[i]==l1[i]){\r
+                               o_row[i]="0";\r
+                       }else{\r
+                               String s1=isSingle(l1[i])?l1[i]:"("+l1[i]+")";\r
+                               String s2=isSingle(l2[i])?l2[i]:"("+l2[i]+")";\r
+                               o_row[i]="("+s1+"-"+s2+")";\r
+                       }\r
+               }\r
+       }\r
+       public static void main(String[] args)\r
+       {\r
+               try {\r
+                       Solver n=new Solver();\r
+\r
+                       for(int i=0;i<4;i++){\r
+                               for(int i2=0;i2<i;i2++){\r
+                                       n.mul(i2,n._data[i][i2],n._temp);\r
+                                       n.subRow(i,n._temp,n._data[i]);                                 \r
+                               }\r
+                               n.div(i,n._data[i][i],n._data[i]);\r
+                       }\r
+                       n.dump();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }       \r
+}\r