OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@802 7cac0...
[nyartoolkit-and/nyartoolkit-and.git] / lib / src / jp / nyatla / nyartoolkit / core / squaredetect / NyARSquareContourDetector_ARToolKit.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.NyARLabelOverlapChecker;\r
35 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
36 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
37 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
38 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;\r
39 import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
40 import jp.nyatla.nyartoolkit.core.types.NyARIntCoordinates;\r
41 import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
42 \r
43 \r
44 /**\r
45  * このクラスは、{@link NyARLabeling_ARToolKit}クラスを用いた矩形検出器です。\r
46  * 検出した矩形を、自己コールバック関数{@link #onSquareDetect}へ通知します。\r
47  * 継承クラスで自己コールバック関数{@link #onSquareDetect}を実装する必要があります。\r
48  */\r
49 public abstract class NyARSquareContourDetector_ARToolKit extends NyARSquareContourDetector\r
50 {\r
51         private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
52         private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
53         private final int _width;\r
54         private final int _height;\r
55 \r
56         private final NyARLabeling_ARToolKit _labeling;\r
57 \r
58         private final NyARLabelingImage _limage;\r
59 \r
60         private final NyARLabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new NyARLabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
61         private final NyARContourPickup_ARToolKit _cpickup=new NyARContourPickup_ARToolKit();\r
62         private final NyARCoord2SquareVertexIndexes _coord2vertex=new NyARCoord2SquareVertexIndexes();\r
63 \r
64         private final NyARIntCoordinates _coord;\r
65         private final int[] __detectMarker_mkvertex = new int[4];\r
66         /**\r
67          * コンストラクタです。\r
68          * 入力画像のサイズを指定して、インスタンスを生成します。\r
69          * @param i_size\r
70          * 入力画像のサイズ\r
71          */\r
72         public NyARSquareContourDetector_ARToolKit(NyARIntSize i_size) throws NyARException\r
73         {\r
74                 this._width = i_size.w;\r
75                 this._height = i_size.h;\r
76                 this._labeling = new NyARLabeling_ARToolKit();\r
77                 this._limage = new NyARLabelingImage(this._width, this._height);\r
78 \r
79                 // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
80                 int number_of_coord = (this._width + this._height) * 2;\r
81 \r
82                 // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
83                 this._coord=new NyARIntCoordinates(number_of_coord);\r
84                 return;\r
85         }\r
86         /**\r
87          * この関数は、ラスタから矩形を検出して、自己コールバック関数{@link #onSquareDetect}で通知します。\r
88          * ARToolKitのarDetectMarker2を基にしています。\r
89          */\r
90         public final void detectMarker(NyARBinRaster i_raster) throws NyARException\r
91         {\r
92                 final NyARLabelingImage limage = this._limage;\r
93 \r
94                 // ラベル数が0ならここまで\r
95                 final int label_num = this._labeling.labeling(i_raster,this._limage);\r
96                 if (label_num < 1) {\r
97                         return;\r
98                 }\r
99 \r
100                 final NyARLabelingLabelStack stack = limage.getLabelStack();\r
101                 //ラベルをソートしておく\r
102                 stack.sortByArea();\r
103                 //\r
104                 final NyARLabelingLabel[] labels = stack.getArray();\r
105 \r
106                 // デカいラベルを読み飛ばし\r
107                 int i;\r
108                 for (i = 0; i < label_num; i++) {\r
109                         // 検査対象内のラベルサイズになるまで無視\r
110                         if (labels[i].area <= AR_AREA_MAX) {\r
111                                 break;\r
112                         }\r
113                 }\r
114                 final int xsize = this._width;\r
115                 final int ysize = this._height;\r
116                 final NyARIntCoordinates coord = this._coord;\r
117                 final int[] mkvertex =this.__detectMarker_mkvertex;\r
118                 \r
119                 final NyARLabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
120 \r
121                 //重なりチェッカの最大数を設定\r
122                 overlap.setMaxLabels(label_num);\r
123                 for (; i < label_num; i++) {\r
124                         final NyARLabelingLabel label_pt = labels[i];\r
125                         final int label_area = label_pt.area;\r
126                         // 検査対象サイズよりも小さくなったら終了\r
127                         if (label_area < AR_AREA_MIN) {\r
128                                 break;\r
129                         }\r
130                         // クリップ領域が画面の枠に接していれば除外\r
131                         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
132                                 continue;\r
133                         }\r
134                         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
135                                 continue;\r
136                         }\r
137                         // 既に検出された矩形との重なりを確認\r
138                         if (!overlap.check(label_pt)) {\r
139                                 // 重なっているようだ。\r
140                                 continue;\r
141                         }\r
142                         // 輪郭を取得\r
143                         if(!this._cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord)){\r
144                                 continue;\r
145                         }\r
146                         //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
147                         if (!this._coord2vertex.getVertexIndexes(coord,label_area, mkvertex)) {\r
148                                 // 頂点の取得が出来なかった\r
149                                 continue;\r
150                         }\r
151                         //矩形を発見したことをコールバック関数で通知\r
152                         this.onSquareDetect(coord,mkvertex);\r
153 \r
154                         // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
155                         overlap.push(label_pt);\r
156                         \r
157                 }\r
158                 return;\r
159         }\r
160 \r
161 }\r
162 \r
163 \r
164 \r