OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@693 7cac0...
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Tue, 30 Nov 2010 13:46:14 +0000 (13:46 +0000)
committerAtsuo Igarashi <atsuoigarashi@ubuntu.(none)>
Tue, 5 Apr 2011 07:08:50 +0000 (16:08 +0900)
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java [new file with mode: 0644]
sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/Solver.java [new file with mode: 0644]

diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingCamera.java
new file mode 100644 (file)
index 0000000..8e6d72a
--- /dev/null
@@ -0,0 +1,951 @@
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ * 
+ */
+package jp.nyatla.nyartoolkit.dev;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+
+import jp.nyatla.nyartoolkit.core.*;
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;
+import jp.nyatla.nyartoolkit.core.pickup.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
+import jp.nyatla.nyartoolkit.core.types.stack.*;
+
+
+///**
+// * QRコードのシンボルを結びつける偉いクラス
+// *
+// */
+//class NyQrCodeSymbolBinder
+//{
+//     LabelingBufferdImage bimg;
+//     
+//     NyARIntPoint[][] _sqare;
+//     /**
+//      * 最小の三角形を構成する頂点セットを得る
+//      * @param i_s0
+//      * @param i_s1
+//      * @param i_s2
+//      * @param o_vertex
+//      */
+//     public static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id)
+//     {
+//             //辺の長さが最小になる頂点の組合せを探す
+//             int d;
+//             int x,y;
+//             int dmax=0x7fffffff;
+//             final NyARIntPoint[] vertex0=i_sqare[0].imvertex;
+//             final NyARIntPoint[] vertex1=i_sqare[1].imvertex;
+//             final NyARIntPoint[] vertex2=i_sqare[2].imvertex;
+//             for(int i=0;i<4;i++)
+//             {
+//                     for(int i2=0;i2<4;i2++)
+//                     {
+//                             for(int i3=0;i3<4;i3++){
+//                                     x=vertex0[i].x-vertex2[i3].x;
+//                                     y=vertex0[i].y-vertex2[i3].y;
+//                                     d=x*x+y*y;
+//                                     x=vertex1[i2].x-vertex2[i3].x;
+//                                     y=vertex1[i2].y-vertex2[i3].y;
+//                                     d+=x*x+y*y;
+//                                     x=vertex1[i2].x-vertex0[i].x;
+//                                     y=vertex1[i2].y-vertex0[i].y;
+//                                     d+=x*x+y*y;
+//                                     if(d<dmax){
+//                                             dmax=d;
+//                                             o_vertex_id[0]=i;                                       
+//                                             o_vertex_id[1]=i2;
+//                                             o_vertex_id[2]=i3;
+//                                     }
+//                             }
+//                     }
+//             }
+//             return;
+//     }
+//     /**
+//      * 2矩形の頂点距離が最低の組合せを探す
+//      * @param i_sqare
+//      * @param o_vertex_id
+//      */
+//     public static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
+//     {
+//             //辺の長さが最小になる頂点の組合せを探す
+//             int d;
+//             int x,y;
+//             int dmax=0x7fffffff;
+//             for(int i=0;i<4;i++)
+//             {
+//                     for(int i2=0;i2<4;i2++)
+//                     {
+//                             x=i_sqare1[i2].x-i_sqare0[i].x;
+//                             y=i_sqare1[i2].y-i_sqare0[i].y;
+//                             d=x*x+y*y;
+//                             if(d<dmax){
+//                                     dmax=d;
+//                                     o_vertex_id[0]=i;                                       
+//                                     o_vertex_id[1]=i2;
+//                             }
+//                     }
+//             }
+//             return;
+//     }       
+//     
+//     /**
+//      * キーシンボルのインデックスを得る
+//      * @param i_sqare
+//      * @param i_vertex_id
+//      * 最小三角形の頂点IDセット
+//      * @return
+//      */
+//     public static int getKeySymble(NyARSquare[] i_sqare,int[] i_vertex_id)
+//     {
+//             //シンボルグループの重心を計算
+//             int cx,cy;
+//             cx=cy=0;
+//             for(int i=0;i<3;i++)
+//             {
+//                     final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;
+//                     cx+=sq_ptr[0].x;                        
+//                     cx+=sq_ptr[1].x;                        
+//                     cx+=sq_ptr[2].x;                        
+//                     cx+=sq_ptr[3].x;                        
+//                     cy+=sq_ptr[0].y;                        
+//                     cy+=sq_ptr[1].y;                        
+//                     cy+=sq_ptr[2].y;                        
+//                     cy+=sq_ptr[3].y;                        
+//             }
+//             cx/=12;
+//             cy/=12; 
+//             //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
+//             int key_symble_idx=0;
+//             int x=i_sqare[0].imvertex[i_vertex_id[0]].x-cx;
+//             int y=i_sqare[0].imvertex[i_vertex_id[0]].y-cy;
+//             int dmax=x*x+y*y;
+//             for(int i=1;i<3;i++){
+//                     x=i_sqare[i].imvertex[i_vertex_id[i]].x-cx;
+//                     y=i_sqare[i].imvertex[i_vertex_id[i]].y-cy;
+//                     final int d=x*x+y*y;
+//                     if(d<dmax){
+//                             dmax=d;
+//                             key_symble_idx=i;
+//                     }
+//             }
+//             return key_symble_idx;
+//     }
+//     public void bindSquare(NyARSquare i_sq1,int i_lv1,NyARSquare i_sq2,int i_lv2)
+//     {
+//             NyARSquare new_square=new NyARSquare();
+//             //4辺の式を計算
+//             new_square.line[0].copyFrom(i_sq1.line[(i_lv1)%4]);
+//             new_square.line[1].copyFrom(i_sq1.line[(i_lv1+3)%4]);
+//             new_square.line[2].copyFrom(i_sq2.line[(i_lv2)%4]);
+//             new_square.line[3].copyFrom(i_sq2.line[(i_lv2+3)%4]);
+//             //歪み無しの座標系を計算
+//             final NyARDoublePoint2d[] l_sqvertex = new_square.sqvertex;
+//             final NyARLinear[] l_line = new_square.line;            
+//             for (int i = 0; i < 4; i++) {
+//                     final NyARLinear l_line_i = l_line[i];
+//                     final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+//                     final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+//                     if (w1 == 0.0) {
+//                             return;
+//                     }
+//                     l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+//                     l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+////                   // 頂点インデクスから頂点座標を得て保存
+////                   l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+////                   l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+//             }
+//             Graphics g=this.bimg.getGraphics();
+//             g.setColor(Color.red);
+//             int[] x=new int[4];
+//             int[] y=new int[4];
+//             for(int i=0;i<4;i++){
+//                     x[i]=(int)l_sqvertex[i].x;
+//                     y[i]=(int)l_sqvertex[i].y;
+//             }
+//             g.drawPolygon(x,y,4);
+//             //基準点はVertexをそのまま採用
+//             //2個の想定点は座標を逆変換して設定
+//     }
+//     /**
+//      *
+//      * @param i_sq
+//      * @param o_sq
+//      * @return
+//      */
+//     public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+//     {
+//             int[] minimum_triangle_vertex=new int[3];
+//             int[] minimum_line_vertex=new int[2];
+//
+//             //辺の長さが最小になる頂点の組合せを探す
+//             getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
+//             
+//             //キーシンボルのインデクス番号を得る
+//             int key_simble_idx=getKeySymble(i_sq,minimum_triangle_vertex);
+//             
+//             //エッジシンボルのインデックス番号を決める
+//             int symbol_e1_idx=(key_simble_idx+1)%3;
+//             int symbol_e2_idx=(key_simble_idx+2)%3;
+//             
+//             //エッジシンボル間で最短距離を取る頂点ペアを取る
+//             //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
+//             getMinimumLineVertex(i_sq[symbol_e1_idx].imvertex,i_sq[symbol_e2_idx].imvertex,minimum_line_vertex);
+//             
+//             //内対角を外対角に変換
+//             int lv1=(minimum_line_vertex[0]+2)%4;
+//             int lv2=(minimum_line_vertex[1]+2)%4;
+//             int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
+//             //矩形のバインド
+//             bindSquare(i_sq[symbol_e1_idx],lv1,i_sq[symbol_e2_idx],lv2);
+//                             
+//             
+//             Graphics g=this.bimg.getGraphics();
+//             //内対角に緑の点を打つ
+//             g.setColor(Color.green);
+//             g.fillRect(i_sq[symbol_e1_idx].imvertex[lv1].x-2,i_sq[symbol_e1_idx].imvertex[lv1].y-2,4,4);
+//             g.fillRect(i_sq[symbol_e2_idx].imvertex[lv2].x-2,i_sq[symbol_e2_idx].imvertex[lv2].y-2,4,4);
+////           g.fillRect(i_sq[symbol_e2_idx][minimum_line_vertex[1]].x-2,i_sq[symbol_e2_idx][minimum_line_vertex[1]].y-2,4,4);
+//             
+//             
+//             //中央の中心エッジから最も遠い点が
+//             //両端のエッジも探す
+//             
+//             
+//             
+//
+////           this.bimg.getGraphics().fillRect(i_sq[edge1_id][vid1_id].x,i_sq[edge1_id][vid1_id].y,5,5);
+//             
+//             for (int i = 0; i <3; i++) {
+//                     int[] xp=new int[4]; 
+//                     int[] yp=new int[4]; 
+//                     for(int i2=0;i2<4;i2++){
+//                             xp[i2]=i_sq[i].imvertex[i2].x;
+//                             yp[i2]=i_sq[i].imvertex[i2].y;
+//                     }
+//                     this.bimg.getGraphics().setColor(Color.RED);
+//                     this.bimg.getGraphics().drawPolygon(xp, yp,4);
+//             }               
+//             
+//             
+//             return false;
+//             
+//             
+//             
+//             
+//
+//             
+//     }       
+//     
+//     
+//     
+//     
+//}
+
+
+/**
+ * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス
+ * 
+ */
+class NyARQRCodeDetector implements INyARSquareDetector
+{
+       LabelingBufferdImage bimg;
+       private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
+
+       private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
+
+       private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
+
+       private final int _width;
+
+       private final int _height;
+
+       private final NyARLabeling_ARToolKit _labeling;
+
+       private final NyARLabelingImage _limage;
+
+       private final NyARCameraDistortionFactor _dist_factor_ref;
+
+       /**
+        * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+        * 
+        * @param i_param
+        */
+       public NyARQRCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+       {
+               this._width = i_size.w;
+               this._height = i_size.h;
+               this._dist_factor_ref = i_dist_factor_ref;
+               this._labeling = new NyARLabeling_ARToolKit();
+               this._limage = new NyARLabelingImage(this._width, this._height);
+               this._labeling.attachDestination(this._limage);
+
+               // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+               int number_of_coord = (this._width + this._height) * 2;
+
+               // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+               this._max_coord = number_of_coord;
+               this._xcoord = new int[number_of_coord * 2];
+               this._ycoord = new int[number_of_coord * 2];
+       }
+
+       private final int _max_coord;
+
+       private final int[] _xcoord;
+
+       private final int[] _ycoord;
+
+       private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+       {
+               // vertex1を境界にして、後方に配列を連結
+               System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+               System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+       }
+
+       private final int[] __detectMarker_mkvertex = new int[5];
+
+       /**
+        * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+        * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+        * 
+        * @param i_raster
+        * 解析する2値ラスタイメージを指定します。
+        * @param o_square_stack
+        * 抽出した正方形候補を格納するリスト
+        * @throws NyARException
+        */
+       public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+       {
+               final INyARLabeling labeling_proc = this._labeling;
+               final NyARLabelingImage limage = this._limage;
+
+               // 初期化
+
+               // マーカーホルダをリセット
+               o_square_stack.clear();
+
+               // ラベリング
+               labeling_proc.labeling(i_raster);
+
+               // ラベル数が0ならここまで
+               final int label_num = limage.getLabelStack().getLength();
+               if (label_num < 1) {
+                       return;
+               }
+
+               final NyARLabelingLabelStack stack = limage.getLabelStack();
+               // ラベルを大きい順に整列
+               stack.sortByArea();
+               final NyARLabelingLabel[] labels = stack.getArray();
+
+
+               // デカいラベルを読み飛ばし
+               int i;
+               for (i = 0; i < label_num; i++) {
+                       // 検査対象内のラベルサイズになるまで無視
+                       if (labels[i].area <= AR_AREA_MAX) {
+                               break;
+                       }
+               }
+               
+               final int xsize = this._width;
+               final int ysize = this._height;
+               final int[] xcoord = this._xcoord;
+               final int[] ycoord = this._ycoord;
+               final int coord_max = this._max_coord;
+               final int[] mkvertex = this.__detectMarker_mkvertex;
+               final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
+               final int[] indextable = limage.getIndexArray();
+               int coord_num;
+               int label_area;
+               NyARLabelingLabel label_pt;
+               NyARSquareStack wk_stack=new NyARSquareStack(100);
+
+               for (; i < label_num; i++) {
+                       label_pt = labels[i];
+                       label_area = label_pt.area;
+                       // 検査対象サイズよりも小さくなったら終了
+                       if (label_area < AR_AREA_MIN) {
+                               break;
+                       }
+                       // クリップ領域が画面の枠に接していれば除外
+                       if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+                               continue;
+                       }
+                       if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+                               continue;
+                       }
+                       // 特徴点候補であるかを確認する。
+                       if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
+                               continue;
+                       }
+
+                       // 輪郭を取得
+                       coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+                       if (coord_num == coord_max) {
+                               // 輪郭が大きすぎる。
+                               continue;
+                       }
+                       // 頂点候補のインデクスを取得
+                       final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+                       // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+                       normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+                       // 頂点情報を取得
+                       if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+                               continue;
+                       }
+                       NyARSquare square=(NyARSquare)wk_stack.prePush();
+                       if(!getSquareLine(mkvertex,xcoord,ycoord,square)){
+                               wk_stack.pop();
+                               continue;
+                       }
+               }
+               bindQrcodeEdge(wk_stack);
+               //エッジ同士の相関関係をしらべる。
+
+               return;
+       }
+       /**
+        *
+        * @param i_sq
+        * @param o_sq
+        * @return
+        */
+       public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+       {
+               NyQrCodeSymbolBinder binder=new NyQrCodeSymbolBinder();
+               binder.bimg=this.bimg;
+               binder.(i_sq, o_sq);
+
+               return false;
+               
+               
+               
+               
+       }
+       /**
+        * QRコードのエッジペアを作る
+        * @param i_square_stack
+        */
+       public void bindQrcodeEdge(NyARSquareStack i_square_stack)
+       {
+               
+               NyARSquare sq_ptr1,sq_ptr2,sq_ptr3;
+               int number_of_edge=i_square_stack.getLength();
+               if(number_of_edge<3){
+                       return;
+               }
+               NyARSquare[] sa=i_square_stack.getArray();
+               for(int i=0;i<number_of_edge;i++)
+               {       
+                       for(int i2=i+1;i2<number_of_edge;i2++)
+                       {
+                               sq_ptr2=sa[i2];
+                               for(int i3=i2+1;i3<number_of_edge;i3++){
+                                       sq_ptr3=sa[i3];
+                                       //3個のエッジの関連性を確認する。
+                                       margeEdge(sa,null);
+                               }
+                               //
+                       }
+               }
+       }
+       /**
+        * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
+        * 
+        * @param i_v1
+        * @param i_v2
+        * @param o_line
+        */
+       final private void getLine(NyARDoublePoint2d i_v1, NyARDoublePoint2d i_v2, NyARLinear o_line)
+       {
+               final double x = i_v1.x - i_v2.x;
+               final double y = i_v1.y - i_v2.y;
+               final double x2 = x * x;
+               final double y2 = y * y;
+               final double rise_ = Math.sqrt(x2 / (x2 + y2));
+               o_line.rise = rise_;
+               o_line.run = Math.sqrt(y2 / (x2 + y2));
+               if (x < 0) {
+                       if (y < 0) {
+                               o_line.rise = -o_line.rise;
+                       } else {
+                               o_line.rise = -o_line.rise;
+                               o_line.run = -o_line.run;
+                       }
+               } else {
+                       if (y < 0) {
+                               o_line.rise = -o_line.rise;
+                               o_line.run = -o_line.run;
+                       } else {
+                               o_line.rise = -o_line.rise;
+                       }
+               }
+               o_line.intercept = (i_v1.y + (o_line.run / o_line.rise) * (i_v1.x)) * rise_;
+
+       }
+       private final INyARPca2d _pca=new NyARPca2d_MatrixPCA_O2(100);
+       private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();
+       private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();
+       private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();
+       /**
+        * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
+        * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
+        * Optimize:STEP[424->391]
+        * 
+        * @param i_cparam
+        * @return
+        * @throws NyARException
+        */
+       private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
+       {
+               final NyARLinear[] l_line = o_square.line;
+               final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;  
+               final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;
+               final NyARDoublePoint2d mean=this.__getSquareLine_mean;
+               final NyARDoublePoint2d ev=this.__getSquareLine_ev;
+       
+               
+               for (int i = 0; i < 4; i++) {
+                       final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+                       final int st = (int) (i_mkvertex[i] + w1);
+                       final int ed = (int) (i_mkvertex[i + 1] - w1);
+                       final int n = ed - st + 1;
+                       if (n < 2) {
+                               // nが2以下でmatrix.PCAを計算することはできないので、エラー
+                               return false;
+                       }
+                       //主成分分析する。
+                       this._pca.pcaWithDistortionFactor(i_xcoord, i_ycoord, st, n,dist_factor, evec, ev,mean);
+                       final NyARLinear l_line_i = l_line[i];
+                       l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+                       l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+                       l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+               }
+
+               final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
+               final 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];
+                       final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+                       if (w1 == 0.0) {
+                               return false;
+                       }
+                       l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+                       l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+                       // 頂点インデクスから頂点座標を得て保存
+                       l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+                       l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+               }
+               return true;
+       }
+       /**
+        * 辺からの対角線が最長になる点を対角線候補として返す。
+        * 
+        * @param i_xcoord
+        * @param i_ycoord
+        * @param i_coord_num
+        * @return
+        */
+       private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+       {
+               final int sx = i_xcoord[0];
+               final int sy = i_ycoord[0];
+               int d = 0;
+               int w, x, y;
+               int ret = 0;
+               for (int i = 1; i < i_coord_num; i++) {
+                       x = i_xcoord[i] - sx;
+                       y = i_ycoord[i] - sy;
+                       w = x * x + y * y;
+                       if (w > d) {
+                               d = w;
+                               ret = i;
+                       }
+                       // ここでうまく終了条件入れられないかな。
+               }
+               return ret;
+       }
+
+       private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+       private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+       /**
+        * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+        * 
+        * @param i_x_coord
+        * @param i_y_coord
+        * @param i_vertex1_index
+        * @param i_coord_num
+        * @param i_area
+        * @param o_vertex
+        * 要素数はint[4]である事
+        * @return
+        */
+       private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+       {
+               final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+               final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+               final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+               final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+               final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+               int dmax = 0;
+               int v1 = i_vertex1_index;
+               for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+                       // {
+                       final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+                       if (d > dmax) {
+                               dmax = d;
+                               v1 = i;
+                       }
+               }
+               final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+               o_vertex[0] = i_vertex1_index;
+
+               if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+                       // 0 ) {
+                       return false;
+               }
+               if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+                       // < 0) {
+                       return false;
+               }
+
+               int v2;
+               if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+                       o_vertex[1] = wv1.vertex[0];
+                       o_vertex[2] = v1;
+                       o_vertex[3] = wv2.vertex[0];
+               } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+                       // 頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+                       v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+                       if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+                               return false;
+                       }
+                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+                               return false;
+                       }
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+                               o_vertex[1] = wv1.vertex[0];
+                               o_vertex[2] = wv2.vertex[0];
+                               o_vertex[3] = v1;
+                       } else {
+                               return false;
+                       }
+               } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+                       // v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+                       v2 = (v1 + end_of_coord) / 2;
+
+                       if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+                               return false;
+                       }
+                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+                               return false;
+                       }
+                       if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+                               o_vertex[1] = v1;
+                               o_vertex[2] = wv1.vertex[0];
+                               o_vertex[3] = wv2.vertex[0];
+                       } else {
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+               o_vertex[4] = end_of_coord;
+               return true;
+       }
+       /**
+        * QRコードのエッジ特徴を持つラベルであるかを調べる
+        * @param buf
+        * @param index_table
+        * @param i_label
+        * @return
+        */
+       private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)
+       {
+               int tx, bx;
+               int w;
+               int i_label_id = i_label.id;
+               int[] limage_j;
+               final int clip_l = i_label.clip_l;
+               final int clip_b = i_label.clip_b;
+               final int clip_r = i_label.clip_r;
+               final int clip_t = i_label.clip_t;
+
+               tx = bx = 0;
+               // 上接点(→)
+               limage_j = buf[clip_t];
+               for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+                       w = limage_j[i];
+                       if (w > 0 && index_table[w - 1] == i_label_id) {
+                               tx = i;
+                               break;
+                       }
+               }
+               // 下接点(←)
+               limage_j = buf[clip_b];
+               for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+                       w = limage_j[i];
+                       if (w > 0 && index_table[w - 1] == i_label_id) {
+                               bx = i;
+                               break;
+                       }
+               }
+               final int cx = (clip_l + clip_r) / 2;
+               final int cy = (clip_t + clip_b) / 2;
+               // 横断チェック(中心から線を引いて、101になるかしらべる)
+               if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {
+                       return false;
+               }
+               if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {
+                       return false;
+               }
+               return true;
+       }
+
+       /**
+        * 対角線のパターンを調べる。
+        * 
+        * @param buf
+        * @param i_px1
+        * @param i_py1
+        * @param i_px2
+        * @param i_py2
+        * @return
+        */
+       private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)
+       {
+               int sub_y = i_py2 - i_py1;
+               int sub_x = i_px2 - i_px1;
+               // 黒
+               int i = 0;
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+                               break;
+                       }
+
+               }
+               if (i == sub_y) {
+                       return false;
+               }
+               // 白
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {
+                               break;
+                       }
+
+               }
+               if (i == sub_y) {
+                       return false;
+               }
+               // 黒
+               for (; i < sub_y; i++) {
+                       int yp = i_py1 + i;
+                       int xp = i_px1 + i * sub_x / sub_y;
+                       if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+                               break;
+                       }
+
+               }
+               if (i != sub_y) {
+                       return false;
+               }
+               // 端まで到達したらOK
+               return true;
+       }
+
+}
+
+
+public class LabelingCamera extends Frame implements JmfCaptureListener
+{
+       private final String camera_file = "../Data/camera_para.dat";
+
+       private JmfNyARRaster_RGB _raster;
+
+       private JmfCameraCapture capture;
+       private NyARParam ap;
+       public LabelingCamera() throws NyARException, NyARException
+       {
+               setBounds(0, 0, 640 + 64, 720 + 64);
+               // キャプチャの準備
+               capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+               capture.setCaptureListener(this);
+
+               // キャプチャイメージ用のラスタを準備
+               this._raster = new JmfNyARRaster_RGB(320, 240);
+               
+               // AR用カメラパラメタファイルをロード
+               ap = new NyARParam();
+               ap.loadARParamFromFile(camera_file);
+               ap.changeScreenSize(320, 240);          
+               
+               
+       }
+
+       // そのラベルが特徴点候補か返す。
+
+       private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+       private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+
+       private NyARLabelingImage _limage = new NyARLabelingImage(320, 240);
+
+       private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+       private NyARRasterFilter_ARToolkitThreshold filter_gs2bin;
+
+       public void onUpdateBuffer(Buffer i_buffer)
+       {
+               NyARRasterFilter_AreaAverage gs2bin=new NyARRasterFilter_AreaAverage();
+
+               try {
+                       // キャプチャしたバッファをラスタにセット
+                       _raster.setBuffer(i_buffer);
+
+                       Graphics g = getGraphics();
+                       // キャプチャ画像
+                       BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+                       Image img = b2i.createImage(i_buffer);
+                       this.getGraphics().drawImage(img, 32, 32, this);
+
+                       // 画像1
+                       INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+                       filter_rgb2gs.doFilter(_raster, _gsraster1);
+                       this._bimg.drawImage(this._gsraster1);
+                       this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+                       
+
+                       // 画像2
+                       gs2bin.doFilter(_gsraster1, _binraster1);
+                       this._bimg.drawImage(_binraster1);
+                       this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+                       // 画像3
+                       NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+                       NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+                       labeling.attachDestination(limage);
+                       labeling.labeling(_binraster1);
+                       this._bimg.drawImage(this._gsraster1);
+                       NyARLabelingLabel[] labels =  limage.getLabelStack().getArray();
+
+                       NyARSquareStack stack = new NyARSquareStack(100);
+                       NyARQRCodeDetector detect = new NyARQRCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+                       detect.bimg=this._bimg;
+
+                       detect.detectMarker(_binraster1, stack);
+                       for (int i = 0; i < stack.getLength(); i++) {
+                               NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray();
+                               int[] xp=new int[4]; 
+                               int[] yp=new int[4]; 
+                               for(int i2=0;i2<4;i2++){
+                                       xp[i2]=square_ptr[i].imvertex[i2].x;
+                                       yp[i2]=square_ptr[i].imvertex[i2].y;
+                               }
+                               this._bimg.getGraphics().setColor(Color.RED);
+                               this._bimg.getGraphics().drawPolygon(xp, yp,2);
+                       }
+                       this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+                       // 画像3
+                       // threshold.debugDrawHistogramMap(_workraster, _workraster2);
+                       // this._bimg2.setImage(this._workraster2);
+                       // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+                       // 画像4
+                       // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+                       // threshold.analyzeRaster(_gsraster1);
+                       // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+                       // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+                       // this._bimg.drawImage(_binraster1);
+
+                       // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+                       // detector.analyzeRaster(_binraster1);
+
+                       // this._bimg.overlayData(detector.geResult());
+
+                       // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+                       // 画像5
+
+                       /*
+                        * threshold2.debugDrawHistogramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+                        * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+                        */
+
+                       // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+       private INyARLabeling labelingFactory(int i_idx)
+       {
+               // switch(i_idx){
+               // case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
+               // case 1:{return new NyLineLabeling();}
+               // }
+               return null;
+
+       }
+
+       private void startCapture()
+       {
+               try {
+                       capture.start();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public static void main(String[] args)
+       {
+               try {
+                       LabelingCamera mainwin = new LabelingCamera();
+                       mainwin.setVisible(true);
+                       mainwin.startCapture();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+}
diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/LabelingTest.java
new file mode 100644 (file)
index 0000000..1ac6285
--- /dev/null
@@ -0,0 +1,103 @@
+\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.*;\r
+import java.awt.event.WindowAdapter;\r
+import java.awt.event.WindowEvent;\r
+import java.awt.image.BufferedImage;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.util.Date;\r
+\r
+import javax.imageio.ImageIO;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.NyARLabeling_Rle;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.NyARRleLabelFragmentInfo;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_RGB;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.NyARRasterFilter_Rgb2Gs_RgbAve;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARContourPickup;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+import jp.nyatla.nyartoolkit.utils.j2se.*;\r
+\r
+\r
+class Main_Labeling extends NyARLabeling_Rle\r
+{\r
+       private NyARIntPoint2d[] vx=NyARIntPoint2d.createArray(100);\r
+       public NyARGrayscaleRaster current_gs;\r
+       public int current_th;\r
+       public Main_Labeling(int i_width,int i_height) throws NyARException\r
+       {\r
+               super(i_width,i_height);\r
+       }\r
+       /**\r
+        * @Override\r
+        */\r
+       protected void onLabelFound(NyARRleLabelFragmentInfo iRefLabel)throws NyARException\r
+       {\r
+               NyARContourPickup ct=new NyARContourPickup();\r
+               Date d2 = new Date();\r
+               \r
+               for(int i=0;i<100000;i++){\r
+                       int c=ct.getContour(this.current_gs,this.current_th, iRefLabel.entry_x,iRefLabel.clip_t, this.vx);\r
+               }\r
+               Date d = new Date();\r
+               NyARDoublePoint3d ang=new NyARDoublePoint3d();\r
+               System.out.println(d.getTime() - d2.getTime());\r
+\r
+               return;\r
+       }\r
+}\r
+\r
+/**\r
+ * ラべリングと、輪郭線抽出のテストコード\r
+ * @author nyatla\r
+ *\r
+ */\r
+public class LabelingTest extends Frame\r
+{\r
+       private final String source_file = "../Data/ラべリングのエントリポイントエラー.png";\r
+       private BufferedImage _src_image;\r
+       public LabelingTest() throws NyARException,Exception\r
+       {\r
+               this._src_image = ImageIO.read(new File(source_file));\r
+               \r
+               INyARRgbRaster ra =new NyARRgbRaster_RGB(this._src_image.getWidth(),this._src_image.getHeight());\r
+               NyARRasterImageIO.copy(this._src_image,ra);\r
+               //GS値化\r
+               NyARGrayscaleRaster gs=new NyARGrayscaleRaster(this._src_image.getWidth(),this._src_image.getHeight());\r
+               NyARRasterFilter_Rgb2Gs_RgbAve filter=new NyARRasterFilter_Rgb2Gs_RgbAve(ra.getBufferType());\r
+               filter.doFilter(ra,gs);\r
+               //ラべリングの試験\r
+               Main_Labeling lv=new Main_Labeling(ra.getWidth(),ra.getHeight());\r
+               lv.current_gs=gs;\r
+               lv.current_th=230;\r
+               lv.labeling(gs,lv.current_th);\r
+               //画像をストア\r
+               \r
+               \r
+               this.addWindowListener(new WindowAdapter() {\r
+                       public void windowClosing(WindowEvent e)\r
+                       {\r
+                               System.exit(0);\r
+                       }\r
+               });\r
+               //ペイント\r
+       }\r
+\r
+       public static void main(String[] args)\r
+       {\r
+               try {\r
+                       LabelingTest app = new LabelingTest();\r
+                       app.setVisible(true);\r
+                       app.setBounds(0, 0, 640, 480);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+}\r
diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARColorPatt_DiagonalRatio.java
new file mode 100644 (file)
index 0000000..de95d6d
--- /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.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\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/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/NyARSquareDetector_Vector.java
new file mode 100644 (file)
index 0000000..472489c
--- /dev/null
@@ -0,0 +1,358 @@
+/* \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 edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelOverlapChecker;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARCoord2SquareVertexIndexes;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+\r
+\r
+/**\r
+ * \r
+ *\r
+ */\r
+public class NyARSquareDetector_Vector\r
+{\r
+       private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+       private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+       private final int _width;\r
+       private final int _height;\r
+       private final int[] _xcoord;\r
+       private final int[] _ycoord;\r
+\r
+       private final NyARLabeling_Rle _labeling;\r
+\r
+       private final NyARLabelOverlapChecker<NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo> _overlap_checker = new NyARLabelOverlapChecker<NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo>(32,NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo.class);\r
+       private final SquareContourDetector_Vector _sqconvertor;\r
+       private final NyARContourPickup _cpickup=new NyARContourPickup();\r
+       private final NyARRleLabelFragmentInfoPtrStack _stack;\r
+       \r
+       private final int _max_coord;\r
+       /**\r
+        * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+        * \r
+        * @param i_param\r
+        */\r
+       public NyARSquareDetector_Vector(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+       {\r
+               this._width = i_size.w;\r
+               this._height = i_size.h;\r
+               //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
+               this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
+               this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN);\r
+               this._sqconvertor=new SquareContourDetector_Vector(i_size,i_dist_factor_ref);\r
+               this._stack=new NyARRleLabelFragmentInfoPtrStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
+               \r
+\r
+               // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+               int number_of_coord = (this._width + this._height) * 2;\r
+\r
+               // 輪郭バッファ\r
+               this._max_coord = number_of_coord;\r
+               this._xcoord = new int[number_of_coord];\r
+               this._ycoord = new int[number_of_coord];\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * arDetectMarker2を基にした関数\r
+        * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
+        * directionの確定は行いません。\r
+        * @param i_raster\r
+        * 解析する2値ラスタイメージを指定します。\r
+        * @param o_square_stack\r
+        * 抽出した正方形候補を格納するリスト\r
+        * @throws NyARException\r
+        */\r
+       public final void detectMarker(NyARGrayscaleRaster i_gs,int i_th,NyARSquareStack o_square_stack) throws NyARException\r
+       {\r
+               final NyARRleLabelFragmentInfoPtrStack flagment=this._stack;\r
+               final NyARLabelOverlapChecker<NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
+\r
+               // マーカーホルダをリセット\r
+               o_square_stack.clear();\r
+\r
+               // ラベル数が0ならここまで\r
+               final int label_num=this._labeling.labeling(i_gs,i_th, 0, i_gs.getHeight(), flagment);\r
+               if (label_num < 1) {\r
+                       return;\r
+               }\r
+               //ラベルをソートしておく\r
+               flagment.sortByArea();\r
+               //ラベルリストを取得\r
+               NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
+\r
+               final int xsize = this._width;\r
+               final int ysize = this._height;\r
+               final int coord_max = this._max_coord;\r
+               int[] xcoord = this._xcoord;\r
+               int[] ycoord = this._ycoord;\r
+\r
+\r
+               //重なりチェッカの最大数を設定\r
+               overlap.setMaxLabels(label_num);\r
+\r
+               for (int i=0; i < label_num; i++) {\r
+                       final NyARRleLabelFragmentInfoPtrStack.RleLabelFragmentInfo label_pt=labels[i];\r
+                       final int label_area = label_pt.area;\r
+               \r
+                       // クリップ領域が画面の枠に接していれば除外\r
+                       if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
+                               continue;\r
+                       }\r
+                       if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
+                               continue;\r
+                       }\r
+                       // 既に検出された矩形との重なりを確認\r
+                       if (!overlap.check(label_pt)) {\r
+                               // 重なっているようだ。\r
+                               continue;\r
+                       }\r
+                       \r
+                       // 輪郭を取得\r
+                       final int coord_num = _cpickup.getContour(i_gs,i_th,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+                       if (coord_num == coord_max) {\r
+                               // 輪郭が大きすぎる。\r
+                               continue;\r
+                       }\r
+\r
+                       //ここから先が輪郭分析\r
+                       NyARSquare square_ptr = o_square_stack.prePush();\r
+                       if(!this._sqconvertor.coordToSquare(i_gs,xcoord,ycoord,coord_num,label_area,square_ptr)){\r
+                               o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
+                               continue;                               \r
+                       }\r
+                       // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+                       overlap.push(label_pt);\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * デバック用API\r
+        * @return\r
+        */\r
+       public NyARRleLabelFragmentInfoPtrStack _getFragmentStack()\r
+       {\r
+               return this._stack;\r
+       }\r
+       /********************************************************************************\r
+        * \r
+        * 追加クラス \r
+        * \r
+        ********************************************************************************/\r
+       private class SquareContourDetector_Vector\r
+       {\r
+               private final NyARObserv2IdealMap2 _distmap;\r
+               private final int[] __detectMarker_mkvertex = new int[4];\r
+               private final NyARCoord2SquareVertexIndexes _coord2vertex=new NyARCoord2SquareVertexIndexes();\r
+               public SquareContourDetector_Vector(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref)\r
+               {\r
+                       this._distmap=new NyARObserv2IdealMap2(i_distfactor_ref,i_size);\r
+                       return;\r
+               }\r
+\r
+               public boolean coordToSquare(NyARGrayscaleRaster i_raster,int[] i_xcoord,int[] i_ycoord,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException\r
+               {\r
+\r
+                       final int[] mkvertex = this.__detectMarker_mkvertex;\r
+\r
+                       // 頂点情報を取得\r
+                       if (!this._coord2vertex.getVertexIndexes(i_xcoord, i_ycoord,i_coord_num, i_label_area, mkvertex)) {\r
+                               // 頂点の取得が出来なかったので破棄\r
+                               return false;\r
+                       }               \r
+                       // マーカーを検出\r
+                       if (!getSquareLine(i_raster,mkvertex, i_xcoord, i_ycoord,i_coord_num, o_square)){\r
+                               // 矩形が成立しなかった。\r
+                               return false;\r
+                       }\r
+                       return true;\r
+               }\r
+               /**\r
+                * 指定した範囲の輪郭点ベクトル・座標を、加算する。\r
+                * @param i_raster\r
+                * @param i_xcoord\r
+                * @param i_ycoord\r
+                * @param i_st\r
+                * @param i_ed\r
+                * @param o_vecsum\r
+                * @param o_possum\r
+                * @return\r
+                */\r
+               private boolean addCoordVecPos(NyARGrayscaleRaster i_raster,int[] i_xcoord, int[] i_ycoord,int i_st,int i_ed,NyARIntPoint2d io_vecsum)\r
+               {\r
+                       int dxi,dyi;\r
+                       //ベクトル分析\r
+                       dxi=io_vecsum.x;\r
+                       dyi=io_vecsum.y;\r
+                       for(int i=i_st;i<i_ed;i++){\r
+                               //境界に設置していたら失敗する。\r
+                               if(i_xcoord[i]<1 || i_ycoord[i]<1 || i_xcoord[i]>=319 || i_ycoord[i]>=239){\r
+                                       return false;\r
+                               }\r
+                               //o_vecsumをワークに流用\r
+                               i_raster.getPixelVector8(i_xcoord[i],i_ycoord[i],io_vecsum);\r
+                               dxi+=io_vecsum.x;\r
+                               dyi-=io_vecsum.y;\r
+                       }\r
+                       io_vecsum.x=dxi;\r
+                       io_vecsum.y=dyi;\r
+                       return true;            \r
+               }\r
+               \r
+               \r
+               private NyARDoublePoint2d __work_pos=new NyARDoublePoint2d();\r
+               \r
+               private boolean getSquareLine(NyARGrayscaleRaster i_raster,int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord,int i_cood_num, NyARSquare o_square) throws NyARException\r
+               {\r
+                       final NyARLinear[] l_line = o_square.line;\r
+                       final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
+                       final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
+                       final NyARDoublePoint2d idealcenter=this.__work_pos;\r
+               \r
+                       NyARIntPoint2d vecsum=new NyARIntPoint2d();\r
+                       for (int i = 0; i < 4; i++){\r
+                               //頂点を取得\r
+                               int ver1=i_mkvertex[i];\r
+                               int ver2=i_mkvertex[(i+1)%4];\r
+\r
+                               int n,st,ed;\r
+                               double w1;\r
+                               //探索区間の決定\r
+                               if(ver2>=i_mkvertex[i]){\r
+                                       //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+                                       w1 = (double) (ver2 - ver1 + 1) * 0.05 + 0.5;\r
+                                       //探索区間の決定\r
+                                       st = (int) (ver1+w1);\r
+                                       ed = (int) (ver2 - w1);\r
+                               }else{\r
+                                       //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+                                       w1 = (double) (ver2+i_cood_num-ver1+1)%i_cood_num * 0.05 + 0.5;\r
+                                       //探索区間の決定\r
+                                       st = (int) (ver1+w1)%i_cood_num;\r
+                                       ed = (int) (ver2+i_cood_num-w1)%i_cood_num;\r
+                               }\r
+                               vecsum.x=vecsum.y=0;\r
+                               //ベクトル分析\r
+                               if(st<=ed){\r
+                                       //1区間\r
+                                       n = ed - st+1;\r
+                                       addCoordVecPos(i_raster,i_xcoord,i_ycoord,st,ed+1,vecsum);\r
+                                       this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,st,n,idealcenter);\r
+                               }else{\r
+                                       //探索区間は2区間\r
+                                       double cx,cy;\r
+                                       n=ed+i_cood_num-st+1;\r
+                                       addCoordVecPos(i_raster,i_xcoord,i_ycoord,st,i_cood_num,vecsum);\r
+                                       addCoordVecPos(i_raster,i_xcoord,i_ycoord,0,ed,vecsum);\r
+                                       //輪郭の中心位置を計算\r
+                                       this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,st,i_cood_num-st,idealcenter);\r
+                                       cx=idealcenter.x;\r
+                                       cy=idealcenter.y;\r
+                                       this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,0,ed+1,idealcenter);\r
+                                       idealcenter.x=(idealcenter.x+cx)/2;\r
+                                       idealcenter.y=(idealcenter.y+cy)/2;\r
+                               }\r
+                               //中央値を歪修正(ほんとはピクセル単位にゆがみ矯正するべきだと思う)\r
+                               \r
+                               double l=Math.sqrt((double)(vecsum.x*vecsum.x+vecsum.y*vecsum.y));\r
+                               final NyARLinear l_line_i = l_line[i];\r
+                               //直交するベクトルを計算\r
+                               l_line_i.a =  vecsum.x/l;\r
+                               l_line_i.b =  -vecsum.y/l;\r
+                               //cを計算\r
+                               l_line_i.c  = -(l_line_i.a * (idealcenter.x) + l_line_i.b * (idealcenter.y));\r
+                               \r
+                               // 頂点インデクスから頂点座標を得て保存\r
+                               l_imvertex[i].x = i_xcoord[ver1];\r
+                               l_imvertex[i].y = i_ycoord[ver1];\r
+                       }\r
+                       //線分式から頂点を計算\r
+                       for(int i=0;i<4;i++)\r
+                       {\r
+                               if(!NyARLinear.crossPos(l_line[i],l_line[(i + 3) % 4],l_sqvertex[i])){\r
+                                       return false;\r
+                               }\r
+                       }               \r
+                       return true;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * 輪郭線の中心位置を計算する関数を追加したマップクラス\r
+        */\r
+       private class NyARObserv2IdealMap2 extends NyARObserv2IdealMap\r
+       {\r
+               public NyARObserv2IdealMap2(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)\r
+               {\r
+                       super(i_distfactor,i_screen_size);\r
+               }\r
+               /**\r
+                * 歪み矯正した座標における、各座標の合計値を\r
+                * @param i_x_coord\r
+                * @param i_y_coord\r
+                * @param i_start\r
+                * @param i_num\r
+                * @param o_center\r
+                */\r
+               public void getIdealCoodCenter(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num,NyARDoublePoint2d o_center)\r
+               {\r
+                       int idx;\r
+                       double x,y;\r
+                       x=y=0;\r
+                       final double[] mapx=this._mapx;\r
+                       final double[] mapy=this._mapy;\r
+                       final int stride=this._stride;\r
+                       for (int j = 0; j < i_num; j++){\r
+                               idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*stride;\r
+                               x+=mapx[idx];\r
+                               y+=mapy[idx];\r
+                       }\r
+                       o_center.x=x/(double)i_num;\r
+                       o_center.y=y/(double)i_num;\r
+                       return;\r
+               }\r
+       }       \r
+}\r
+\r
+\r
+\r
diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/OptimizeCompareTest.java
new file mode 100644 (file)
index 0000000..beeefc6
--- /dev/null
@@ -0,0 +1,293 @@
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+import com.sun.opengl.util.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+/**\r
+ * 2種類の最適化アルゴリズムを比較するテストプログラム\r
+ *\r
+ */\r
+\r
+class Program implements JmfCaptureListener\r
+{\r
+       private OptimizeCompareTest _view1;\r
+       private OptimizeCompareTest _view2;\r
+       public Object _sync_object=new Object();        \r
+       public NyARParam _ar_param;\r
+       public NyARCode _ar_code;\r
+       private final static int SCREEN_X = 320;\r
+       private final static int SCREEN_Y = 240;\r
+       private JmfCaptureDevice _capture;\r
+       public GLNyARRaster_RGB _cap_image;\r
+       public Program(NyARParam i_param, NyARCode i_ar_code) throws NyARException\r
+       {\r
+               // キャプチャの準備\r
+               JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();\r
+               this._capture = devlist.getDevice(0);\r
+               if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) {\r
+                       throw new NyARException();\r
+               }\r
+               this._ar_param=i_param;\r
+               this._ar_code=i_ar_code;\r
+               this._capture.setOnCapture(this);\r
+               // GL対応のRGBラスタオブジェクト\r
+               this._cap_image = new GLNyARRaster_RGB(i_param, this._capture.getCaptureFormat());      \r
+               this._view1=new OptimizeCompareTest(this,NyARSingleDetectMarker.PF_NYARTOOLKIT);\r
+               this._view2=new OptimizeCompareTest(this,NyARSingleDetectMarker.PF_NYARTOOLKIT_ARTOOLKIT_FITTING);\r
+               this._capture.start();\r
+               return;\r
+       }\r
+       public void onUpdateBuffer(Buffer i_buffer)\r
+       {\r
+               try {\r
+                       synchronized (this._sync_object) {\r
+                               this._cap_image.setBuffer(i_buffer);\r
+                               this._view1.updateCapture(this._cap_image);\r
+                               this._view2.updateCapture(this._cap_image);\r
+                       }\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+       //GL API\r
+       void glDrawCube(GL i_gl)\r
+       {\r
+               // Colour cube data.\r
+               int polyList = 0;\r
+               float fSize = 0.5f;// マーカーサイズに対して0.5倍なので、4cmの立方体\r
+               int f, i;\r
+               float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+               float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+               int cube_num_faces = 6;\r
+               short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+               if (polyList == 0) {\r
+                       polyList = i_gl.glGenLists(1);\r
+                       i_gl.glNewList(polyList, GL.GL_COMPILE);\r
+                       i_gl.glBegin(GL.GL_QUADS);\r
+                       for (f = 0; f < cube_num_faces; f++)\r
+                               for (i = 0; i < 4; i++) {\r
+                                       i_gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+                                       i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+                               }\r
+                       i_gl.glEnd();\r
+                       i_gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+                       for (f = 0; f < cube_num_faces; f++) {\r
+                               i_gl.glBegin(GL.GL_LINE_LOOP);\r
+                               for (i = 0; i < 4; i++)\r
+                                       i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+                               i_gl.glEnd();\r
+                       }\r
+                       i_gl.glEndList();\r
+               }\r
+\r
+               i_gl.glPushMatrix(); // Save world coordinate system.\r
+               i_gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+               i_gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+               i_gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+               i_gl.glCallList(polyList); // Draw the cube.\r
+               i_gl.glPopMatrix(); // Restore world coordinate system.\r
+               return;\r
+       }\r
+       \r
+}\r
+/**\r
+ * simpleLiteと同じようなテストプログラム 出来る限りARToolKitのサンプルと似せて作ってあります。 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
+ * \r
+ */\r
+public class OptimizeCompareTest implements GLEventListener\r
+{\r
+       private final static int SCREEN_X = 320;\r
+\r
+       private final static int SCREEN_Y = 240;\r
+\r
+       private Animator _animator;\r
+       \r
+       private Program _parent;\r
+\r
+\r
+//     private JmfCaptureDevice _capture;\r
+\r
+       private GL _gl;\r
+       private NyARGLUtil _glnya;\r
+\r
+       // NyARToolkit関係\r
+       private NyARSingleDetectMarker _nya;\r
+       private NyARParam _ar_param;\r
+\r
+       private double[] _camera_projection = new double[16];\r
+\r
+\r
+       public OptimizeCompareTest(Program i_program,int i_pf) throws NyARException\r
+       {\r
+               this._parent=i_program;\r
+               this._ar_param = i_program._ar_param;\r
+\r
+               Frame frame = new Frame("["+i_pf+"]");\r
+\r
+               // NyARToolkitの準備\r
+               this._nya = new NyARSingleDetectMarker(this._ar_param, i_program._ar_code, 80.0,i_program._cap_image.getBufferType(),i_pf);\r
+               this._nya.setContinueMode(true);// ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+               \r
+               // 3Dを描画するコンポーネント\r
+               GLCanvas canvas = new GLCanvas();\r
+               frame.add(canvas);\r
+               canvas.addGLEventListener(this);\r
+               frame.addWindowListener(new WindowAdapter() {\r
+                       public void windowClosing(WindowEvent e)\r
+                       {\r
+                               System.exit(0);\r
+                       }\r
+               });\r
+\r
+               frame.setVisible(true);\r
+               Insets ins = frame.getInsets();\r
+               frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+               canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+       }\r
+\r
+       public void init(GLAutoDrawable drawable)\r
+       {\r
+               this._gl = drawable.getGL();\r
+               this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+               this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+               // NyARToolkitの準備\r
+               try {\r
+                       // NyARToolkit用の支援クラス\r
+                       _glnya = new NyARGLUtil(_gl);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+               // カメラパラメータの計算\r
+               this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+               this._animator = new Animator(drawable);\r
+               this._animator.start();\r
+               return;\r
+       }\r
+\r
+       public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+       {\r
+               _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+               _gl.glViewport(0, 0, width, height);\r
+\r
+               // 視体積の設定\r
+               _gl.glMatrixMode(GL.GL_PROJECTION);\r
+               _gl.glLoadIdentity();\r
+               // 見る位置\r
+               _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+               _gl.glLoadIdentity();\r
+       }\r
+\r
+       private boolean _is_marker_exist=false;\r
+       private NyARTransMatResult __display_transmat_result = new NyARTransMatResult();\r
+\r
+       private double[] __display_wk = new double[16];\r
+\r
+       public void display(GLAutoDrawable drawable)\r
+       {\r
+               NyARTransMatResult transmat_result = __display_transmat_result;\r
+               if (!this._parent._cap_image.hasData()) {\r
+                       return;\r
+               }\r
+               // 背景を書く\r
+               this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+               this._glnya.drawBackGround(this._parent._cap_image, 1.0);                       \r
+               try{\r
+                       synchronized(this._parent._sync_object){\r
+                               // マーカーがあれば、立方体を描画\r
+                               if (this._is_marker_exist){\r
+                                       // マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+                                       // Projection transformation.\r
+                                       _gl.glMatrixMode(GL.GL_PROJECTION);\r
+                                       _gl.glLoadMatrixd(_camera_projection, 0);\r
+                                       _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+                                       // Viewing transformation.\r
+                                       _gl.glLoadIdentity();\r
+                                       // 変換行列を取得\r
+                                       _nya.getTransmationMatrix(transmat_result);\r
+                                       // 変換行列をOpenGL形式に変換\r
+                                       _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+                                       _gl.glLoadMatrixd(__display_wk, 0);\r
+               \r
+                                       // All other lighting and geometry goes here.\r
+                                       this._parent.glDrawCube(_gl);\r
+                               }\r
+                       }\r
+                       Thread.sleep(1);// タスク実行権限を一旦渡す\r
+               }catch(Exception e){\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+       public void updateCapture(GLNyARRaster_RGB i_img)\r
+       {\r
+               try {\r
+                       synchronized (this._parent._sync_object) {\r
+                               this._is_marker_exist =this._nya.detectMarkerLite(i_img, 110);\r
+                       }\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+       {\r
+       }\r
+\r
+       private final static String CARCODE_FILE = "../Data/patt.hiro";\r
+\r
+       private final static String PARAM_FILE = "../Data/camera_para.dat";\r
+\r
+       public static void main(String[] args)\r
+       {\r
+               try {\r
+                       NyARParam param = new NyARParam();\r
+                       param.loadARParamFromFile(PARAM_FILE);\r
+                       param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+\r
+                       NyARCode code = new NyARCode(16, 16);\r
+                       code.loadARPattFromFile(CARCODE_FILE);\r
+\r
+                       new Program(param, code);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return;\r
+       }\r
+}\r
diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTest.java
new file mode 100644 (file)
index 0000000..d109faa
--- /dev/null
@@ -0,0 +1,232 @@
+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
+\r
+import java.awt.color.ColorSpace;\r
+import java.awt.image.*;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.util.Date;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPickup;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\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.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+import jp.nyatla.nyartoolkit.utils.j2se.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+\r
+\r
+public class PattPickupTest extends Frame implements JmfCaptureListener\r
+{\r
+       private final String PARAM_FILE = "../Data/camera_para.dat";\r
+\r
+       private final static String CARCODE_FILE = "../Data/patt.hiro";\r
+\r
+       private static final long serialVersionUID = -2110888320986446576L;\r
+\r
+       private JmfCaptureDevice _capture;\r
+\r
+       private JmfNyARRaster_RGB _capraster;\r
+\r
+       private int W = 320;\r
+\r
+       private int H = 240;\r
+\r
+       private NyARParam _param;\r
+\r
+       private NyARBinRaster _bin_raster;\r
+\r
+       private NyARSquareStack _stack = new NyARSquareStack(100);\r
+\r
+       private NyARSingleDetectMarker detect;\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, W, H, 30.0f)) {\r
+                       if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV, W, H, 30.0f)) {\r
+                               throw new NyARException("キャプチャフォーマットが見つかりません。");\r
+                       }\r
+               }\r
+               NyARParam ar_param = new NyARParam();\r
+               ar_param.loadARParamFromFile(PARAM_FILE);\r
+               ar_param.changeScreenSize(W, H);\r
+\r
+               NyARCode code = new NyARCode(16, 16);\r
+               code.loadARPattFromFile(CARCODE_FILE);\r
+               this._capraster = new JmfNyARRaster_RGB(W, H, this._capture.getCaptureFormat());\r
+               this.detect = new NyARSingleDetectMarker(ar_param, code, 80, this._capraster.getBufferType());\r
+               this._capture.setOnCapture(this);\r
+               this._bin_raster = new NyARBinRaster(W, H);\r
+               this._param = ar_param;\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 final String data_file = "../Data/320x240ABGR.raw";\r
+\r
+       private INyARColorPatt _patt1 = new NyARColorPatt_O3(16, 16);\r
+\r
+       public void draw(INyARRgbRaster i_raster)\r
+       {\r
+               try {\r
+                       Insets ins = this.getInsets();\r
+                       Graphics g = getGraphics();\r
+\r
+                       {// ピックアップ画像の表示\r
+                               // 矩形抽出\r
+                               INyARRasterFilter_Bin to_binfilter = new NyARRasterFilterBuilder_RgbToBin(110, i_raster.getBufferType());\r
+                               to_binfilter.doFilter(i_raster, this._bin_raster);\r
+                               if (this.detect.detectMarkerLite(i_raster, 100)) {\r
+\r
+                                       NyARTransMatResult res = new NyARTransMatResult();\r
+                                       this.detect.getTransmationMatrix(res);\r
+                                       int max_point = 0;\r
+\r
+                                       // NyARSquare t=new NyARSquare();\r
+\r
+                                               TransformedBitmapPickup patt2 = new TransformedBitmapPickup(this._param.getPerspectiveProjectionMatrix(), 100, 100, 1);\r
+\r
+                                               BufferedImage sink = new BufferedImage(this._patt1.getWidth(), this._patt1.getHeight(), ColorSpace.TYPE_RGB);\r
+                                               BufferedImage sink2 = new BufferedImage(patt2.getWidth(), patt2.getHeight(), ColorSpace.TYPE_RGB);\r
+                                               patt2.pickupImage2d(i_raster,-20,-40,20,-80,res);\r
+                                               /*\r
+                                                * t.imvertex[0].x=(int)483.0639377595418; t.imvertex[0].y=(int)303.17616747966747;\r
+                                                * \r
+                                                * t.imvertex[1].x=(int)506.1019505415998; t.imvertex[1].y=(int)310.5313224526344;\r
+                                                * \r
+                                                * t.imvertex[2].x=(int)589.3605435960492; t.imvertex[2].y=(int)258.46261716798523;\r
+                                                * \r
+                                                * t.imvertex[3].x=(int)518.1385869954609; t.imvertex[3].y=(int)325.1434618295405;\r
+                                                */\r
+                                               Graphics g1, g2, g3;\r
+                                       /*      {// ARToolkit\r
+                                                       // 一番それっぽいパターンを取得\r
+                                                       this._patt1.pickFromRaster(i_raster, t.imvertex);\r
+                                                       Date d2 = new Date();\r
+                                                       for (int i = 0; i < 10000; i++) {\r
+                                                               this._patt1.pickFromRaster(i_raster, t.imvertex);\r
+                                                       }\r
+                                                       Date d = new Date();\r
+                                                       System.out.println(d.getTime() - d2.getTime());\r
+\r
+                                                       // パターンを書く\r
+                                                       NyARRasterImageIO.copy(this._patt1, sink);\r
+                                                       g1 = sink.getGraphics();\r
+                                                       g1.setColor(Color.red);\r
+                                               }*/\r
+                                               {// 疑似アフィン変換\r
+                                                       NyARRasterImageIO.copy(patt2, sink2);\r
+                                                       g2 = sink2.getGraphics();\r
+                                                       g2.setColor(Color.red);\r
+\r
+                                               }\r
+                                               g.drawImage(sink, ins.left + 320, ins.top, 128, 128, null);\r
+                                               g.drawImage(sink2, ins.left + 320, ins.top + 128, 128, 128, null);\r
+                                               // g.drawImage(sink3, ins.left + 100, ins.top + 240, this._patt3.getWidth() * 10, this._patt3.getHeight() * 10, null);\r
+                                       \r
+                               }\r
+                               {// 撮影画像\r
+                                       BufferedImage sink = new BufferedImage(i_raster.getWidth(), i_raster.getHeight(), ColorSpace.TYPE_RGB);\r
+                                       NyARRasterImageIO.copy(i_raster, sink);\r
+                                       g.drawImage(sink, ins.left, ins.top, this);\r
+                               }\r
+\r
+                               {// 信号取得テスト\r
+\r
+                               }\r
+                       }\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public void onUpdateBuffer(Buffer i_buffer)\r
+       {\r
+               try {\r
+\r
+                       {// ピックアップ画像の表示\r
+                               // 矩形抽出\r
+                               this._capraster.setBuffer(i_buffer);\r
+                               draw(this._capraster);\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 void startImage()\r
+       {\r
+               try {\r
+                       // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+                       File f = new File(data_file);\r
+                       FileInputStream fs = new FileInputStream(data_file);\r
+                       byte[] buf = new byte[(int) f.length() * 4];\r
+                       fs.read(buf);\r
+                       INyARRgbRaster ra = NyARRgbRaster_BGRA.wrap(buf, W, H);\r
+                       draw(ra);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\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
+                       // mainwin.startImage();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java b/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/PattPickupTestS.java
new file mode 100644 (file)
index 0000000..53b56a9
--- /dev/null
@@ -0,0 +1,104 @@
+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.imageio.ImageIO;\r
+import javax.media.Buffer;\r
+import javax.media.format.VideoFormat;\r
+import javax.media.util.BufferToImage;\r
+\r
+import java.awt.color.ColorSpace;\r
+import java.awt.image.*;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.util.Date;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPickup;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\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.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+import jp.nyatla.nyartoolkit.sample.RawFileTest;\r
+import jp.nyatla.nyartoolkit.utils.j2se.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+\r
+\r
+public class PattPickupTestS extends Frame\r
+{\r
+       private final String code_file = "../Data/flarlogo.pat";\r
+\r
+       private final static String SAMPLE_FILES = "../Data/flarlogo_45.png";\r
+\r
+       private final String camera_file = "../Data/camera_para.dat";\r
+\r
+\r
+\r
+       public void Test_arDetectMarkerLite() throws Exception\r
+       {\r
+               // AR用カメラパラメタファイルをロード\r
+               NyARParam ap = new NyARParam();\r
+               ap.loadARParamFromFile(camera_file);\r
+\r
+\r
+               // AR用のパターンコードを読み出し\r
+               NyARCode code = new NyARCode(16, 16);\r
+               code.loadARPattFromFile(code_file);\r
+\r
+               // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+               BufferedImage src_image = ImageIO.read(new File(SAMPLE_FILES));\r
+               INyARRgbRaster ra  = new NyARRgbRaster_RGB(src_image.getWidth(),src_image.getHeight(),true);\r
+               NyARRasterImageIO.copy(src_image, ra);\r
+               \r
+               \r
+               // NyARToolkitの準備\r
+               ap.changeScreenSize(src_image.getWidth(),src_image.getHeight());\r
+\r
+\r
+               // Blank_Raster ra=new Blank_Raster(320, 240);\r
+\r
+               // 1パターンのみを追跡するクラスを作成\r
+               NyARSingleDetectMarker ar = new NyARSingleDetectMarker(\r
+                               ap, code, 80.0,ra.getBufferType(),NyARSingleDetectMarker.PF_NYARTOOLKIT);\r
+               NyARTransMatResult result_mat = new NyARTransMatResult();\r
+               ar.setContinueMode(false);\r
+               ar.detectMarkerLite(ra, 100);\r
+               ar.getTransmationMatrix(result_mat);\r
+\r
+               NyARDoublePoint3d ang=new NyARDoublePoint3d();\r
+               result_mat.getZXYAngle(ang);\r
+               NyARRasterImageIO.copy(((INyARColorPatt)(ar._getProbe()[0])),b);\r
+               \r
+       }\r
+       BufferedImage b=new BufferedImage(16,16,ColorSpace.TYPE_RGB);\r
+\r
+       public void drawImage(){\r
+               Graphics g=this.getGraphics();\r
+               g.drawImage(b,50,50,100,100,null);\r
+       };      \r
+       public static void main(String[] args)\r
+       {\r
+               try {\r
+                       PattPickupTestS app = new PattPickupTestS();\r
+                       app.setVisible(true);\r
+                       app.setBounds(0, 0, 640, 480);\r
+                       app.Test_arDetectMarkerLite();\r
+                       app.drawImage();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+}\r
diff --git a/sample/sandbox/src.dev/jp/nyatla/nyartoolkit/dev/Solver.java b/sample/sandbox/src.dev/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