OSDN Git Service

[Backup]NyARToolkit for Java
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Thu, 27 Aug 2009 06:49:31 +0000 (06:49 +0000)
committernyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Thu, 27 Aug 2009 06:49:31 +0000 (06:49 +0000)
Rleラベリング演算の整数化

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

trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/qrcode/NyARQrCodeDetector.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/quadx2/NyARSquareDetector_Quad.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/vertexdetect/NyARVertexDetector.java
trunk/sample/sandbox/jp/nyatla/nyartoolkit/sandbox/x2/NyARSquareDetector_X2.java
trunk/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabeling_ARToolKit.java
trunk/src/jp/nyatla/nyartoolkit/core/labeling/rlelabeling/NyARLabeling_Rle.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/utils/NyObjectStack.java
trunk/test/jp/nyatla/nyartoolkit/dev/LabelingCamera.java

index a58acc8..623437a 100644 (file)
@@ -93,11 +93,10 @@ public class NyARQrCodeDetector implements INyARSquareDetector
                }\r
 \r
                final NyARLabelingLabelStack stack = limage.getLabelStack();\r
-               final NyARLabelingLabel[] labels = stack.getArray();\r
-\r
                // ラベルを大きい順に整列\r
                stack.sortByArea();\r
 \r
+               final NyARLabelingLabel[] labels = stack.getArray();\r
                // デカいラベルを読み飛ばし\r
                int i;\r
                for (i = 0; i < label_num; i++) {\r
index bce9c29..689861e 100644 (file)
@@ -125,12 +125,11 @@ public class NyARSquareDetector_Quad implements INyARSquareDetector
         }\r
 \r
         NyARLabelingLabelStack stack = limage.getLabelStack();\r
+               // ラベルを大きい順に整列\r
+               stack.sortByArea();\r
+        \r
         NyARLabelingLabel[] labels = stack.getArray();\r
 \r
-\r
-        // ラベルを大きい順に整列\r
-        stack.sortByArea();\r
-\r
         // デカいラベルを読み飛ばし\r
         int i;\r
         for (i = 0; i < label_num; i++)\r
index c2f03ba..09a34e7 100644 (file)
@@ -110,13 +110,13 @@ public class NyARVertexDetector implements INyARSquareDetector
                if (label_num < 1) {\r
                        return;\r
                }\r
+               \r
 \r
                final NyARLabelingLabelStack stack = limage.getLabelStack();\r
-               final NyARLabelingLabel[] labels = stack.getArray();\r
-               \r
-               \r
                // ラベルを大きい順に整列\r
                stack.sortByArea();\r
+               \r
+               final NyARLabelingLabel[] labels = stack.getArray();\r
 \r
                // デカいラベルを読み飛ばし\r
                int i;\r
index 00948d7..fd2eaf4 100644 (file)
@@ -47,9 +47,6 @@ import jp.nyatla.nyartoolkit.core.param.*;
  */\r
 public class NyARSquareDetector_X2 implements INyARSquareDetector\r
 {\r
-       private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
-\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
 \r
@@ -70,7 +67,7 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
        {\r
                this._width = i_size.w;\r
                this._height = i_size.h;\r
-               this._labeling = new NyARLabeling_Rle(this._width);\r
+               this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
                this._sqconvertor=new SquareContourDetector_X2(i_size,i_dist_factor_ref);\r
                this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
                \r
@@ -113,17 +110,10 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
                if (label_num < 1) {\r
                        return;\r
                }\r
-\r
+               //ラベルをソートしておく\r
+               flagment.sortByArea();\r
                RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
 \r
-               // デカいラベルを読み飛ばし\r
-               int i;\r
-               for (i = 0; i < label_num; i++) {\r
-                       // 検査対象内のラベルサイズになるまで無視\r
-                       if (labels[i].area <= AR_AREA_MAX) {\r
-                               break;\r
-                       }\r
-               }\r
 \r
                final int xsize = this._width;\r
                final int ysize = this._height;\r
@@ -134,14 +124,10 @@ public class NyARSquareDetector_X2 implements INyARSquareDetector
                //重なりチェッカの最大数を設定\r
                overlap.setMaxLabels(label_num);\r
 \r
-               for (; i < label_num; i++) {\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
-                       // 検査対象サイズよりも小さくなったら終了\r
-                       if (label_pt.area < AR_AREA_MIN) {\r
-                               break;\r
-                       }\r
-               \r
+\r
                        // クリップ領域が画面の枠に接していれば除外\r
                        if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
                                continue;\r
index 60c3cc5..ca07e31 100644 (file)
@@ -258,9 +258,7 @@ final public class NyARLabeling_ARToolKit
                        label_pt = labels[i];\r
                        label_pt.pos_x /= label_pt.area;\r
                        label_pt.pos_y /= label_pt.area;\r
-               }\r
-               // ラベルを大きい順に整列\r
-               label_list.sortByArea();                \r
+               }               \r
                return wlabel_num;\r
        }\r
 \r
