OSDN Git Service

[Backup]NyARToolkit for Java
[nyartoolkit-and/nyartoolkit-and.git] / sample / sandbox / jp / nyatla / nyartoolkit / sandbox / quadx2 / NyARSquareDetector_Quad.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.quadx2;\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.ContourPickup;\r
38 import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;\r
39 import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
40 import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
41 import jp.nyatla.nyartoolkit.core.squaredetect.SquareContourDetector;\r
42 import jp.nyatla.nyartoolkit.core.types.*;\r
43 import jp.nyatla.nyartoolkit.core.param.*;\r
44 \r
45 import jp.nyatla.nyartoolkit.sandbox.x2.*;\r
46 \r
47 \r
48 /**\r
49  * 1/4に解像度を落して解析するNyARSquareDetector_X2\r
50  * 与えるBinRasterが既に1/4のサイズになっていないといけないことに注意\r
51  */\r
52 public class NyARSquareDetector_Quad implements INyARSquareDetector\r
53 {\r
54     private static int AR_AREA_MAX = 25000;// #define AR_AREA_MAX 100000\r
55 \r
56     private static int AR_AREA_MIN = 20;// #define AR_AREA_MIN 70\r
57     private int _width;\r
58     private int _height;\r
59 \r
60     private NyARLabeling_ARToolKit _labeling;\r
61 \r
62     private NyARLabelingImage _limage;\r
63 \r
64         private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
65         private final SquareContourDetector _sqconvertor;\r
66         private final ContourPickup _cpickup=new ContourPickup();\r
67     /**\r
68      * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
69      * \r
70      * @param i_param\r
71      */\r
72     public NyARSquareDetector_Quad(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException\r
73     {\r
74         this._width = i_size.w / 2;\r
75         this._height = i_size.h / 2;\r
76         this._labeling = new NyARLabeling_ARToolKit();\r
77         this._limage = new NyARLabelingImage(this._width, this._height);\r
78         this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);        \r
79 \r
80         // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
81         int number_of_coord = (this._width + this._height) * 2;\r
82 \r
83         // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
84         this._max_coord = number_of_coord;\r
85         this._xcoord = new int[number_of_coord * 2];\r
86         this._ycoord = new int[number_of_coord * 2];\r
87 \r
88         //1/4サイズの歪みマップを作る\r
89         NyARCameraDistortionFactor quadfactor = new NyARCameraDistortionFactor();\r
90         quadfactor.copyFrom(i_dist_factor_ref);\r
91         quadfactor.changeScale(0.5);\r
92     }\r
93 \r
94     private int _max_coord;\r
95     private int[] _xcoord;\r
96     private int[] _ycoord;\r
97 \r
98     /**\r
99      * arDetectMarker2を基にした関数\r
100      * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
101      * directionの確定は行いません。\r
102      * @param i_raster\r
103      * 解析する2値ラスタイメージを指定します。\r
104      * @param o_square_stack\r
105      * 抽出した正方形候補を格納するリスト\r
106      * @throws NyARException\r
107      */\r
108     public void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
109     {\r
110         NyARLabelingImage limage = this._limage;\r
111 \r
112         // 初期化\r
113 \r
114         // マーカーホルダをリセット\r
115         o_square_stack.clear();\r
116 \r
117         // ラベリング\r
118         this._labeling.labeling(i_raster,limage);\r
119 \r
120         // ラベル数が0ならここまで\r
121         int label_num = limage.getLabelStack().getLength();\r
122         if (label_num < 1)\r
123         {\r
124             return;\r
125         }\r
126 \r
127         NyARLabelingLabelStack stack = limage.getLabelStack();\r
128         NyARLabelingLabel[] labels = stack.getArray();\r
129 \r
130 \r
131         // ラベルを大きい順に整列\r
132         stack.sortByArea();\r
133 \r
134         // デカいラベルを読み飛ばし\r
135         int i;\r
136         for (i = 0; i < label_num; i++)\r
137         {\r
138             // 検査対象内のラベルサイズになるまで無視\r
139             if (labels[i].area <= AR_AREA_MAX)\r
140             {\r
141                 break;\r
142             }\r
143         }\r
144 \r
145         int xsize = this._width;\r
146         int ysize = this._height;\r
147         int[] xcoord = this._xcoord;\r
148         int[] ycoord = this._ycoord;\r
149         int coord_max = this._max_coord;\r
150                 final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
151 \r
152         int label_area;\r
153         NyARLabelingLabel label_pt;\r
154 \r
155         //重なりチェッカの最大数を設定\r
156         overlap.setMaxLabels(label_num);\r
157 \r
158         for (; i < label_num; i++)\r
159         {\r
160             label_pt = labels[i];\r
161             label_area = label_pt.area;\r
162             // 検査対象サイズよりも小さくなったら終了\r
163             if (label_area < AR_AREA_MIN)\r
164             {\r
165                 break;\r
166             }\r
167             // クリップ領域が画面の枠に接していれば除外\r
168             if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2)\r
169             {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
170                 continue;\r
171             }\r
172             if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2)\r
173             {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
174                 continue;\r
175             }\r
176             // 既に検出された矩形との重なりを確認\r
177             if (!overlap.check(label_pt))\r
178             {\r
179                 // 重なっているようだ。\r
180                 continue;\r
181             }\r
182                         // 既に検出された矩形との重なりを確認\r
183                         if (!overlap.check(label_pt)) {\r
184                                 // 重なっているようだ。\r
185                                 continue;\r
186                         }\r
187                         // 輪郭を取得\r
188                         final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
189                         if (coord_num == coord_max) {\r
190                                 // 輪郭が大きすぎる。\r
191                                 continue;\r
192                         }\r
193                         //輪郭分析用に正規化する。\r
194                         final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
195 \r
196                         //ここから先が輪郭分析\r
197                         NyARSquare square_ptr = o_square_stack.prePush();\r
198                         if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
199                                 o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
200                                 continue;                               \r
201                         }\r
202                                     \r
203             // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
204             overlap.push(label_pt);\r
205         }\r
206         return;\r
207     }\r
208 }\r
209 \r
210 \r