OSDN Git Service

[Backup]NyARToolkit for Java
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Wed, 19 Aug 2009 07:46:22 +0000 (07:46 +0000)
committernyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Wed, 19 Aug 2009 07:46:22 +0000 (07:46 +0000)
新型ラベリングの強化など

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

13 files changed:
trunk/src/jp/nyatla/nyartoolkit/core/labeling/LabelOverlapChecker.java [moved from trunk/src/jp/nyatla/nyartoolkit/core/squaredetect/LabelOverlapChecker.java with 76% similarity]
trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelInfo.java
trunk/src/jp/nyatla/nyartoolkit/core/labeling/NyARLabelInfoStack.java
trunk/src/jp/nyatla/nyartoolkit/core/labeling/artoolkit/NyARLabelingLabel.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/labeling/rlelabeling/RleLabelFragmentInfoStack.java
trunk/src/jp/nyatla/nyartoolkit/core/raster/rgb/NyARRgbRaster_BGRA.java
trunk/src/jp/nyatla/nyartoolkit/core/squaredetect/ContourPickup.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/j2se/BufferedImageSink.java [deleted file]
trunk/src/jp/nyatla/utils/j2se/NyARRasterImageIO.java [new file with mode: 0644]

  *     <airmail(at)ebony.plala.or.jp>\r
  * \r
  */\r
-package jp.nyatla.nyartoolkit.core.squaredetect;\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
 \r
-import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
+import java.lang.reflect.Array;\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
 \r
 /**\r
  * ラベル同士の重なり(内包関係)を調べるクラスです。 \r
  * ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。\r
  */\r
