OSDN Git Service

[tag]NyARToolkit/2.5.1
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.5.1 / sample / sandbox / jp / nyatla / nyartoolkit / sandbox / vertexdetect / NyARVertexDetector.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 version ARToolkit class library.\r
11  * Copyright (C)2008 R.Iizuka\r
12  *\r
13  * This program is free software; you can redistribute it and/or\r
14  * modify it under the terms of the GNU General Public License\r
15  * as published by the Free Software Foundation; either version 2\r
16  * of the License, or (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 framework; if not, write to the Free Software\r
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
26  * \r
27  * For further information please contact.\r
28  *      http://nyatla.jp/nyatoolkit/\r
29  *      <airmail(at)ebony.plala.or.jp>\r
30  * \r
31  */\r
32 package jp.nyatla.nyartoolkit.sandbox.vertexdetect;\r
33 import jp.nyatla.nyartoolkit.NyARException;\r
34 import jp.nyatla.nyartoolkit.core.labeling.*;\r
35 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
36 import jp.nyatla.nyartoolkit.core.raster.*;\r
37 import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
38 import jp.nyatla.nyartoolkit.core.types.*;\r
39 import jp.nyatla.nyartoolkit.core.param.*;\r
40 /**\r
41  * PCAではなく、頂点座標そのものからSquare位置を計算するクラス\r
42  *\r
43  */\r
44 public class NyARVertexDetector extends NyARSquareContourDetector\r
45 {\r
46         private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
47 \r
48         private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
49         private final int _width;\r
50         private final int _height;\r
51 \r
52         private final NyARLabeling_ARToolKit _labeling;\r
53 \r
54         private final NyARLabelingImage _limage;\r
55 \r
56         private final NyARLabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new NyARLabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
57         private final NyARCoord2Linear _sqconvertor;\r
58         private final NyARContourPickup _cpickup=new NyARContourPickup();\r
59 \r
60         /**\r
61          * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
62          * \r
63          * @param i_param\r
64          */\r
65         public NyARVertexDetector(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
66         {\r
67                 this._width = i_size.w;\r
68                 this._height = i_size.h;\r
69                 this._labeling = new NyARLabeling_ARToolKit();\r
70                 this._limage = new NyARLabelingImage(this._width, this._height);\r
71         this._sqconvertor=new NyARCoord2Linear(i_size,i_dist_factor_ref);        \r
72 \r
73                 // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
74                 int number_of_coord = (this._width + this._height) * 2;\r
75 \r
76                 // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
77                 this._max_coord = number_of_coord;\r
78                 this._xcoord = new int[number_of_coord * 2];\r
79                 this._ycoord = new int[number_of_coord * 2];\r
80         }\r
81 \r
82         private final int _max_coord;\r
83         private final int[] _xcoord;\r
84         private final int[] _ycoord;\r
85 \r
86         /**\r
87          * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double\r
88          * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。\r
89          * \r
90          * @param i_raster\r
91          * 解析する2値ラスタイメージを指定します。\r
92          * @param o_square_stack\r
93          * 抽出した正方形候補を格納するリスト\r
94          * @throws NyARException\r
95          */\r
96         public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
97         {\r
98                 final NyARLabelingImage limage = this._limage;\r
99 \r
100                 // 初期化\r
101 \r
102                 // マーカーホルダをリセット\r
103                 o_square_stack.clear();\r
104 \r
105                 // ラベリング\r
106                 this._labeling.labeling(i_raster,this._limage);\r
107 \r
108                 // ラベル数が0ならここまで\r
109                 final int label_num = limage.getLabelStack().getLength();\r
110                 if (label_num < 1) {\r
111                         return;\r
112                 }\r
113                 \r
114 \r
115                 final NyARLabelingLabelStack stack = limage.getLabelStack();\r
116                 // ラベルを大きい順に整列\r
117                 stack.sortByArea();\r
118                 \r
119                 final NyARLabelingLabel[] labels = stack.getArray();\r
120 \r
121                 // デカいラベルを読み飛ばし\r
122                 int i;\r
123                 for (i = 0; i < label_num; i++) {\r
124                         // 検査対象内のラベルサイズになるまで無視\r
125                         if (labels[i].area <= AR_AREA_MAX) {\r
126                                 break;\r
127                         }\r
128                 }\r
129 \r
130                 final int xsize = this._width;\r
131                 final int ysize = this._height;\r
132                 final int[] xcoord = this._xcoord;\r
133                 final int[] ycoord = this._ycoord;\r
134                 final int coord_max = this._max_coord;\r
135                 final NyARLabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
136                 int label_area;\r
137                 NyARLabelingLabel label_pt;\r
138 \r
139                 //重なりチェッカの最大数を設定\r
140                 overlap.setMaxLabels(label_num);\r
141 \r
142                 for (; i < label_num; i++) {\r
143                         label_pt = labels[i];\r
144                         label_area = label_pt.area;\r
145                         // 検査対象サイズよりも小さくなったら終了\r
146                         if (label_area < AR_AREA_MIN) {\r
147                                 break;\r
148                         }\r
149                         // クリップ領域が画面の枠に接していれば除外\r
150                         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
151                                 continue;\r
152                         }\r
153                         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
154                                 continue;\r
155                         }\r
156                         // 既に検出された矩形との重なりを確認\r
157                         if (!overlap.check(label_pt)) {\r
158                                 // 重なっているようだ。\r
159                                 continue;\r
160                         }\r
161                         // 輪郭を取得\r
162                         final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
163                         if (coord_num == coord_max) {\r
164                                 // 輪郭が大きすぎる。\r
165                                 continue;\r
166                         }\r
167                         //輪郭分析用に正規化する。\r
168                         final int vertex1 = NyARCoord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
169 \r
170                         //ここから先が輪郭分析\r
171                         NyARSquare square_ptr = o_square_stack.prePush();\r
172                         if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
173                                 o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
174                                 continue;                               \r
175                         }\r
176                         // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
177                         overlap.push(label_pt);\r
178                 }       \r
179                 return;\r
180         }\r
181 \r
182 }