OSDN Git Service

[backup]NyARToolkit for Java
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Sun, 15 Nov 2009 06:55:35 +0000 (06:55 +0000)
committernyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Sun, 15 Nov 2009 06:55:35 +0000 (06:55 +0000)
SquareContourDetectorの仕様を変更。輪郭線の正規化を不要にした。
関連するモジュールの修正。

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

trunk/src/jp/nyatla/nyartoolkit/core/param/NyARObserv2IdealMap.java
trunk/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareDetector_ARToolKit.java
trunk/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARSquareDetector_Rle.java
trunk/src/jp/nyatla/nyartoolkit/core/squaredetect/NyARVertexCounter.java
trunk/src/jp/nyatla/nyartoolkit/core/squaredetect/SquareContourDetector.java

index ca46d72..63f6cc0 100644 (file)
@@ -67,10 +67,10 @@ final public class NyARObserv2IdealMap
                o_point.y=this._mapy[idx];\r
                return;\r
        }\r
-       public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord)\r
+       public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord,int i_out_start_index)\r
        {\r
                int idx;\r
-               int ptr=0;\r
+               int ptr=i_out_start_index;\r
                for (int j = 0; j < i_num; j++) {\r
                        idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*this._stride;\r
                        o_x_coord[ptr]=this._mapx[idx];\r
index 4035399..6f6c591 100644 (file)
@@ -78,8 +78,8 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
 \r
                // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
                this._max_coord = number_of_coord;\r
-               this._xcoord = new int[number_of_coord * 2];\r
-               this._ycoord = new int[number_of_coord * 2];\r
+               this._xcoord = new int[number_of_coord];\r
+               this._ycoord = new int[number_of_coord];\r
                return;\r
        }\r
 \r
@@ -158,12 +158,9 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
                                // 輪郭が大きすぎる。\r
                                continue;\r
                        }\r
-                       //輪郭分析用に正規化する。\r
-                       final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
-\r
                        //ここから先が輪郭分析\r
                        NyARSquare square_ptr = o_square_stack.prePush();\r
-                       if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+                       if(!this._sqconvertor.coordToSquare(xcoord,ycoord,coord_num,label_area,square_ptr)){\r
                                o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
                                continue;                               \r
                        }\r
index c291c82..a8caba2 100644 (file)
@@ -75,10 +75,10 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
                // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
                int number_of_coord = (this._width + this._height) * 2;\r
 \r
-               // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+               // 輪郭バッファ\r
                this._max_coord = number_of_coord;\r
-               this._xcoord = new int[number_of_coord * 2];\r
-               this._ycoord = new int[number_of_coord * 2];\r
+               this._xcoord = new int[number_of_coord];\r
+               this._ycoord = new int[number_of_coord];\r
                return;\r
        }\r
 \r
@@ -112,8 +112,8 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
 \r
                final int xsize = this._width;\r
                final int ysize = this._height;\r
-               final int[] xcoord = this._xcoord;\r
-               final int[] ycoord = this._ycoord;\r
+               int[] xcoord = this._xcoord;\r
+               int[] ycoord = this._ycoord;\r
                final int coord_max = this._max_coord;\r
 \r
 \r
@@ -122,7 +122,7 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
 \r
                for (int i=0; i < label_num; i++) {\r
                        final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
-                       final int label_area = label_pt.area;\r
+                       int label_area = label_pt.area;\r
                \r
                        // クリップ領域が画面の枠に接していれば除外\r
                        if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
@@ -136,22 +136,23 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
                                // 重なっているようだ。\r
                                continue;\r
                        }\r
-                       \r
+\r
                        // 輪郭を取得\r
-                       final int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+                       int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
                        if (coord_num == coord_max) {\r
                                // 輪郭が大きすぎる。\r
                                continue;\r
                        }\r
-                       //輪郭分析用に正規化する。\r
-                       final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
+                       \r
+                       NyARSquare square_ptr = o_square_stack.prePush();\r
 \r
                        //ここから先が輪郭分析\r