-public class LabelOverlapChecker\r
+public class LabelOverlapChecker<T extends NyARLabelInfo>\r
 {\r
-       private NyARLabelingLabel[] _labels = new NyARLabelingLabel[32];\r
+       private T[] _labels;\r
        private int _length;\r
-       public LabelOverlapChecker(int i_max_label)\r
+       private Class<T> _element_type;\r
+       /*\r
+       */\r
+       @SuppressWarnings("unchecked")\r
+       public LabelOverlapChecker(int i_max_label,Class<T> i_element_type)\r
        {\r
-               this._labels = new NyARLabelingLabel[i_max_label];\r
+               this._element_type=i_element_type;\r
+               this._labels = (T[])Array.newInstance(i_element_type, 32);\r
        }\r
 \r
        /**\r
@@ -51,7 +57,7 @@ public class LabelOverlapChecker
         * \r
         * @param i_label_ref\r
         */\r
-       public void push(NyARLabelingLabel i_label_ref)\r
+       public void push(T i_label_ref)\r
        {\r
                this._labels[this._length] = i_label_ref;\r
                this._length++;\r
@@ -63,10 +69,10 @@ public class LabelOverlapChecker
         * @param i_label\r
         * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.\r
         */\r
-       public boolean check(NyARLabelingLabel i_label)\r
+       public boolean check(T i_label)\r
        {\r
                // 重なり処理かな?\r
-               final NyARLabelingLabel[] label_pt = this._labels;\r
+               final T[] label_pt = this._labels;\r
                final int px1 = (int) i_label.pos_x;\r
                final int py1 = (int) i_label.pos_y;\r
                for (int i = this._length - 1; i >= 0; i--) {\r
@@ -86,10 +92,11 @@ public class LabelOverlapChecker
         * \r
         * @param i_max_label\r
         */\r
-       public void setMaxlabel(int i_max_label)\r
+       @SuppressWarnings("unchecked")\r
+       public void setMaxLabels(int i_max_label)\r
        {\r
                if (i_max_label > this._labels.length) {\r
-                       this._labels = new NyARLabelingLabel[i_max_label];\r
+                       this._labels = (T[])Array.newInstance(this._element_type, i_max_label);\r
                }\r
                this._length = 0;\r
        }       \r
index 6079691..549e0f7 100644 (file)
@@ -1,3 +1,34 @@
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ *   Hirokazu Kato\r
+ *   Mark Billinghurst\r
+ *   HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ * \r
+ * For further information please contact.\r
+ *     http://nyatla.jp/nyatoolkit/\r
+ *     <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
 package jp.nyatla.nyartoolkit.core.labeling;\r
 \r
 /**\r
@@ -7,4 +38,10 @@ package jp.nyatla.nyartoolkit.core.labeling;
 public class NyARLabelInfo\r
 {\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 double pos_x;\r
+       public double pos_y;\r
 }\r
index 156447a..ff70fa3 100644 (file)
@@ -51,6 +51,9 @@ public abstract class NyARLabelInfoStack<T extends NyARLabelInfo> extends NyObje
        final public void sortByArea()\r
        {\r
                int len=this._length;\r
+               if(len<1){\r
+                       return;\r
+               }\r
                int h = len *13/10;\r
                T[] item=this._items;\r
                for(;;){\r
@@ -71,6 +74,6 @@ public abstract class NyARLabelInfoStack<T extends NyARLabelInfo> extends NyObje
                        h=h*10/13;\r
                    }\r
                }               \r
-       } \r
+       }\r
 }\r
        \r
index 54bba59..c4c6c9f 100644 (file)
@@ -38,11 +38,6 @@ import jp.nyatla.nyartoolkit.core.labeling.*;
  */\r
 public class NyARLabelingLabel extends NyARLabelInfo\r
 {\r
-       public int id;\r
-       public int clip_r;// 0\r
-       public int clip_l;// 1\r
-       public int clip_b;// 2\r
-       public int clip_t;// 3\r
-       public double pos_x;\r
-       public double pos_y;\r
+       public int id; // フラグメントラベルのインデクス\r
+\r
 }\r
index 9de26f8..60c3cc5 100644 (file)
@@ -53,7 +53,7 @@ final public class NyARLabeling_ARToolKit
         * @param i_raster\r
         * @throws NyARException\r
         */\r
-       public void labeling(NyARBinRaster i_raster,NyARLabelingImage o_destination) throws NyARException\r
+       public int labeling(NyARBinRaster i_raster,NyARLabelingImage o_destination) throws NyARException\r
        {\r
                int label_img_ptr1, label_pixel;\r
                int i, j;\r
@@ -213,7 +213,7 @@ final public class NyARLabeling_ARToolKit
                if (wlabel_num == 0) {// if( *label_num == 0 ) {\r
                        // 発見数0\r
                        o_destination.getLabelStack().clear();\r
-                       return;\r
+                       return 0;\r
                }\r
                // ラベル情報の保存等\r
                NyARLabelingLabelStack label_list = o_destination.getLabelStack();\r
@@ -226,7 +226,7 @@ final public class NyARLabeling_ARToolKit
                NyARLabelingLabel[] labels =label_list.getArray();\r
                for (i = 0; i < wlabel_num; i++) {\r
                        label_pt = labels[i];\r
-                       label_pt.id = i + 1;\r
+                       label_pt.id = (short)(i + 1);\r
                        label_pt.area = 0;\r
                        label_pt.pos_x = label_pt.pos_y = 0;\r
                        label_pt.clip_l = lxsize;// wclip[i*4+0] = lxsize;\r
@@ -259,7 +259,9 @@ final public class NyARLabeling_ARToolKit
                        label_pt.pos_x /= label_pt.area;\r
                        label_pt.pos_y /= label_pt.area;\r
                }\r
-               return;\r
+               // ラベルを大きい順に整列\r
+               label_list.sortByArea();                \r
+               return wlabel_num;\r
        }\r
 \r
 }\r
index 8d412f2..7797c80 100644 (file)
@@ -18,7 +18,7 @@ class RleElement
 {\r
        int l;\r
        int r;\r
-       short id;\r
+       int fid;\r
        public static RleElement[] createArray(int i_length)\r
        {\r
                RleElement[] ret = new RleElement[i_length];\r
@@ -36,8 +36,6 @@ public class NyARLabeling_Rle
 \r
        private RleElement[] _rle2;\r
 \r
-       private short number_of_fragment; // 現在のフラグメントの数\r
-\r
        public NyARLabeling_Rle(int i_width)\r
        {\r
                this._rle1 = RleElement.createArray(i_width/2+1);\r
@@ -96,8 +94,8 @@ public class NyARLabeling_Rle
                                i_out[current].r = (r + 1);\r
                        } else {\r
                                // 最後の1点の場合\r
-                               i_out[current].l = (i_st + i_len - 1);\r
-                               i_out[current].r = (i_st + i_len);\r
+                               i_out[current].l = (i_len - 1);\r
+                               i_out[current].r = (i_len);\r
                        }\r
                        current++;\r
                }\r
@@ -105,31 +103,28 @@ public class NyARLabeling_Rle
                return current;\r
        }\r
 \r
-       private void addFragment(RleElement i_rel_img, short 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,RleLabelFragmentInfoStack 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.id = i_nof;// REL毎の固有ID\r
+               i_rel_img.fid = i_nof;// REL毎の固有ID\r
                RleLabelFragmentInfoStack.RleLabelFragmentInfo v = o_stack.prePush();\r
-               v.id = i_nof;\r
                v.entry_x = l;\r
                v.area =len;\r
                v.clip_l=l;\r
-               v.clip_r=i_rel_img.r;\r
+               v.clip_r=i_rel_img.r-1;\r
                v.clip_t=i_row_index;\r
                v.clip_b=i_row_index;\r
-               v.pos_x+=len*(2*l+(len-1)*1);\r
+               v.pos_x+=(len*(2*l+(len-1)))/2;\r
                v.pos_y+=i_row_index*len;\r
 \r
-               \r
                return;\r
        }\r
 \r
        //\r
-       public void labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+       public int labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
        {\r
                // リセット処理\r
-               this.number_of_fragment = 0;\r
                o_stack.clear();\r
                //\r
                RleElement[] rle_prev = this._rle1;\r
@@ -139,15 +134,17 @@ public class NyARLabeling_Rle
                final int width = i_bin_raster.getWidth();\r
                int[] in_buf = (int[]) i_bin_raster.getBufferReader().getBuffer();\r
 \r
-               short nof = this.number_of_fragment;\r
+               int id_max = 0;\r
+               int label_count=0;\r
                // 初段登録\r
 \r
                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], nof, i_top, i,o_stack);\r
-                       nof++;\r
+                       addFragment(rle_prev[i], id_max, i_top, i,o_stack);\r
+                       id_max++;\r
                        // nofの最大値チェック\r
+                       label_count++;\r
                }\r
                RleLabelFragmentInfoStack.RleLabelFragmentInfo[] f_array = o_stack.getArray();\r
                // 次段結合\r
@@ -158,7 +155,7 @@ public class NyARLabeling_Rle
 \r
                        SCAN_CUR: for (int i = 0; i < len_current; i++) {\r
                                // index_prev,len_prevの位置を調整する\r
-                               short id = -1;\r
+                               int id = -1;\r
                                // チェックすべきprevがあれば確認\r
                                SCAN_PREV: while (index_prev < len_prev) {\r
                                        if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
@@ -167,31 +164,29 @@ 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], nof, y, i,o_stack);\r
-                                               nof++;\r
+                                               addFragment(rle_current[i], id_max, y, i,o_stack);\r
+                                               id_max++;\r
+                                               label_count++;\r
                                                // 次のindexをしらべる\r
                                                continue SCAN_CUR;\r
                                        }\r