index e01843c..a1b71db 100644 (file)
@@ -27,9 +27,33 @@ package jp.nyatla.nyartoolkit.core.labeling.rlelabeling;
 \r
 import jp.nyatla.nyartoolkit.NyARException;\r
 import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.utils.*;\r
 \r
+class RleInfoStack extends NyObjectStack<RleInfoStack.RleInfo>\r
+{\r
+       public class RleInfo\r
+       {\r
+               //継承メンバ\r
+               public int entry_x; // フラグメントラベルの位置\r
+               public int area;\r
+               public int clip_r;\r
+               public int clip_l;\r
+               public int clip_b;\r
+               public int clip_t;\r
+               public long pos_x;\r
+               public long pos_y;              \r
+       }       \r
+       public RleInfoStack(int i_length)\r
+       {\r
+               super(i_length, RleInfoStack.RleInfo.class);\r
+               return;\r
+       }\r
 \r
-\r
+       protected RleInfoStack.RleInfo createElement()\r
+       {\r
+               return new RleInfoStack.RleInfo();\r
+       }\r
+}\r
 /**\r
  * [strage class]\r
  */\r
@@ -53,14 +77,33 @@ class RleElement
 // RleImageをラベリングする。\r
 public class NyARLabeling_Rle\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
+       \r
+       private RleInfoStack _rlestack;\r
        private RleElement[] _rle1;\r
-\r
        private RleElement[] _rle2;\r
+       private int _max_area;\r
+       private int _min_area;\r
 \r
-       public NyARLabeling_Rle(int i_width)\r
+       public NyARLabeling_Rle(int i_width,int i_height)\r
        {\r
+               this._rlestack=new RleInfoStack(i_width*i_height*2048/(320*240)+32);\r
                this._rle1 = RleElement.createArray(i_width/2+1);\r
                this._rle2 = RleElement.createArray(i_width/2+1);\r
+               setAreaRange(AR_AREA_MAX,AR_AREA_MIN);\r
+\r
+               return;\r
+       }\r
+       /**\r
+        * 対象サイズ\r
+        * @param i_max\r
+        * @param i_min\r
+        */\r
+       public void setAreaRange(int i_max,int i_min)\r
+       {\r
+               this._max_area=i_max;\r
+               this._min_area=i_min;\r
                return;\r
        }\r
 \r
@@ -124,12 +167,12 @@ public class NyARLabeling_Rle
                return current;\r
        }\r
 \r
