OSDN Git Service

[TAG]NyARToolkit for Java 2.4.2
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.4.2 / src / jp / nyatla / nyartoolkit / core / squaredetect / NyARSquareContourDetector_Rle.java
1 /* \r
2  * PROJECT: NyARToolkit\r
3  * --------------------------------------------------------------------------------\r
4  * This work is based on the original ARToolKit developed by\r
5  *   Hirokazu Kato\r
6  *   Mark Billinghurst\r
7  *   HITLab, University of Washington, Seattle\r
8  * http://www.hitl.washington.edu/artoolkit/\r
9  *\r
10  * The NyARToolkit is Java edition ARToolKit class library.\r
11  * Copyright (C)2008-2009 Ryo Iizuka\r
12  *\r
13  * This program is free software: you can redistribute it and/or modify\r
14  * it under the terms of the GNU General Public License as published by\r
15  * the Free Software Foundation, either version 3 of the License, or\r
16  * (at your option) any later version.\r
17  * \r
18  * This program is distributed in the hope that it will be useful,\r
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
21  * GNU General Public License for more details.\r
22  *\r
23  * You should have received a copy of the GNU General Public License\r
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
25  * \r
26  * For further information please contact.\r
27  *      http://nyatla.jp/nyatoolkit/\r
28  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
29  * \r
30  */\r
31 package jp.nyatla.nyartoolkit.core.squaredetect;\r
32 \r
33 import jp.nyatla.nyartoolkit.NyARException;\r
34 import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
35 import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
36 import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
37 import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
38 import jp.nyatla.nyartoolkit.core.types.*;\r
39 import java.util.*;\r
40 \r
41 \r
42 public class NyARSquareContourDetector_Rle implements INyARSquareContourDetector\r
43 {\r
44         private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
45         private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
46         private final int _width;\r
47         private final int _height;\r
48 \r
49         private final NyARLabeling_Rle _labeling;\r
50 \r
51         private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
52         private final ContourPickup _cpickup=new ContourPickup();\r
53         private final RleLabelFragmentInfoStack _stack;\r
54         private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
55         \r
56         private final int _max_coord;\r
57         private final int[] _xcoord;\r
58         private final int[] _ycoord;\r
59         /**\r
60          * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
61          * \r
62          * @param i_param\r
63          */\r
64         public NyARSquareContourDetector_Rle(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
65         {\r
66                 this._width = i_size.w;\r
67                 this._height = i_size.h;\r
68                 //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
69                 this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
70                 this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN);\r
71                 this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
72                 \r
73 \r
74                 // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
75                 int number_of_coord = (this._width + this._height) * 2;\r
76 \r
77                 // 輪郭バッファ\r
78                 this._max_coord = number_of_coord;\r
79                 this._xcoord = new int[number_of_coord];\r
80                 this._ycoord = new int[number_of_coord];\r
81                 return;\r
82         }\r
83 \r
84         private final int[] __detectMarker_mkvertex = new int[4];\r
85         \r
86         public void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException\r
87         {\r
88                 final RleLabelFragmentInfoStack flagment=this._stack;\r
89                 final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
90 \r
91                 // ラベル数が0ならここまで\r
92                 final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
93                 if (label_num < 1) {\r
94                         return;\r
95                 }\r
96                 //ラベルをソートしておく\r
97                 flagment.sortByArea();\r
98                 //ラベルリストを取得\r
99                 RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
100 \r
101                 final int xsize = this._width;\r
102                 final int ysize = this._height;\r
103                 int[] xcoord = this._xcoord;\r
104                 int[] ycoord = this._ycoord;\r
105                 final int coord_max = this._max_coord;\r
106                 final int[] mkvertex =this.__detectMarker_mkvertex;\r
107 \r
108 \r
109                 //重なりチェッカの最大数を設定\r
110                 overlap.setMaxLabels(label_num);\r
111 \r
112                 for (int i=0; i < label_num; i++) {\r
113                         final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
114                         int label_area = label_pt.area;\r
115                 \r
116                         // クリップ領域が画面の枠に接していれば除外\r
117                         if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
118                                 continue;\r
119                         }\r
120                         if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
121                                 continue;\r
122                         }\r
123                         // 既に検出された矩形との重なりを確認\r
124                         if (!overlap.check(label_pt)) {\r
125                                 // 重なっているようだ。\r
126                                 continue;\r
127                         }\r
128                         \r
129                         //輪郭を取得\r
130                         int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
131                         if (coord_num == coord_max) {\r
132                                 // 輪郭が大きすぎる。\r
133                                 continue;\r
134                         }\r
135                         //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
136                         if (!this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex)) {\r
137                                 // 頂点の取得が出来なかった\r
138                                 continue;\r
139                         }\r
140                         //矩形を発見したことをコールバック関数で通知\r
141                         i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);\r
142 \r
143                         // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
144                         overlap.push(label_pt);\r
145                 \r
146                 }\r
147                 return;\r
148         }\r
149         /**\r
150          * デバック用API\r
151          * @return\r
152          */\r
153         public RleLabelFragmentInfoStack _getFragmentStack()\r
154         {\r
155                 return this._stack;\r
156         }\r
157 \r
158 }\r
159 \r
160 \r
161 \r