-                                       // 結合対象->prevのIDをコピーして、対象フラグメントの情報を更新\r
-                                       id = f_array[rle_prev[index_prev].id].id;\r
-                                       RleLabelFragmentInfoStack.RleLabelFragmentInfo prev_ptr;\r
-                                       final RleLabelFragmentInfoStack.RleLabelFragmentInfo id_ptr = f_array[id];\r
-                                       prev_ptr = f_array[rle_prev[index_prev].id];\r
-                                       rle_current[i].id = id;\r
+                                       id=rle_prev[index_prev].fid;//ルートフラグメントid\r
+                                       RleLabelFragmentInfoStack.RleLabelFragmentInfo id_ptr = f_array[id];\r
+                                       //結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新\r
+                                       rle_current[i].fid = id;//フラグメントIDを保存\r
                                        //\r
                                        final int l= rle_current[i].l;\r
                                        final int r= rle_current[i].r;\r
-                                       final int len=rle_current[i].r - rle_current[i].l;\r
+                                       final int len=r-l;\r
+                                       //結合先フラグメントの情報を更新する。\r
                                        id_ptr.area += len;\r
-                                       id_ptr.entry_x = prev_ptr.entry_x;\r
-                                       id_ptr.clip_l=l<prev_ptr.clip_l?l:prev_ptr.clip_l;\r
-                                       id_ptr.clip_r=r>prev_ptr.clip_r?r:prev_ptr.clip_r;\r
-                                       //id_ptr.clip_tは変更無し。\r
+                                       //tとentry_xは、結合先のを使うので更新しない。\r
+                                       id_ptr.clip_l=l<id_ptr.clip_l?l:id_ptr.clip_l;\r
+                                       id_ptr.clip_r=r>id_ptr.clip_r?r-1:id_ptr.clip_r;\r
                                        id_ptr.clip_b=y;\r
-                                       id_ptr.pos_x+=len*(2*l+(len-1)*1);\r
+                                       id_ptr.pos_x+=(len*(2*l+(len-1)))/2;\r
                                        id_ptr.pos_y+=y*len;\r