-       private void addFragment(RleElement i_rel_img, int i_nof, int i_row_index, int i_rel_index,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+       private void addFragment(RleElement i_rel_img, int i_nof, int i_row_index, int i_rel_index,RleInfoStack o_stack) throws NyARException\r
        {\r
                int l=i_rel_img.l;\r
                final int len=i_rel_img.r - l;\r
                i_rel_img.fid = i_nof;// REL毎の固有ID\r
-               RleLabelFragmentInfoStack.RleLabelFragmentInfo v = o_stack.prePush();\r
+               RleInfoStack.RleInfo v = o_stack.prePush();\r
                v.entry_x = l;\r
                v.area =len;\r
                v.clip_l=l;\r
@@ -146,7 +189,9 @@ public class NyARLabeling_Rle
        public int labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
        {\r
                // リセット処理\r
-               o_stack.clear();\r
+               final RleInfoStack rlestack=this._rlestack;\r
+               rlestack.clear();\r
+\r
                //\r
                RleElement[] rle_prev = this._rle1;\r
                RleElement[] rle_current = this._rle2;\r
@@ -162,12 +207,12 @@ public class NyARLabeling_Rle
                len_prev = toRel(in_buf, i_top, width, rle_prev);\r
                for (int i = 0; i < len_prev; i++) {\r
                        // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行\r
-                       addFragment(rle_prev[i], id_max, i_top, i,o_stack);\r
+                       addFragment(rle_prev[i], id_max, i_top, i,rlestack);\r
                        id_max++;\r
                        // nofの最大値チェック\r
                        label_count++;\r
                }\r
-               RleLabelFragmentInfoStack.RleLabelFragmentInfo[] f_array = o_stack.getArray();\r
+               RleInfoStack.RleInfo[] f_array = rlestack.getArray();\r
                // 次段結合\r
                for (int y = i_top + 1; y < i_bottom; y++) {\r
                        // カレント行の読込\r
@@ -185,14 +230,14 @@ public class NyARLabeling_Rle
                                                continue;\r
                                        } else if (rle_prev[index_prev].l - rle_current[i].r > 0) {// 0なら8方位ラベリングになる\r
                                                // prevがcur右方にある→独立フラグメント\r
-                                               addFragment(rle_current[i], id_max, y, i,o_stack);\r
+                                               addFragment(rle_current[i], id_max, y, i,rlestack);\r
                                                id_max++;\r
                                                label_count++;\r
                                                // 次のindexをしらべる\r
                                                continue SCAN_CUR;\r
                                        }\r
                                        id=rle_prev[index_prev].fid;//ルートフラグメントid\r
-                                       RleLabelFragmentInfoStack.RleLabelFragmentInfo id_ptr = f_array[id];\r
+                                       RleInfoStack.RleInfo id_ptr = f_array[id];\r
                                        //結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新\r
                                        rle_current[i].fid = id;//フラグメントIDを保存\r
                                        //\r
@@ -222,7 +267,7 @@ public class NyARLabeling_Rle
                                                \r
                                                //結合するルートフラグメントを取得\r
                                                final int prev_id =rle_prev[index_prev].fid;\r
-                                               RleLabelFragmentInfoStack.RleLabelFragmentInfo prev_ptr = f_array[prev_id];\r
+                                               RleInfoStack.RleInfo prev_ptr = f_array[prev_id];\r
                                                if (id != prev_id){\r
                                                        label_count--;\r
                                                        //prevとcurrentのフラグメントidを書き換える。\r
@@ -282,7 +327,7 @@ public class NyARLabeling_Rle
                                // curにidが割り当てられたかを確認\r
                                // 右端独立フラグメントを追加\r
                                if (id < 0){\r
-                                       addFragment(rle_current[i], id_max, y, i,o_stack);\r
+                                       addFragment(rle_current[i], id_max, y, i,rlestack);\r
                                        id_max++;\r
                                        label_count++;\r
                                }\r
@@ -293,18 +338,34 @@ public class NyARLabeling_Rle
                        len_prev = len_current;\r
                        rle_current = tmp;\r
                }\r
-               //ソートする。\r
-               o_stack.sortByArea();\r
-               //ラベル数を再設定\r
+               //対象のラベルだけ転写\r
                o_stack.reserv(label_count);\r
-               //posを計算\r
-               for(int i=0;i<label_count;i++){\r
-                       final RleLabelFragmentInfoStack.RleLabelFragmentInfo tmp=f_array[i];\r
-                       tmp.pos_x/=tmp.area;\r
-                       tmp.pos_y/=tmp.area;\r
+               RleLabelFragmentInfoStack.RleLabelFragmentInfo[] o_dest_array=o_stack.getArray();\r
+               final int max=this._max_area;\r
+               final int min=this._min_area;\r
+               int active_labels=0;\r
+               for(int i=id_max-1;i>=0;i--){\r
+                       final int area=f_array[i].area;\r
+                       if(area<min || area>max){//対象外のエリア0のもminではじく\r
+                               continue;\r
+                       }\r
+                       //\r
+                       final RleInfoStack.RleInfo src_info=f_array[i];\r
+                       final RleLabelFragmentInfoStack.RleLabelFragmentInfo dest_info=o_dest_array[active_labels];\r
+                       dest_info.area=area;\r
+                       dest_info.clip_b=src_info.clip_b;\r
+                       dest_info.clip_r=src_info.clip_r;\r
+                       dest_info.clip_t=src_info.clip_t;\r
+                       dest_info.clip_l=src_info.clip_l;\r
+                       dest_info.entry_x=src_info.entry_x;\r
+                       dest_info.pos_x=src_info.pos_x/src_info.area;\r
+                       dest_info.pos_y=src_info.pos_y/src_info.area;\r
+                       active_labels++;\r
                }\r
+               //ラベル数を再設定\r
+               o_stack.pops(label_count-active_labels);\r
                //ラベル数を返却\r
-               return label_count;\r
+               return active_labels;\r
        }       \r
 }\r
 \r
index 2dae3eb..94bff8f 100644 (file)
@@ -79,6 +79,9 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
                }\r
 \r
                final NyARLabelingLabelStack stack = limage.getLabelStack();\r
+               //ラベルをソートしておく\r
+               stack.sortByArea();\r
+               //\r
                final NyARLabelingLabel[] labels = stack.getArray();\r
 \r
                // デカいラベルを読み飛ばし\r
index 2912e08..97feab1 100644 (file)
@@ -37,9 +37,9 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
        {\r
                this._width = i_size.w;\r
                this._height = i_size.h;\r
-               //歪み計算テーブルを作ると、8*width/height*2の領域を消費します\r
-               //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
-               this._labeling = new NyARLabeling_Rle(this._width);\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(i_size,i_dist_factor_ref);\r
                this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
                \r
@@ -72,39 +72,29 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
                // マーカーホルダをリセット\r
                o_square_stack.clear();\r
 \r
-               // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
+               // ラベル数が0ならここまで\r
                final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
                if (label_num < 1) {\r
                        return;\r
                }\r
-               // ラベルを大きい順に整列\r
+               //ラベルをソートしておく\r
+               flagment.sortByArea();\r
+               //ラベルリストを取得\r
                RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
 \r
-               // デカいラベルを読み飛ばし\r
-               int i;\r
-               for (i = 0; i < label_num; i++) {\r
-                       // 検査対象内のラベルサイズになるまで無視\r
-                       if (labels[i].area <= AR_AREA_MAX) {\r
-                               break;\r
-                       }\r
-               }\r
-\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
                final int coord_max = this._max_coord;\r
 \r
+\r
                //重なりチェッカの最大数を設定\r
                overlap.setMaxLabels(label_num);\r
 \r
-               for (; i < label_num; i++) {\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
-                       // 検査対象サイズよりも小さくなったら終了\r
-                       if (label_pt.area < AR_AREA_MIN) {\r
-                               break;\r
-                       }\r
                \r
                        // クリップ領域が画面の枠に接していれば除外\r
                        if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
index 7ca6c3d..5644696 100644 (file)
@@ -92,17 +92,28 @@ public abstract class NyObjectStack<T>
         * 見かけ上の要素数を1減らして、最後尾のアイテムを返します。\r
         * @return\r
         */\r
-       public final T pop() throws NyARException\r
+       public final T pop()\r
        {\r
-               if(this._length<1){\r
-                       throw new NyARException();\r
-               }\r
+               assert(this._length>=1);\r
                this._length--;\r
-               return this.getItem(this._length);\r
+               return this._items[this._length];\r
        }\r
        /**\r
+        * 見かけ上の要素数をi_count個減らします。\r
+        * @param i_count\r
+        * @return\r
+        * NULLを返します。\r
+        */\r
+       public final void pops(int i_count)\r
+       {\r
+               assert(this._length>=i_count);\r
+               this._length-=i_count;\r
+               return;\r
+       }       \r
+       \r
+       /**\r
         * 0~i_number_of_item-1までの領域を予約します。\r
-        * 予約すると、見かけ上の要素数は0にリセットされます。\r
+        * 予約済の領域よりも小さい場合には、現在の長さを調整します。\r
         * @param i_number_of_reserv\r
         */\r
        final public void reserv(int i_number_of_item) throws NyARException\r
@@ -167,7 +178,6 @@ public abstract class NyObjectStack<T>
        {\r
                return this._length;\r
        }\r
-       \r
        /**\r
         * 見かけ上の要素数をリセットします。\r
         */\r
index 83ff9c5..8396b96 100644 (file)
@@ -368,10 +368,10 @@ class NyARQRCodeDetector implements INyARSquareDetector
                }
 
                final NyARLabelingLabelStack stack = limage.getLabelStack();
-               final NyARLabelingLabel[] labels = stack.getArray();
-
                // ラベルを大きい順に整列
                stack.sortByArea();
+               final NyARLabelingLabel[] labels = stack.getArray();
+
 
                // デカいラベルを読み飛ばし
                int i;