OSDN Git Service

[更新]NyARToolkit
[nyartoolkit-and/nyartoolkit-and.git] / 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_INT1D);\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 pix;\r
106                 int i_label_id=i_label.id;\r
107                 int[] index_table=this._index_table;\r
108                 int[] limage=this._ref_buf;\r
109                 int limage_ptr=i_label.clip_t*this._size.w;\r
110                 final int clip1 = i_label.clip_r;\r
111                 // p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 =&(limage[j*xsize+clip[0]]);\r
112                 for (int i = i_label.clip_l; i <= clip1; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
113                         pix = limage[limage_ptr+i];\r
114                         if (pix > 0 && index_table[pix-1] == i_label_id){\r
115                                 return i;\r
116                         }\r
117                 }\r
118                 //あれ?見つからないよ?\r
119                 throw new NyARException();\r
120         }\r
121         /**\r
122          * i_index番目のラベルの輪郭線を配列に返します。\r
123          * @param i_index\r
124          * @param i_array_size\r
125          * @param o_coord_x\r
126          * @param o_coord_y\r
127          * @return\r
128          * 輪郭線の長さを返します。\r
129          * @throws NyARException\r
130          */\r
131         public int getContour(int i_index,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
132         {\r
133                 final int width=this._size.w;\r
134                 final int[] xdir = this._getContour_xdir;// static int xdir[8] = { 0,1, 1, 1, 0,-1,-1,-1};\r
135                 final int[] ydir = this._getContour_ydir;// static int ydir[8] = {-1,-1,0, 1, 1, 1, 0,-1};\r
136                 final NyARLabelingLabel label=(NyARLabelingLabel)this._label_list.getItem(i_index);             \r
137                 int i;\r
138                 //クリップ領域の上端に接しているポイントを得る。\r
139                 int sx=getTopClipTangentX(label);\r
140                 int sy=label.clip_t;\r
141 \r
142                 int coord_num = 1;\r
143                 o_coord_x[0] = sx;\r
144                 o_coord_y[0] = sy;\r
145                 int dir = 5;\r
146 \r
147                 int[] limage=this._ref_buf;\r
148                 int c = o_coord_x[0];\r
149                 int r = o_coord_y[0];\r
150                 for (;;) {\r
151                         dir = (dir + 5) % 8;\r
152                         for (i = 0; i < 8; i++) {\r
153                                 if (limage[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
154                                         break;\r
155                                 }\r
156                                 dir = (dir + 1) % 8;\r
157                         }\r
158                         if (i == 8) {\r
159                                 //8方向全て調べたけどラベルが無いよ?\r
160                                 throw new NyARException();// return(-1);\r
161                         }\r
162                         // xcoordとycoordをc,rにも保存\r
163                         c = c + xdir[dir];\r
164                         r = r + ydir[dir];\r
165                         o_coord_x[coord_num] = c;\r
166                         o_coord_y[coord_num] = r;\r
167                         // 終了条件判定\r
168                         if (c == sx && r == sy){\r
169                                 coord_num++;\r
170                                 break;\r
171                         }\r
172                         coord_num++;\r
173                         if (coord_num == i_array_size) {\r
174                                 //輪郭が末端に達した\r
175                                 return coord_num;\r
176                         }\r
177                 }\r
178                 return coord_num;               \r
179                 \r
180         }\r
181 }\r