-                                       // 多重リンクの確認\r
-\r
+                                       //多重結合の確認(2個目以降)\r
                                        index_prev++;\r
                                        while (index_prev < len_prev) {\r
                                                if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
@@ -202,41 +197,65 @@ public class NyARLabeling_Rle
                                                        index_prev--;\r
                                                        continue SCAN_CUR;\r
                                                }\r
-                                               // prevとcurは連結している。\r
-                                               final short prev_id = rle_prev[index_prev].id;\r
-                                               prev_ptr = f_array[prev_id];\r
-                                               if (id != prev_id) {\r
-                                                       id_ptr.area += prev_ptr.area;\r
-                                                       prev_ptr.area = 0;\r
-                                                       // 結合対象->現在のidをインデクスにセット\r
-                                                       prev_ptr.id = id;\r
+                                               // prevとcurは連結している→ルートフラグメントの統合\r
+                                               \r
+                                               //結合するルートフラグメントを取得\r
+                                               final int prev_id =rle_prev[index_prev].fid;\r
+                                               RleLabelFragmentInfoStack.RleLabelFragmentInfo prev_ptr = f_array[prev_id];\r
+                                               if (id != prev_id){\r
+                                                       if(prev_ptr.area==0){\r
+                                                               System.out.println("ERRRR");\r
+                                                       }\r
+                                                       label_count--;\r
+                                                       //prevとcurrentのフラグメントidを書き換える。\r
+                                                       for(int i2=index_prev;i2<len_prev;i2++){\r
+                                                               //prevは現在のidから最後まで\r
+                                                               if(rle_prev[i2].fid==prev_id){\r
+                                                                       rle_prev[i2].fid=id;\r
+                                                               }\r
+                                                       }\r
+                                                       for(int i2=0;i2<i;i2++){\r
+                                                               //currentは0から現在-1まで\r
+                                                               if(rle_current[i2].fid==prev_id){\r
+                                                                       rle_current[i2].fid=id;\r
+                                                               }\r
+                                                       }\r
+                                                       \r
+                                                       //現在のルートフラグメントに情報を集約\r
+                                                       id_ptr.area +=prev_ptr.area;\r
+                                                       id_ptr.pos_x+=prev_ptr.pos_x;\r
+                                                       id_ptr.pos_y+=prev_ptr.pos_y;\r
                                                        //tとentry_xの決定\r
                                                        if (id_ptr.clip_t > prev_ptr.clip_t) {\r
                                                                // 現在の方が下にある。\r
                                                                id_ptr.clip_t = prev_ptr.clip_t;\r
                                                                id_ptr.entry_x = prev_ptr.entry_x;\r
                                                        }else if (id_ptr.clip_t < prev_ptr.clip_t) {\r
-                                                               // 現在の方が上にある。なにもしない。\r
+                                                               // 現在の方が上にある。prevにフィードバック\r
                                                        } else {\r
                                                                // 水平方向で小さい方がエントリポイント。\r
                                                                if (id_ptr.entry_x > prev_ptr.entry_x) {\r
                                                                        id_ptr.entry_x = prev_ptr.entry_x;\r
+                                                               }else{\r
                                                                }\r
-                                                       }                                                       \r
-                                                       //bの決定(現状のまま)\r
+                                                       }\r
                                                        //lの決定\r
                                                        if (id_ptr.clip_l > prev_ptr.clip_l) {\r
                                                                id_ptr.clip_l=prev_ptr.clip_l;\r
+                                                       }else{\r
                                                        }\r
                                                        //rの決定\r
                                                        if (id_ptr.clip_r < prev_ptr.clip_r) {\r
                                                                id_ptr.clip_r=prev_ptr.clip_r;\r
+                                                       }else{\r
                                                        }\r
-                                                       id_ptr.pos_x+=prev_ptr.pos_x;\r
-                                                       id_ptr.pos_y+=prev_ptr.pos_y;                                                   \r
-                                                       \r
+                                                       //bの決定\r
 \r
+                                                       //結合済のルートフラグメントを無効化する。\r
+                                                       prev_ptr.area=0;\r
                                                }\r
+\r
+\r
                                                index_prev++;\r
                                        }\r
                                        index_prev--;\r
@@ -244,9 +263,10 @@ public class NyARLabeling_Rle
                                }\r
                                // curにidが割り当てられたかを確認\r
                                // 右端独立フラグメントを追加\r
-                               if (id < 0) {\r
-                                       addFragment(rle_current[i], nof, y, i,o_stack);\r
-                                       nof++;\r
+                               if (id < 0){\r
+                                       addFragment(rle_current[i], id_max, y, i,o_stack);\r
+                                       id_max++;\r
+                                       label_count++;\r
                                }\r
                        }\r
                        // prevとrelの交換\r