-                       NyARSquare square_ptr = o_square_stack.prePush();\r
-                       if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+                       if(!this._sqconvertor.coordToSquare(xcoord,ycoord,coord_num,label_area,square_ptr)){\r
                                o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
                                continue;                               \r
                        }\r
+                                       \r
+                       \r
                        // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
                        overlap.push(label_pt);\r
                }\r
index b82940f..8aa1833 100644 (file)
@@ -46,13 +46,13 @@ final public class NyARVertexCounter
 \r
        private int[] y_coord;\r
 \r
-       public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, double i_thresh)\r
+       public boolean getVertex(int[] i_x_coord, int[] i_y_coord,int i_coord_len,int st, int ed, double i_thresh)\r
        {\r
                this.number_of_vertex = 0;\r
                this.thresh = i_thresh;\r
                this.x_coord = i_x_coord;\r
                this.y_coord = i_y_coord;\r
-               return get_vertex(st, ed);\r
+               return get_vertex(st, ed,i_coord_len);\r
        }\r
 \r
        /**\r
@@ -65,7 +65,7 @@ final public class NyARVertexCounter
         * @param thresh\r
         * @return\r
         */\r
-       private boolean get_vertex(int st, int ed)\r
+       private boolean get_vertex(int st, int ed,int i_coord_len)\r
        {\r
                //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。\r
                //dmaxは4乗なのでやるとしてもint64じゃないとマズイ\r
@@ -76,15 +76,36 @@ final public class NyARVertexCounter
                final int b = lx_coord[st] - lx_coord[ed];\r
                final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
                double dmax = 0;\r
-               for (int i = st + 1; i < ed; i++) {\r
-                       final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
-                       if (d * d > dmax) {\r
-                               dmax = d * d;\r
-                               v1 = i;\r
+               if(st<ed){\r
+                       //stとedが1区間\r
+                       for (int i = st + 1; i < ed; i++) {\r
+                               final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+                               if (d * d > dmax) {\r
+                                       dmax = d * d;\r
+                                       v1 = i;\r
+                               }\r
+                       }\r
+               }else{\r
+                       //stとedが2区間\r
+                       for (int i = st + 1; i < i_coord_len; i++) {\r
+                               final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+                               if (d * d > dmax) {\r
+                                       dmax = d * d;\r
+                                       v1 = i;\r
+                               }\r
+                       }\r
+                       for (int i = 0; i < ed; i++) {\r
+                               final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+                               if (d * d > dmax) {\r
+                                       dmax = d * d;\r
+                                       v1 = i;\r
+                               }\r
                        }\r
                }\r
+\r
+               \r
                if (dmax / (double)(a * a + b * b) > thresh) {\r
-                       if (!get_vertex(st, v1)) {\r
+                       if (!get_vertex(st, v1,i_coord_len)) {\r
                                return false;\r
                        }\r
                        if (number_of_vertex > 5) {\r
@@ -93,7 +114,7 @@ final public class NyARVertexCounter
                        vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
                        number_of_vertex++;// (*vnum)++;\r
 \r
-                       if (!get_vertex(v1, ed)) {\r
+                       if (!get_vertex(v1, ed,i_coord_len)) {\r
                                return false;\r
                        }\r
                }\r
index cb870b1..b45c814 100644 (file)
@@ -68,44 +68,64 @@ public class SquareContourDetector
                return;\r
        }\r
 \r
-       public boolean coordToSquare(int[] i_xcoord,int[] i_ycoord,int i_st_index,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException\r
+       public boolean coordToSquare(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
+               int vertex_1=getFarPoint(i_xcoord,i_ycoord,i_coord_num,0);\r
                // 頂点情報を取得\r
-               if (!getSquareVertex(i_xcoord, i_ycoord, i_st_index, i_coord_num, i_label_area, mkvertex)) {\r
+               if (!getSquareVertex(i_xcoord, i_ycoord, vertex_1, i_coord_num-1, i_label_area, mkvertex)) {\r
                        // 頂点の取得が出来なかったので破棄\r
                        return false;\r
                }\r
                // マーカーを検出\r
-               if (!getSquareLine(mkvertex, i_xcoord, i_ycoord, o_square)){\r
+               if (!getSquareLine(mkvertex, i_xcoord, i_ycoord,i_coord_num-1, o_square)){\r
                        // 矩形が成立しなかった。\r
                        return false;\r
                }\r
                return true;\r
        }\r
        \r
-       private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException\r
+       private boolean getSquareLine(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 NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
                final double[] mean=this.__getSquareLine_mean;\r
                final double[] ev=this.__getSquareLine_ev;\r
        \r
-               \r
-               for (int i = 0; i < 4; i++) {\r
-                       final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
-                       final int st = (int) (i_mkvertex[i] + w1);\r
-                       final int ed = (int) (i_mkvertex[i + 1] - w1);\r
-                       final int n = ed - st + 1;\r
+               double w1;              \r
+               for (int i = 0; i < 4; i++){\r
+                       int n,st,ed;\r
+                       //探索区間の決定\r
+                       if(i_mkvertex[i + 1]>=i_mkvertex[i]){\r
+                               //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+                               w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
+                               //探索区間の決定\r
+                               st = (int) (i_mkvertex[i]+w1);\r
+                               ed = (int) (i_mkvertex[i+1] - w1);\r
+                       }else{\r
+                               //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+                               w1 = (double) (i_mkvertex[i + 1]+i_cood_num-i_mkvertex[i]+1)%i_cood_num * 0.05 + 0.5;\r
+                               //探索区間の決定\r
+                               st = (int) (i_mkvertex[i]+w1)%i_cood_num;\r
+                               ed = (int) (i_mkvertex[i+1]+i_cood_num-w1)%i_cood_num;\r
+                       }\r
+                       //探索区間数を確認\r
+                       if(st<=ed){\r
+                               //探索区間は1区間\r
+                               n = ed - st + 1;\r
+                               this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,0);\r
+                       }else{\r
+                               //探索区間は2区間\r
+                               n=ed+1+i_cood_num-st;\r
+                               this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st,i_cood_num-st,this._xpos,this._ypos,0);\r
+                               this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, 0,ed+1,this._xpos,this._ypos,i_cood_num-st);\r
+                       }\r
+                       //要素数の確認\r
                        if (n < 2) {\r
                                // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
                                return false;\r
                        }\r
-                       //配列作成\r
-                       this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos);\r
-                       \r
                        //主成分分析する。\r
                        this._pca.pca(this._xpos,this._ypos,n,evec, ev,mean);\r
                        final NyARLinear l_line_i = l_line[i];\r
@@ -119,7 +139,7 @@ public class SquareContourDetector
                for (int i = 0; i < 4; i++) {\r
                        final NyARLinear l_line_i = l_line[i];\r
                        final NyARLinear l_line_2 = l_line[(i + 3) % 4];\r
-                       final double w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
+                       w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
                        if (w1 == 0.0) {\r
                                return false;\r
                        }\r
@@ -131,33 +151,22 @@ public class SquareContourDetector
                }\r
                return true;\r
        }       \r
+       \r
+\r
        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)\r
        {\r
                final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;\r
                final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;\r
-               final int end_of_coord = i_vertex1_index + i_coord_num - 1;\r
-               final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];\r
-               final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];\r
-               int dmax = 0;\r
-               int v1 = i_vertex1_index;\r
-               for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)\r
-                       // {\r
-                       final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);\r
-                       if (d > dmax) {\r
-                               dmax = d;\r
-                               v1 = i;\r
-                       }\r
-               }\r
+               int prev_vertex_index=(i_vertex1_index+i_coord_num)%i_coord_num;\r
+               int v1=getFarPoint(i_x_coord,i_y_coord,i_coord_num,i_vertex1_index);\r
                final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;\r
 \r
                o_vertex[0] = i_vertex1_index;\r
 \r
-               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)<\r
-                                                                                                                                                                       // 0 ) {\r
+               if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, i_vertex1_index, v1, thresh)) {\r
                        return false;\r
                }\r
