OSDN Git Service

[TAG]2.4.0
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.4.0 / sample / sandbox / jp / nyatla / nyartoolkit / sandbox / x2 / NyARSquareDetector_X2.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.x2;\r
33 import jp.nyatla.nyartoolkit.NyARException;\r
34 import jp.nyatla.nyartoolkit.core.labeling.*;\r
35 import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\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 \r
42 \r
43 /**\r
44  * イメージから正方形候補を検出するクラス。\r
45  * このクラスは、arDetectMarker2.cとの置き換えになります。\r
46  * \r
47  */\r
48 public class NyARSquareDetector_X2 implements INyARSquareDetector\r
49 {\r
50         private final int _width;\r
51         private final int _height;\r
52 \r
53         private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
54         private final SquareContourDetector_X2 _sqconvertor;\r
55         private final ContourPickup _cpickup=new ContourPickup();\r
56         private final RleLabelFragmentInfoStack _stack;\r
57 \r
58         \r
59         \r
60         private final NyARLabeling_Rle _labeling;\r
61         /**\r
62          * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
63          * \r
64          * @param i_param\r
65          */\r
66         public NyARSquareDetector_X2(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
67         {\r
68                 this._width = i_size.w;\r
69                 this._height = i_size.h;\r
70                 this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
71                 this._sqconvertor=new SquareContourDetector_X2(i_size,i_dist_factor_ref);\r
72                 this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
73                 \r
74 \r
75                 // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
76                 int number_of_coord = (this._width + this._height) * 2;\r
77 \r
78                 // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
79                 this._max_coord = number_of_coord;\r
80                 this._xcoord = new int[number_of_coord * 2];\r
81                 this._ycoord = new int[number_of_coord * 2];\r
82         }\r
83         private final int _max_coord;\r
84         private final int[] _xcoord;\r
85         private final int[] _ycoord;\r
86 \r
87 \r
88         /**\r
89          * arDetectMarker2を基にした関数\r
90          * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
91          * directionの確定は行いません。\r
92          * @param i_raster\r
93          * 解析する2値ラスタイメージを指定します。\r
94          * @param o_square_stack\r
95          * 抽出した正方形候補を格納するリスト\r
96          * @throws NyARException\r
97          */\r
98         public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
99         {\r
100                 final RleLabelFragmentInfoStack flagment=this._stack;\r
101                 final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
102 \r
103                 // 初期化\r
104 \r
105                 // マーカーホルダをリセット\r
106                 o_square_stack.clear();\r
107 \r
108                 // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
109                 final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
110                 if (label_num < 1) {\r
111                         return;\r
112                 }\r
113                 //ラベルをソートしておく\r
114                 flagment.sortByArea();\r
115                 RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
116 \r
117 \r
118                 final int xsize = this._width;\r
119                 final int ysize = this._height;\r
120                 final int[] xcoord = this._xcoord;\r
121                 final int[] ycoord = this._ycoord;\r
122                 final int coord_max = this._max_coord;\r
123 \r
124                 //重なりチェッカの最大数を設定\r
125                 overlap.setMaxLabels(label_num);\r
126 \r
127                 for (int i=0; i < label_num; i++) {\r
128                         final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
129                         final int label_area = label_pt.area;\r
130 \r
131                         // クリップ領域が画面の枠に接していれば除外\r
132                         if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
133                                 continue;\r
134                         }\r
135                         if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
136                                 continue;\r
137                         }\r
138                         // 既に検出された矩形との重なりを確認\r
139                         if (!overlap.check(label_pt)) {\r
140                                 // 重なっているようだ。\r
141                                 continue;\r
142                         }\r
143                         \r
144                         // 輪郭を取得\r
145                         final int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
146                         if (coord_num == coord_max) {\r
147                                 // 輪郭が大きすぎる。\r
148                                 continue;\r
149                         }\r
150                         //輪郭分析用に正規化する。\r
151                         final int vertex1 = SquareContourDetector_X2.normalizeCoord(xcoord, ycoord, coord_num);\r
152 \r
153                         //ここから先が輪郭分析\r
154                         NyARSquare square_ptr = o_square_stack.prePush();\r
155                         if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
156                                 o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
157                                 continue;                               \r
158                         }\r
159                         // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
160                         overlap.push(label_pt);\r
161                 }\r
162                 return;         \r
163         }\r
164 }\r
165 \r
166 \r