@@ -255,8 +275,18 @@ public class NyARLabeling_Rle
                        len_prev = len_current;\r
                        rle_current = tmp;\r
                }\r
-               // フラグメントの数を更新\r
-               this.number_of_fragment = nof;\r
+               //ソートする。\r
+               o_stack.sortByArea();\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
+               }\r
+               //ラベル数を返却\r
+               return label_count;\r
        }       \r
 }\r
 \r
index 29697c2..0420ece 100644 (file)
@@ -11,14 +11,7 @@ public class RleLabelFragmentInfoStack  extends NyARLabelInfoStack<RleLabelFragm
        {\r
                //継承メンバ\r
                //int area; // フラグメントラベルの領域数\r
-               public short id; // フラグメントラベルのインデクス\r
                public int entry_x; // フラグメントラベルの位置\r
-               public int clip_t;\r
-               public int clip_l;\r
-               public int clip_r;\r
-               public int clip_b;\r
-               public double pos_x;\r
-               public double pos_y;\r
        }       \r
        public RleLabelFragmentInfoStack(int i_length)\r
        {\r
index 84d357d..c36f874 100644 (file)
@@ -71,7 +71,11 @@ public class NyARRgbRaster_BGRA extends NyARRgbRaster_BasicClass implements INyA
                }\r
                public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
                {\r
-                       NyARException.notImplement();           \r
+                       final byte[] ref_buf = this._parent._ref_buf;\r
+                       final int bp = (i_x + i_y * this._parent._size.w) * 4;\r
+                       ref_buf[bp+0] = (byte)i_rgb[0];// R\r
+                       ref_buf[bp+1] = (byte)i_rgb[1];// G\r
+                       ref_buf[bp+2] = (byte)i_rgb[2];// B     \r
                }\r
                public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
                {\r
index e25a7e3..af0c05d 100644 (file)
@@ -1,5 +1,10 @@
 package jp.nyatla.nyartoolkit.core.squaredetect;\r
-\r
+/*\r
+import java.awt.color.ColorSpace;\r
+import java.awt.image.BufferedImage;\r
+import java.io.*;\r
+import javax.imageio.*;\r
+import jp.nyatla.utils.j2se.*;*/\r
 import jp.nyatla.nyartoolkit.NyARException;\r
 import jp.nyatla.nyartoolkit.core.raster.*;\r
 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
@@ -32,16 +37,15 @@ public class ContourPickup
                final int width=i_raster.getWidth();\r
                final int height=i_raster.getHeight();\r
                //クリップ領域の上端に接しているポイントを得る。\r
-               int sx=i_entry_x;\r
-               int sy=i_entry_y;\r
+\r
 \r
                int coord_num = 1;\r
-               o_coord_x[0] = sx;\r
-               o_coord_y[0] = sy;\r
+               o_coord_x[0] = i_entry_x;\r
+               o_coord_y[0] = i_entry_y;\r
                int dir = 5;\r
 \r
-               int c = o_coord_x[0];\r
-               int r = o_coord_y[0];\r
+               int c = i_entry_x;\r
+               int r = i_entry_y;\r
                for (;;) {\r
                        dir = (dir + 5) % 8;//dirの正規化\r
                        //ここは頑張ればもっと最適化できると思うよ。\r
@@ -80,11 +84,19 @@ public class ContourPickup
                                        if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
                                                break;\r
                                        }\r
+/*\r
+                                       try{\r
+                                               BufferedImage b=new BufferedImage(width,height,ColorSpace.TYPE_RGB);\r
+                                               NyARRasterImageIO.copy(i_raster, b);\r
+                                       ImageIO.write(b,"png",new File("bug.png"));\r
+                                       }catch(Exception e){\r
+                                               \r
+                                       }*/\r
                                        //8方向全て調べたけどラベルが無いよ?\r
                                        throw new NyARException();                      \r
                                }\r
                        }else{\r
-                               //境界に接しているとき\r
+                               //境界に接しているとき                                \r
                                int i;\r
                                for (i = 0; i < 8; i++){                                \r
                                        final int x=c + xdir[dir];\r
@@ -111,7 +123,7 @@ public class ContourPickup
                        o_coord_x[coord_num] = c;\r
                        o_coord_y[coord_num] = r;\r
                        // 終了条件判定\r
-                       if (c == sx && r == sy){\r
+                       if (c == i_entry_x && r == i_entry_y){\r
                                coord_num++;\r
                                break;\r
                        }\r
@@ -222,6 +234,6 @@ public class ContourPickup
                        }\r
                }\r
                return coord_num;\r
-       }       \r
+       }\r
 \r
 }\r