-               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)\r
-                       // < 0) {\r
+               if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) {\r
                        return false;\r
                }\r
 \r
@@ -168,11 +177,15 @@ public class SquareContourDetector
                        o_vertex[3] = wv2.vertex[0];\r
                } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {\r
                        //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。\r
-                       v2 = (v1-i_vertex1_index)/2+i_vertex1_index;\r
-                       if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {\r
+                       if(v1>=i_vertex1_index){\r
+                               v2 = (v1-i_vertex1_index)/2+i_vertex1_index;\r
+                       }else{\r
+                               v2 = ((v1+i_coord_num-i_vertex1_index)/2+i_vertex1_index)%i_coord_num;\r
+                       }\r
+                       if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, i_vertex1_index, v2, thresh)) {\r
                                return false;\r
                        }\r
-                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {\r
+                       if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, v1, thresh)) {\r
                                return false;\r
                        }\r
                        if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
@@ -183,13 +196,17 @@ public class SquareContourDetector
                                return false;\r
                        }\r
                } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {\r
-                       //v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;\r
-                       v2 = (v1+ end_of_coord)/2;\r
-\r
-                       if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {\r
+                       //v2 = (v1+ end_of_coord)/2;\r
+                       if(v1<=prev_vertex_index){\r
+                               v2 = (v1+prev_vertex_index)/2;\r
+                       }else{\r
+                               v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num;\r
+                               \r
+                       }\r
+                       if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, v1, v2, thresh)) {\r
                                return false;\r
                        }\r
