OSDN Git Service

[Backup]NyARToolkit for Java
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core / squaredetect / ContourPickup.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.raster.*;\r
35 import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
36 \r
37 public class ContourPickup\r
38 {\r
39         //巡回参照できるように、テーブルを二重化\r
40         //                                           0  1  2  3  4  5  6  7   0  1  2  3  4  5  6\r
41         protected final static int[] _getContour_xdir = { 0, 1, 1, 1, 0,-1,-1,-1 , 0, 1, 1, 1, 0,-1,-1};\r
42         protected final static int[] _getContour_ydir = {-1,-1, 0, 1, 1, 1, 0,-1 ,-1,-1, 0, 1, 1, 1, 0};\r
43 \r
44         /**\r
45          * ラスタのエントリポイントから辿れる輪郭線を配列に返します。\r
46          * @param i_raster\r
47          * @param i_entry_x\r
48          * @param i_entry_y\r
49          * @param i_array_size\r
50          * @param o_coord_x\r
51          * @param o_coord_y\r
52          * @return\r
53          * 輪郭線の長さを返します。\r
54          * @throws NyARException\r
55          */\r
56         public int getContour(NyARBinRaster i_raster,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
57         {\r
58                 final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
59                 final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
60 \r
61                 final int[] i_buf=(int[])i_raster.getBufferReader().getBuffer();\r
62                 final int width=i_raster.getWidth();\r
63                 final int height=i_raster.getHeight();\r
64                 //クリップ領域の上端に接しているポイントを得る。\r
65 \r
66 \r
67                 int coord_num = 1;\r
68                 o_coord_x[0] = i_entry_x;\r
69                 o_coord_y[0] = i_entry_y;\r
70                 int dir = 5;\r
71 \r
72                 int c = i_entry_x;\r
73                 int r = i_entry_y;\r
74                 for (;;) {\r
75                         dir = (dir + 5) % 8;//dirの正規化\r
76                         //ここは頑張ればもっと最適化できると思うよ。\r
77                         //4隅以外の境界接地の場合に、境界チェックを省略するとかね。\r
78                         if(c>=1 && c<width-1 && r>=1 && r<height-1){\r
79                                 for(;;){//gotoのエミュレート用のfor文\r
80                                         //境界に接していないとき\r
81                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
82                                                 break;\r
83                                         }\r
84                                         dir++;\r
85                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
86                                                 break;\r
87                                         }\r
88                                         dir++;\r
89                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
90                                                 break;\r
91                                         }\r
92                                         dir++;\r
93                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
94                                                 break;\r
95                                         }\r
96                                         dir++;\r
97                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
98                                                 break;\r
99                                         }\r
100                                         dir++;\r
101                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
102                                                 break;\r
103                                         }\r
104                                         dir++;\r
105                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
106                                                 break;\r
107                                         }\r
108                                         dir++;\r
109                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] == 0) {\r
110                                                 break;\r
111                                         }\r
112 /*\r
113                                         try{\r
114                                                 BufferedImage b=new BufferedImage(width,height,ColorSpace.TYPE_RGB);\r
115                                                 NyARRasterImageIO.copy(i_raster, b);\r
116                                         ImageIO.write(b,"png",new File("bug.png"));\r
117                                         }catch(Exception e){\r
118                                                 \r
119                                         }*/\r
120                                         //8方向全て調べたけどラベルが無いよ?\r
121                                         throw new NyARException();                      \r
122                                 }\r
123                         }else{\r
124                                 //境界に接しているとき                                \r
125                                 int i;\r
126                                 for (i = 0; i < 8; i++){                                \r
127                                         final int x=c + xdir[dir];\r
128                                         final int y=r + ydir[dir];\r
129                                         //境界チェック\r
130                                         if(x>=0 && x<width && y>=0 && y<height){\r
131                                                 if (i_buf[(y)*width+(x)] == 0) {\r
132                                                         break;\r
133                                                 }\r
134                                         }\r
135                                         dir++;//倍長テーブルを参照するので問題なし\r
136                                 }\r
137                                 if (i == 8) {\r
138                                         //8方向全て調べたけどラベルが無いよ?\r
139                                         throw new NyARException();// return(-1);\r
140                                 }                               \r
141                         }\r
142                         \r
143                         dir=dir% 8;//dirの正規化\r
144 \r
145                         // xcoordとycoordをc,rにも保存\r
146                         c = c + xdir[dir];\r
147                         r = r + ydir[dir];\r
148                         o_coord_x[coord_num] = c;\r
149                         o_coord_y[coord_num] = r;\r
150                         // 終了条件判定\r
151                         if (c == i_entry_x && r == i_entry_y){\r
152                                 coord_num++;\r
153                                 break;\r
154                         }\r
155                         coord_num++;\r
156                         if (coord_num == i_array_size) {\r
157                                 //輪郭が末端に達した\r
158                                 return coord_num;\r
159                         }\r
160                 }\r
161                 return coord_num;\r
162         }\r
163         public int getContour(NyARLabelingImage i_raster,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
164         {       \r
165                 final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
166                 final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
167 \r
168                 final int[] i_buf=(int[])i_raster.getBufferReader().getBuffer();\r
169                 final int width=i_raster.getWidth();\r
170                 final int height=i_raster.getHeight();\r
171                 //クリップ領域の上端に接しているポイントを得る。\r
172                 int sx=i_entry_x;\r
173                 int sy=i_entry_y;\r
174 \r
175                 int coord_num = 1;\r
176                 o_coord_x[0] = sx;\r
177                 o_coord_y[0] = sy;\r
178                 int dir = 5;\r
179 \r
180                 int c = o_coord_x[0];\r
181                 int r = o_coord_y[0];\r
182                 for (;;) {\r
183                         dir = (dir + 5) % 8;//dirの正規化\r
184                         //ここは頑張ればもっと最適化できると思うよ。\r
185                         //4隅以外の境界接地の場合に、境界チェックを省略するとかね。\r
186                         if(c>=1 && c<width-1 && r>=1 && r<height-1){\r
187                                 for(;;){//gotoのエミュレート用のfor文\r
188                                         //境界に接していないとき\r
189                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
190                                                 break;\r
191                                         }\r
192                                         dir++;\r
193                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
194                                                 break;\r
195                                         }\r
196                                         dir++;\r
197                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
198                                                 break;\r
199                                         }\r
200                                         dir++;\r
201                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
202                                                 break;\r
203                                         }\r
204                                         dir++;\r
205                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
206                                                 break;\r
207                                         }\r
208                                         dir++;\r
209                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
210                                                 break;\r
211                                         }\r
212                                         dir++;\r
213                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
214                                                 break;\r
215                                         }\r
216                                         dir++;\r
217                                         if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
218                                                 break;\r
219                                         }\r
220                                         //8方向全て調べたけどラベルが無いよ?\r
221                                         throw new NyARException();                      \r
222                                 }\r
223                         }else{\r
224                                 //境界に接しているとき\r
225                                 int i;\r
226                                 for (i = 0; i < 8; i++){                                \r
227                                         final int x=c + xdir[dir];\r
228                                         final int y=r + ydir[dir];\r
229                                         //境界チェック\r
230                                         if(x>=0 && x<width && y>=0 && y<height){\r
231                                                 if (i_buf[(y)*width+(x)] > 0) {\r
232                                                         break;\r
233                                                 }\r
234                                         }\r
235                                         dir++;//倍長テーブルを参照するので問題なし\r
236                                 }\r
237                                 if (i == 8) {\r
238                                         //8方向全て調べたけどラベルが無いよ?\r
239                                         throw new NyARException();// return(-1);\r
240                                 }                               \r
241                         }\r
242                         \r
243                         dir=dir% 8;//dirの正規化\r
244 \r
245                         // xcoordとycoordをc,rにも保存\r
246                         c = c + xdir[dir];\r
247                         r = r + ydir[dir];\r
248                         o_coord_x[coord_num] = c;\r
249                         o_coord_y[coord_num] = r;\r
250                         // 終了条件判定\r
251                         if (c == sx && r == sy){\r
252                                 coord_num++;\r
253                                 break;\r
254                         }\r
255                         coord_num++;\r
256                         if (coord_num == i_array_size) {\r
257                                 //輪郭が末端に達した\r
258                                 return coord_num;\r
259                         }\r
260                 }\r
261                 return coord_num;\r
262         }\r
263 \r
264 }\r