index 44e5dbd..c2e2f13 100644 (file)
@@ -4,6 +4,7 @@ import jp.nyatla.nyartoolkit.NyARException;
 import jp.nyatla.nyartoolkit.core.INyARSquareDetector;\r
 import jp.nyatla.nyartoolkit.core.NyARSquare;\r
 import jp.nyatla.nyartoolkit.core.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
@@ -25,7 +26,7 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
 \r
        private final NyARLabelingImage _limage;\r
 \r
-       private final LabelOverlapChecker _overlap_checker = new LabelOverlapChecker(32);\r
+       private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
        private final SquareContourDetector _sqconvertor;\r
        private final ContourPickup _cpickup=new ContourPickup();\r
        \r
@@ -76,21 +77,14 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
                // マーカーホルダをリセット\r
                o_square_stack.clear();\r
 \r
-               // ラベリング\r
-               this._labeling.labeling(i_raster,this._limage);\r
-\r
-               // ラベル数が0ならここまで\r
-               final int label_num = limage.getLabelStack().getLength();\r
+               // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
+               final int label_num = this._labeling.labeling(i_raster,this._limage);\r
                if (label_num < 1) {\r
                        return;\r
                }\r
 \r
                final NyARLabelingLabelStack stack = limage.getLabelStack();\r
                final NyARLabelingLabel[] labels = stack.getArray();\r
-               \r
-               \r
-               // ラベルを大きい順に整列\r
-               stack.sortByArea();\r
 \r
                // デカいラベルを読み飛ばし\r
                int i;\r
@@ -106,17 +100,14 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
                final int[] xcoord = this._xcoord;\r
                final int[] ycoord = this._ycoord;\r
                final int coord_max = this._max_coord;\r
-               final LabelOverlapChecker overlap = this._overlap_checker;\r
-               int coord_num;\r
-               int label_area;\r
-               NyARLabelingLabel label_pt;\r
+               final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
 \r
                //重なりチェッカの最大数を設定\r
-               overlap.setMaxlabel(label_num);\r
+               overlap.setMaxLabels(label_num);\r
 \r
                for (; i < label_num; i++) {\r
-                       label_pt = labels[i];\r
-                       label_area = label_pt.area;\r
+                       final NyARLabelingLabel label_pt = labels[i];\r
+                       final int label_area = label_pt.area;\r
                        // 検査対象サイズよりも小さくなったら終了\r
                        if (label_area < AR_AREA_MIN) {\r
                                break;\r
@@ -134,7 +125,7 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
                                continue;\r
                        }\r
                        // 輪郭を取得\r
-                       coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
+                       final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
                        if (coord_num == coord_max) {\r
                                // 輪郭が大きすぎる。\r
                                continue;\r
@@ -150,7 +141,7 @@ public class NyARSquareDetector_ARToolKit implements INyARSquareDetector
                        }\r
                        // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
                        overlap.push(label_pt);\r
-               }       \r
+               }\r
                return;\r
        }\r
 \r
index 112092e..a94189c 100644 (file)
@@ -1,10 +1,13 @@
 package jp.nyatla.nyartoolkit.core.squaredetect;\r
 \r
 \r
+import java.util.Date;\r
+\r
 import jp.nyatla.nyartoolkit.NyARException;\r
 import jp.nyatla.nyartoolkit.core.INyARSquareDetector;\r
 import jp.nyatla.nyartoolkit.core.NyARSquare;\r
 import jp.nyatla.nyartoolkit.core.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
 import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
 import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
 import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
@@ -21,14 +24,14 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
 \r
        private final NyARLabeling_Rle _labeling;\r
 \r
-       private final LabelOverlapChecker _overlap_checker = new LabelOverlapChecker(32);\r
+       private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
        private final SquareContourDetector _sqconvertor;\r
        private final ContourPickup _cpickup=new ContourPickup();\r
        private final RleLabelFragmentInfoStack _stack;\r
        \r
        private final int _max_coord;\r
        private final int[] _xcoord;\r