-                       if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {\r
+                       if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, prev_vertex_index, thresh)) {\r
                                return false;\r
                        }\r
                        if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
@@ -197,33 +214,41 @@ public class SquareContourDetector
                                o_vertex[2] = wv1.vertex[0];\r
                                o_vertex[3] = wv2.vertex[0];\r
                        } else {\r
+                               \r
                                return false;\r
                        }\r
                } else {\r
                        return false;\r
                }\r
-               o_vertex[4] = end_of_coord;\r
+               o_vertex[4] = prev_vertex_index;\r
                return true;\r
        }\r
-       \r
+\r
        /**\r
-        * 輪郭線の矩形検出開始ポイントを特定して、座標を並べ替えます。\r
-        * 輪郭線の先頭から、対角線が最長になる点を1点検索し、それより前の区間をバッファの後方に接続します。\r
-        * 戻り値は対角線が最長になった点です。関数終了後、返却値+i_coord_numの要素が有効になります。\r
+        * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。\r
         * @param i_xcoord\r
         * @param i_ycoord\r
         * @param i_coord_num\r
         * @return\r
         */\r
-       public static int normalizeCoord(int[] i_coord_x, int[] i_coord_y,int i_coord_num)\r
+       private static int getFarPoint(int[] i_coord_x, int[] i_coord_y,int i_coord_num,int i_point)\r
        {\r
                //\r
-               final int sx = i_coord_x[0];\r
-               final int sy = i_coord_y[0];\r
+               final int sx = i_coord_x[i_point];\r
+               final int sy = i_coord_y[i_point];\r
                int d = 0;\r
                int w, x, y;\r
                int ret = 0;\r
-               for (int i = 1; i < i_coord_num; i++) {\r
+               for (int i = i_point+1; i < i_coord_num; i++) {\r
+                       x = i_coord_x[i] - sx;\r
+                       y = i_coord_y[i] - sy;\r
+                       w = x * x + y * y;\r
+                       if (w > d) {\r
+                               d = w;\r
+                               ret = i;\r
+                       }\r
+               }\r
+               for (int i = 0; i < i_point; i++) {\r
                        x = i_coord_x[i] - sx;\r
                        y = i_coord_y[i] - sy;\r
                        w = x * x + y * y;\r
@@ -231,12 +256,7 @@ public class SquareContourDetector
                                d = w;\r
                                ret = i;\r
                        }\r
-                       // ここでうまく終了条件入れられないかな。\r
                }               \r
-               // vertex1を境界にして、後方に配列を連結\r
-               System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, ret);\r
-               System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, ret);\r
                return ret;\r
        }       \r
-       \r
 }
\ No newline at end of file