OSDN Git Service

[バックアップ]NyARToolkit
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src / jp / nyatla / nyartoolkit / core / labeling / NyARLabelingImage.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.core.labeling;\r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.raster.*;\r
36 import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
37 import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;\r
38 import jp.nyatla.nyartoolkit.core.types.*;\r
39 \r
40 /**\r
41  *\r
42  */\r
43 public class NyARLabelingImage extends NyARRaster_BasicClass implements INyARLabelingImage\r
44 {\r
45         private final static int MAX_LABELS = 1024*32;  \r
46         protected int[][] _ref_buf;\r
47         private INyARBufferReader _buffer_reader;\r
48         protected NyARLabelingLabelStack _label_list;\r
49         protected int[] _index_table;\r
50         protected boolean _is_index_table_enable;\r
51         public NyARLabelingImage(int i_width, int i_height)\r
52         {\r
53                 super(new NyARIntSize(i_width,i_height));\r
54                 this._ref_buf =new int[i_height][i_width];\r
55                 this._label_list = new NyARLabelingLabelStack(MAX_LABELS);\r
56                 this._index_table=new int[MAX_LABELS];\r
57                 this._is_index_table_enable=false;\r
58                 this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT2D);\r
59                 \r
60                 return;\r
61         }\r
62         public INyARBufferReader getBufferReader()\r
63         {\r
64                 return this._buffer_reader;\r
65         }\r
66 \r
67 \r
68         /**\r
69          * ラベリング結果がインデックステーブルを持つ場合、その配列を返します。\r
70          * 持たない場合、nullを返します。\r
71          * \r
72          * 値がnullの時はラベル番号そのものがラスタに格納されていますが、\r
73          * null以外の時はラスタに格納されているのはインデクス番号です。\r
74          * \r
75          * インデクス番号とラベル番号の関係は、以下の式で表されます。\r
76          * ラベル番号:=value[インデクス番号]\r
77          * \r
78          */\r
79         public int[] getIndexArray()\r
80         {\r
81                 return this._is_index_table_enable?this._index_table:null;\r
82         }\r
83         \r
84         public NyARLabelingLabelStack getLabelStack()\r
85         {\r
86                 return this._label_list;\r
87         }\r
88         public void reset(boolean i_label_index_enable)\r
89         {\r
90                 assert(i_label_index_enable==true);//非ラベルモードは未実装\r
91                 this._label_list.clear();\r
92                 this._is_index_table_enable=i_label_index_enable;\r
93                 return;\r
94         }\r
95         \r
96         protected final int[] _getContour_xdir = { 0, 1, 1, 1, 0,-1,-1,-1};\r
97         protected final int[] _getContour_ydir = {-1,-1, 0, 1, 1, 1, 0,-1};\r
98         /**\r
99          * i_labelのラベルの、クリップ領域が上辺に接しているx座標を返します。\r
100          * @param i_index\r
101          * @return\r
102          */\r
103         protected int getTopClipTangentX(NyARLabelingLabel i_label) throws NyARException\r
104         {\r
105                 int w;\r
106                 int i_label_id=i_label.id;\r
107                 int[] index_table=this._index_table;\r
108                 int[] limage_j=this._ref_buf[i_label.clip_t];\r
109                 final int clip1 = i_label.clip_r;\r
110                 // p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 =&(limage[j*xsize+clip[0]]);\r
111                 for (int i = i_label.clip_l; i <= clip1; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
112                         w = limage_j[i];\r
113                         if (w > 0 && index_table[w-1] == i_label_id){\r
114                                 return i;\r
115                         }\r
116                 }\r
117                 //あれ?見つからないよ?\r
118                 throw new NyARException();\r
119         }\r
120         /**\r
121          * i_index番目のラベルの輪郭線を配列に返します。\r
122          * @param i_index\r
123          * @param i_array_size\r
124          * @param o_coord_x\r
125          * @param o_coord_y\r
126          * @return\r
127          * 輪郭線の長さを返します。\r
128          * @throws NyARException\r
129          */\r
130         public int getContour(int i_index,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
131         {\r
132                 final int[] xdir = this._getContour_xdir;// static int xdir[8] = { 0,1, 1, 1, 0,-1,-1,-1};\r
133                 final int[] ydir = this._getContour_ydir;// static int ydir[8] = {-1,-1,0, 1, 1, 1, 0,-1};\r
134                 final NyARLabelingLabel label=(NyARLabelingLabel)this._label_list.getItem(i_index);             \r
135                 int i;\r
136                 //クリップ領域の上端に接しているポイントを得る。\r
137                 int sx=getTopClipTangentX(label);\r
138                 int sy=label.clip_t;\r
139 \r
140                 int coord_num = 1;\r
141                 o_coord_x[0] = sx;\r
142                 o_coord_y[0] = sy;\r
143                 int dir = 5;\r
144 \r
145                 int[][] limage=this._ref_buf;\r
146                 int c = o_coord_x[0];\r
147                 int r = o_coord_y[0];\r
148                 for (;;) {\r
149                         dir = (dir + 5) % 8;\r
150                         for (i = 0; i < 8; i++) {\r
151                                 if (limage[r + ydir[dir]][c + xdir[dir]] > 0) {\r
152                                         break;\r
153                                 }\r
154                                 dir = (dir + 1) % 8;\r
155                         }\r
156                         if (i == 8) {\r
157                                 //8方向全て調べたけどラベルが無いよ?\r
158                                 throw new NyARException();// return(-1);\r
159                         }\r
160                         // xcoordとycoordをc,rにも保存\r
161                         c = c + xdir[dir];\r
162                         r = r + ydir[dir];\r
163                         o_coord_x[coord_num] = c;\r
164                         o_coord_y[coord_num] = r;\r
165                         // 終了条件判定\r
166                         if (c == sx && r == sy){\r
167                                 coord_num++;\r
168                                 break;\r
169                         }\r
170                         coord_num++;\r
171                         if (coord_num == i_array_size) {\r
172                                 //輪郭が末端に達した\r
173                                 return coord_num;\r
174                         }\r
175                 }\r
176                 return coord_num;               \r
177                 \r
178         }\r
179 }\r