-       private final int[] _ycoord;    \r
+       private final int[] _ycoord;\r
        /**\r
         * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
         * \r
@@ -42,7 +45,7 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
                //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
                this._labeling = new NyARLabeling_Rle(this._width);\r
                this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
-               this._stack=new RleLabelFragmentInfoStack(1024);//検出可能な最大ラベル数\r
+               this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
                \r
 \r
                // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
@@ -68,22 +71,17 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
        public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
        {\r
                final RleLabelFragmentInfoStack flagment=this._stack;\r
+               final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
 \r
                // マーカーホルダをリセット\r
                o_square_stack.clear();\r
 \r
-               // ラベリング\r
-               this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
-\r
-               // ラベル数が0ならここまで\r
-               final int label_num = flagment.getLength();\r
+               // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\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
                // ラベルを大きい順に整列\r
-               flagment.sortByArea();\r
                RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
 \r
                // デカいラベルを読み飛ばし\r
@@ -95,36 +93,38 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
                        }\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
-               int coord_num;\r
-               int label_area;\r
 \r
                //重なりチェッカの最大数を設定\r
-//             overlap.setMaxlabel(label_num);\r
+               overlap.setMaxLabels(label_num);\r
 \r
                for (; i < label_num; i++) {\r
                        final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
-                       label_area = label_pt.area;\r
+                       final int label_area = label_pt.area;\r
                        // 検査対象サイズよりも小さくなったら終了\r
-                       if (label_area < AR_AREA_MIN) {\r
+                       if (label_pt.area < AR_AREA_MIN) {\r
                                break;\r
                        }\r
-//                     // クリップ領域が画面の枠に接していれば除外\r
-//                     if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
-//                             continue;\r
-//                     }\r
-//                     if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
-//                             continue;\r
-//                     }\r
-//                     // 既に検出された矩形との重なりを確認\r
-//                     if (!overlap.check(label_pt)) {\r
-//                             // 重なっているようだ。\r
-//                             continue;\r
-//                     }\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
-                       coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+                       final 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
@@ -139,10 +139,18 @@ public class NyARSquareDetector_Rle implements INyARSquareDetector
                                continue;                               \r
                        }\r
                        // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
-//                     overlap.push(label_pt);\r
-               }       \r
+                       overlap.push(label_pt);\r
+               }\r
                return;\r
        }\r
+       /**\r
+        * デバック用API\r
+        * @return\r
+        */\r
+       public RleLabelFragmentInfoStack _getFragmentStack()\r
+       {\r
+               return this._stack;\r
+       }\r
 \r
 }\r
 \r
