OSDN Git Service

c2e2f138706381012c9b833603d2fceb5d271fd9
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src / jp / nyatla / nyartoolkit / core / squaredetect / NyARSquareDetector_ARToolKit.java
1 package jp.nyatla.nyartoolkit.core.squaredetect;\r
2 \r
3 import jp.nyatla.nyartoolkit.NyARException;\r
4 import jp.nyatla.nyartoolkit.core.INyARSquareDetector;\r
5 import jp.nyatla.nyartoolkit.core.NyARSquare;\r
6 import jp.nyatla.nyartoolkit.core.NyARSquareStack;\r
7 import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
8 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
9 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
10 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
11 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;\r
12 import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
13 import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
14 import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
15 \r
16 \r
17 \r
18 public class NyARSquareDetector_ARToolKit implements INyARSquareDetector\r
19 {\r
20         private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
21         private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
22         private final int _width;\r
23         private final int _height;\r
24 \r
25         private final NyARLabeling_ARToolKit _labeling;\r
26 \r
27         private final NyARLabelingImage _limage;\r
28 \r
29         private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
30         private final SquareContourDetector _sqconvertor;\r
31         private final ContourPickup _cpickup=new ContourPickup();\r
32         \r
33         private final int _max_coord;\r
34         private final int[] _xcoord;\r
35         private final int[] _ycoord;    \r
36         /**\r
37          * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
38          * \r
39          * @param i_param\r
40          */\r
41         public NyARSquareDetector_ARToolKit(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
42         {\r
43                 this._width = i_size.w;\r
44                 this._height = i_size.h;\r
45                 //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。\r
46                 //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
47                 this._labeling = new NyARLabeling_ARToolKit();\r
48                 this._sqconvertor=new SquareContourDetector(i_size,i_dist_factor_ref);\r
49                 this._limage = new NyARLabelingImage(this._width, this._height);\r
50 \r
51                 // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
52                 int number_of_coord = (this._width + this._height) * 2;\r
53 \r
54                 // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
55                 this._max_coord = number_of_coord;\r
56                 this._xcoord = new int[number_of_coord * 2];\r
57                 this._ycoord = new int[number_of_coord * 2];\r
58                 return;\r
59         }\r
60 \r
61         /**\r
62          * arDetectMarker2を基にした関数\r
63          * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
64          * directionの確定は行いません。\r
65          * @param i_raster\r
66          * 解析する2値ラスタイメージを指定します。\r
67          * @param o_square_stack\r
68          * 抽出した正方形候補を格納するリスト\r
69          * @throws NyARException\r
70          */\r
71         public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
72         {\r
73                 final NyARLabelingImage limage = this._limage;\r
74 \r
75                 // 初期化\r
76 \r
77                 // マーカーホルダをリセット\r
78                 o_square_stack.clear();\r
79 \r
80                 // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
81                 final int label_num = this._labeling.labeling(i_raster,this._limage);\r
82                 if (label_num < 1) {\r
83                         return;\r
84                 }\r
85 \r
86                 final NyARLabelingLabelStack stack = limage.getLabelStack();\r
87                 final NyARLabelingLabel[] labels = stack.getArray();\r
88 \r
89                 // デカいラベルを読み飛ばし\r
90                 int i;\r
91                 for (i = 0; i < label_num; i++) {\r
92                         // 検査対象内のラベルサイズになるまで無視\r
93                         if (labels[i].area <= AR_AREA_MAX) {\r
94                                 break;\r
95                         }\r
96                 }\r
97 \r
98                 final int xsize = this._width;\r
99                 final int ysize = this._height;\r
100                 final int[] xcoord = this._xcoord;\r
101                 final int[] ycoord = this._ycoord;\r
102                 final int coord_max = this._max_coord;\r
103                 final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
104 \r
105                 //重なりチェッカの最大数を設定\r
106                 overlap.setMaxLabels(label_num);\r
107 \r
108                 for (; i < label_num; i++) {\r
109                         final NyARLabelingLabel label_pt = labels[i];\r
110                         final int label_area = label_pt.area;\r
111                         // 検査対象サイズよりも小さくなったら終了\r
112                         if (label_area < AR_AREA_MIN) {\r
113                                 break;\r
114                         }\r
115                         // クリップ領域が画面の枠に接していれば除外\r
116                         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
117                                 continue;\r
118                         }\r
119                         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
120                                 continue;\r
121                         }\r
122                         // 既に検出された矩形との重なりを確認\r
123                         if (!overlap.check(label_pt)) {\r
124                                 // 重なっているようだ。\r
125                                 continue;\r
126                         }\r
127                         // 輪郭を取得\r
128                         final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
129                         if (coord_num == coord_max) {\r
130                                 // 輪郭が大きすぎる。\r
131                                 continue;\r
132                         }\r
133                         //輪郭分析用に正規化する。\r
134                         final int vertex1 = SquareContourDetector.normalizeCoord(xcoord, ycoord, coord_num);\r
135 \r
136                         //ここから先が輪郭分析\r
137                         NyARSquare square_ptr = o_square_stack.prePush();\r
138                         if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
139                                 o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
140                                 continue;                               \r
141                         }\r
142                         // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
143                         overlap.push(label_pt);\r
144                 }\r
145                 return;\r
146         }\r
147 \r
148 }\r
149 \r
150 \r
151 \r