diff --git a/trunk/src/jp/nyatla/utils/j2se/BufferedImageSink.java b/trunk/src/jp/nyatla/utils/j2se/BufferedImageSink.java
deleted file mode 100644 (file)
index e13adf8..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-package jp.nyatla.utils.j2se;\r
-\r
-import java.awt.Color;\r
-import java.awt.image.*;\r
-import jp.nyatla.nyartoolkit.*;\r
-import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
-import jp.nyatla.nyartoolkit.core.raster.*;\r
-import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
-\r
-public class BufferedImageSink extends BufferedImage\r
-{\r
-       public BufferedImageSink(int i_width,int i_height)\r
-       {\r
-               super(i_width,i_height,TYPE_INT_RGB);\r
-       }\r
-       /**\r
-        * i_inの内容を、このイメージにコピーします。\r
-        * @param i_in\r
-        * @throws NyARException\r
-        */\r
-       public void copyFromRaster(INyARRgbRaster i_in) throws NyARException\r
-       {\r
-               assert i_in.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
-               \r
-               //thisへ転写\r
-               INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
-               int[] rgb=new int[3];\r
-\r
-               for(int y=this.getHeight()-1;y>=0;y--){\r
-                       for(int x=this.getWidth()-1;x>=0;x--){\r
-                               reader.getPixel(x,y,rgb);\r
-                               this.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
-                       }\r
-               }\r
-               return;\r
-       }\r
-       /**\r
-        * BIN_8用\r
-        * @param i_in\r
-        * @throws NyARException\r
-        */\r
-       public void copyFromRaster(INyARRaster i_in) throws NyARException\r
-       {\r
-               assert i_in.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
-               if(i_in.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
-               {\r
-                       final int[] buf=(int[])i_in.getBufferReader().getBuffer();\r
-                       final int w=this.getWidth();\r
-                       final int h=this.getHeight();\r
-                       for(int y=h-1;y>=0;y--){\r
-                               for(int x=w-1;x>=0;x--){\r
-                                       this.setRGB(x, y,buf[x+y*w]==0?0:0xffffff);\r
-                               }\r
-                       }\r
-               }\r
-               return;\r
-       }       \r
-       /**\r
-        * i_outへこのイメージを出力します。\r
-        * \r
-        * @param i_out\r
-        * @throws NyARException\r
-        */\r
-       public void copyToRaster(INyARRgbRaster i_out) throws NyARException\r
-       {\r
-               assert i_out.getSize().isEqualSize(this.getWidth(), this.getHeight());\r
-               \r
-               //thisへ転写\r
-               INyARRgbPixelReader reader=i_out.getRgbPixelReader();\r
-               int[] rgb=new int[3];\r
-               for(int y=this.getHeight()-1;y>=0;y--){\r
-                       for(int x=this.getWidth()-1;x>=0;x--){\r
-                               int pix=this.getRGB(x, y);\r
-                               rgb[0]=(pix>>16)&0xff;\r
-                               rgb[1]=(pix>>8)&0xff;\r
-                               rgb[2]=(pix)&0xff;\r
-                               reader.setPixel(x,y,rgb);\r
-                       }\r
-               }\r
-               return;\r
-       }\r
-}\r
diff --git a/trunk/src/jp/nyatla/utils/j2se/NyARRasterImageIO.java b/trunk/src/jp/nyatla/utils/j2se/NyARRasterImageIO.java
new file mode 100644 (file)
index 0000000..aee0fe2
--- /dev/null
@@ -0,0 +1,98 @@
+package jp.nyatla.utils.j2se;\r
+\r
+import java.awt.image.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+public class NyARRasterImageIO\r
+{\r
+       /**\r
+        * i_inの内容を、このイメージにコピーします。\r
+        * @param i_in\r
+        * @throws NyARException\r
+        */\r
+       public static void copy(INyARRgbRaster i_in,BufferedImage o_out) throws NyARException\r
+       {\r
+               assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+               \r
+               //thisへ転写\r
+               INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
+               int[] rgb=new int[3];\r
+\r
+               for(int y=o_out.getHeight()-1;y>=0;y--){\r
+                       for(int x=o_out.getWidth()-1;x>=0;x--){\r
+                               reader.getPixel(x,y,rgb);\r
+                               o_out.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * BIN_8用\r
+        * @param i_in\r
+        * @throws NyARException\r
+        */\r
+       public static void copy(INyARRaster i_in,BufferedImage o_out) throws NyARException\r
+       {\r
+               assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+               if(i_in.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
+               {\r
+                       final int[] buf=(int[])i_in.getBufferReader().getBuffer();\r
+                       final int w=o_out.getWidth();\r
+                       final int h=o_out.getHeight();\r
+                       for(int y=h-1;y>=0;y--){\r
+                               for(int x=w-1;x>=0;x--){\r
+                                       o_out.setRGB(x, y,buf[x+y*w]==0?0:0xffffff);\r
+                               }\r
+                       }\r
+               }\r
+               return;\r
+       }       \r
+       /**\r
+        * i_outへこのイメージを出力します。\r
+        * \r
+        * @param i_out\r
+        * @throws NyARException\r
+        */\r
+       public static void copy(BufferedImage i_in,INyARRgbRaster o_out) throws NyARException\r
+       {\r
+               assert o_out.getSize().isEqualSize(i_in.getWidth(), i_in.getHeight());\r
+               \r
+               //thisへ転写\r
+               INyARRgbPixelReader reader=o_out.getRgbPixelReader();\r
+               int[] rgb=new int[3];\r
+               for(int y=i_in.getHeight()-1;y>=0;y--){\r
+                       for(int x=i_in.getWidth()-1;x>=0;x--){\r
+                               int pix=i_in.getRGB(x, y);\r
+                               rgb[0]=(pix>>16)&0xff;\r
+                               rgb[1]=(pix>>8)&0xff;\r
+                               rgb[2]=(pix)&0xff;\r
+                               reader.setPixel(x,y,rgb);\r
+                       }\r
+               }\r
+               return;\r
+       }\r
+       /**\r
+        * BIN_8用\r
+        * @param i_in\r
+        * @throws NyARException\r
+        */\r
+       public static void copy(BufferedImage i_in,INyARRaster o_out) throws NyARException\r
+       {\r
+               assert o_out.getSize().isEqualSize(i_in.getWidth(), i_in.getHeight());\r
+               if(o_out.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
+               {\r
+                       final int[] buf=(int[])o_out.getBufferReader().getBuffer();\r
+                       final int w=i_in.getWidth();\r
+                       final int h=i_in.getHeight();\r
+                       for(int y=h-1;y>=0;y--){\r
+                               for(int x=w-1;x>=0;x--){\r
+                                       buf[x+y*w]=(i_in.getRGB(x, y)&0xffffff)>0?1:0;\r
+                               }\r
+                       }\r
+               }\r
+               return;\r
+       }       \r
+}\r