OSDN Git Service

d649977dc5b5097a99f9fcf503c8420ed0bb8783
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core / NyARLabeling.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;\r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.raster.*;\r
36 \r
37 \r
38 \r
39 \r
40 /**\r
41  * ラベリングクラス。NyARRasterをラベリングして、結果値を保持します。\r
42  *\r
43  */\r
44 public class NyARLabeling{\r
45     private final int WORK_SIZE=1024*32;//#define WORK_SIZE   1024*32\r
46     private short[][] label_img;//static ARInt16 l_imageL[HARDCODED_BUFFER_WIDTH*HARDCODED_BUFFER_HEIGHT];\r
47     private int[] work=new int[WORK_SIZE];//static int workL[WORK_SIZE];\r
48     private int[] work2=new int[WORK_SIZE*7];//static int work2L[WORK_SIZE*7];\r
49     private int[] area=new int[WORK_SIZE];//static int          wareaL[WORK_SIZE];\r
50     private int[][] clip=new int[WORK_SIZE][4];//static int          wclipL[WORK_SIZE*4];\r
51     private double[] pos=new double[WORK_SIZE*2];//static double       wposL[WORK_SIZE*2];\r
52     private int label_num;\r
53     //\r
54     private int width;\r
55     private int height;\r
56     /**\r
57      * @param i_width\r
58      * ラベリング画像の幅。解析するラスタの幅より大きいこと。\r
59      * @param i_height\r
60      * ラベリング画像の高さ。解析するラスタの高さより大きいこと。\r
61      */\r
62     public NyARLabeling(int i_width,int i_height)\r
63     {\r
64         width =i_width;\r
65         height=i_height;\r
66         label_img=new short[height][width];\r
67         label_num=0;\r
68     }\r
69     /**\r
70      * 検出したラベルの数を返す\r
71      * @return\r
72      */\r
73     public int getLabelNum()\r
74     {\r
75         return label_num;\r
76     }\r
77     /**\r
78      * わからん\r
79      * @return\r
80      * @throws NyARException\r
81      */\r
82     public int[] getLabelRef() throws NyARException\r
83     {\r
84         if(label_num<1){\r
85             throw new NyARException();\r
86         }\r
87         return work;\r
88     }\r
89     /**\r
90      * 検出したエリア配列?よくわからぬ\r
91      * @return\r
92      * @throws NyARException\r
93      */\r
94     public int[] getArea() throws NyARException\r
95     {\r
96         if(label_num<1){\r
97             throw new NyARException();\r
98         }\r
99         return area;\r
100     }\r
101     /**\r
102      * 検出したクリップ配列?よくわからぬ\r
103      * @return\r
104      * @throws NyARException\r
105      */\r
106     public int[][] getClip() throws NyARException\r
107     {\r
108         if(label_num<1){\r
109             throw new NyARException();\r
110         }\r
111         return clip;\r
112     }\r
113     /**\r
114      * 検出した位置配列?よくわからぬ\r
115      * @return\r
116      * @throws NyARException\r
117      */\r
118     public double[] getPos() throws NyARException\r
119     {\r
120         if(label_num<1){\r
121             throw new NyARException();\r
122         }\r
123         return pos;\r
124     }\r
125     /**\r
126      * ラベリング済みイメージを返す\r
127      * @return\r
128      * @throws NyARException\r
129      */\r
130     public short[][] getLabelImg() throws NyARException\r
131     {\r
132         if(label_num<1){\r
133             throw new NyARException();\r
134         }\r
135         return label_img;\r
136     }\r
137     /**\r
138      * 配列の先頭からsize個をゼロクリアする\r
139      * @param array\r
140      * @param size\r
141      */\r
142     private void putZero(int[] array,int size)\r
143     {\r
144         for(int i=0;i<size;i++){\r
145             array[i]=0;\r
146         }\r
147     }\r
148     /**\r
149      * 配列の先頭からsize個をゼロクリアする\r
150      * @param array\r
151      * @param size\r
152      */\r
153     private void putZero(double[] array,int size)\r
154     {\r
155         for(int i=0;i<size;i++){\r
156             array[i]=0;\r
157         }\r
158     }\r
159     /**\r
160      * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )\r
161      * 関数の代替品\r
162      * ラスタimageをラベリングして、結果を保存します。\r
163      * @param image\r
164      * @param thresh\r
165      * @throws NyARException\r
166      */\r
167     public void labeling(NyARRaster image,int thresh) throws NyARException\r
168     {\r
169         int       wk_max;                   /*  work                */\r
170         int       m,n;                      /*  work                */\r
171         int       lxsize, lysize;\r
172         int[] warea;//int       *warea;\r
173         int[][] wclip;//int       *wclip;\r
174         double[] wpos;//double    *wpos;\r
175         int               thresht3 = thresh * 3;\r
176         \r
177         //ラベル数を0に初期化\r
178         label_num=0;\r
179     \r
180         warea=area;//warea   = &wareaL[0];\r
181         wclip=clip;//wclip   = &wclipL[0];\r
182         wpos=pos;//wpos    = &wposL[0];\r
183     \r
184         lxsize=image.getWidth();//lxsize = arUtil_c.arImXsize;\r
185         lysize=image.getHeight();//lysize = arUtil_c.arImYsize;\r
186     \r
187         for(int i = 0; i < lxsize; i++){\r
188             label_img[0][i]=0;\r
189             label_img[lysize-1][i]=0;\r
190         }\r
191         for(int i = 0; i < lysize; i++) {\r
192             label_img[i][0]=0;\r
193             label_img[i][lxsize-1]=0;                       \r
194         }\r
195         int nya_pnt_start_x_start,nya_pnt_start_y_start;\r
196         int nya_poff_step;//スキャンステップ\r
197 \r
198         wk_max = 0;\r
199         nya_pnt_start_y_start=1;\r
200         nya_pnt_start_x_start=1;\r
201         nya_poff_step=1;//スキャンステップ\r
202         int nya_pnt_start_y=nya_pnt_start_y_start;\r
203         for (int j = 1; j < lysize - 1; j++, nya_pnt_start_y++) {//for (int j = 1; j < lysize - 1; j++, pnt += poff*2, pnt2 += 2) {\r
204             int nya_pnt_start_x=nya_pnt_start_x_start;\r
205             int p1=j-1;\r
206             int p2=j;\r
207             for(int i = 1; i < lxsize-1; i++, nya_pnt_start_x+=nya_poff_step) {//for(int i = 1; i < lxsize-1; i++, pnt+=poff, pnt2++) {\r
208                 //RGBの合計値が閾値より大きいかな?\r
209                 if(image.getPixcelTotal(nya_pnt_start_x,nya_pnt_start_y)<=thresht3){\r
210                     //pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 = &(pnt2[-lxsize]);\r
211                     if(label_img[p1][i]>0){//if( *pnt1 > 0 ) {\r
212                         label_img[p2][i]=label_img[p1][i];//*pnt2 = *pnt1;\r
213 \r
214 \r
215                         int p2_index=(label_img[p2][i]-1)*7;\r
216                         work2[p2_index+0]++;//work2[((*pnt2)-1)*7+0] ++;\r
217                         work2[p2_index+1]+=i;//work2[((*pnt2)-1)*7+1] += i;\r
218                         work2[p2_index+2]+=j;//work2[((*pnt2)-1)*7+2] += j;\r
219                         work2[p2_index+6]=j;//work2[((*pnt2)-1)*7+6] = j;\r
220                     }else if(label_img[p1][i+1]> 0 ) {//}else if( *(pnt1+1) > 0 ) {\r
221                         if(label_img[p1][i-1] > 0 ) {//if( *(pnt1-1) > 0 ) {\r
222                             m = work[label_img[p1][i+1]-1];//m = work[*(pnt1+1)-1];\r
223                             n = work[label_img[p1][i-1]-1];//n = work[*(pnt1-1)-1];\r
224                             if( m > n ){\r
225                                 //JartkException.trap("未チェックのパス");\r
226                                 label_img[p2][i]=(short)n;//*pnt2 = n;\r
227                                 //wk=IntPointer.wrap(work, 0);//wk = &(work[0]);\r
228                                 for(int k = 0; k < wk_max; k++) {\r
229                                     //JartkException.trap("未チェックのパス");\r
230                                     if(work[k] == m ){//if( *wk == m ) \r
231                                         //JartkException.trap("未チェックのパス");\r
232                                         work[k]=n;//*wk = n;\r
233                                     }\r
234                                 }\r
235                             }else if( m < n ) {\r
236                                 //JartkException.trap("未チェックのパス");\r
237                                 label_img[p2][i]=(short)m;//*pnt2 = m;\r
238                                 //wk=IntPointer.wrap(work,0);//wk = &(work[0]);\r
239                                 for(int k = 0; k < wk_max; k++){\r
240                                     //JartkException.trap("未チェックのパス");\r
241                                     if(work[k]==n){//if( *wk == n ){\r
242                                         //JartkException.trap("未チェックのパス");\r
243                                         work[k]=m;//*wk = m;\r
244                                     }\r
245                                 }\r
246                             }else{\r
247                                 label_img[p2][i]=(short)m;//*pnt2 = m;\r
248                             }\r
249 \r
250                             int p2_index=(label_img[p2][i]-1)*7;\r
251                             work2[p2_index+0] ++;\r
252                             work2[p2_index+1] += i;\r
253                             work2[p2_index+2] += j;\r
254                             work2[p2_index+6] = j;\r
255                         }else if( (label_img[p2][i-1]) > 0 ) {//}else if( *(pnt2-1) > 0 ) {\r
256                             m = work[(label_img[p1][i+1])-1];//m = work[*(pnt1+1)-1];\r
257                             n = work[(label_img[p2][i-1])-1];//n = work[*(pnt2-1)-1];\r
258                             if( m > n ) {\r
259 \r
260                                 label_img[p2][i]=(short)n;//*pnt2 = n;\r
261                                 for(int k = 0; k < wk_max; k++) {\r
262                                     if(work[k]==m){//if( *wk == m ){\r
263                                         work[k]=n;//*wk = n;\r
264                                     }\r
265                                 }\r
266                             }else if( m < n ) {\r
267                                 label_img[p2][i]=(short)m;//*pnt2 = m;\r
268                                 for(int k = 0; k < wk_max; k++) {\r
269                                     if(work[k]==n){//if( *wk == n ){\r
270                                         work[k]=m;//*wk = m;\r
271                                     }\r
272                                 }\r
273                             }else{\r
274                                 label_img[p2][i]=(short)m;//*pnt2 = m;\r
275                             }\r
276 \r
277 \r
278                             int p2_index=((label_img[p2][i])-1)*7;\r
279                             work2[p2_index+0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
280                             work2[p2_index+1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
281                             work2[p2_index+2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
282                         }else{\r
283 \r
284                             label_img[p2][i]=label_img[p1][i+1];//*pnt2 = *(pnt1+1);\r
285                             \r
286                             int p2_index=((label_img[p2][i])-1)*7;\r
287                             work2[p2_index+0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
288                             work2[p2_index+1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
289                             work2[p2_index+2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
290                             if( work2[p2_index+3] > i ){//if( work2[((*pnt2)-1)*7+3] > i ){             \r
291                                 work2[p2_index+3] = i;//        work2[((*pnt2)-1)*7+3] = i;\r
292                             }\r
293                             work2[p2_index+6] = j;//work2[((*pnt2)-1)*7+6] = j;\r
294                         }\r
295                     }else if( (label_img[p1][i-1]) > 0 ) {//}else if( *(pnt1-1) > 0 ) {\r
296                         label_img[p2][i]=label_img[p1][i-1];//*pnt2 = *(pnt1-1);\r
297 \r
298                         int p2_index=((label_img[p2][i])-1)*7;\r
299                         work2[p2_index+0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
300                         work2[p2_index+1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
301                         work2[p2_index+2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
302                         if( work2[p2_index+4] < i ){//if( work2[((*pnt2)-1)*7+4] < i ){\r
303                             work2[p2_index+4] = i;//    work2[((*pnt2)-1)*7+4] = i;\r
304                         }\r
305                         work2[p2_index+6] = j;//work2[((*pnt2)-1)*7+6] = j;\r
306                     }else if(label_img[p2][i-1] > 0) {//}else if( *(pnt2-1) > 0) {\r
307                         label_img[p2][i]=label_img[p2][i-1];//*pnt2 = *(pnt2-1);\r
308 \r
309                         int p2_index=((label_img[p2][i])-1)*7;\r
310                         work2[p2_index+0] ++;//work2[((*pnt2)-1)*7+0] ++;\r
311                         work2[p2_index+1] += i;//work2[((*pnt2)-1)*7+1] += i;\r
312                         work2[p2_index+2] += j;//work2[((*pnt2)-1)*7+2] += j;\r
313                         if( work2[p2_index+4] < i ){//if( work2[((*pnt2)-1)*7+4] < i ){\r
314                             work2[p2_index+4] = i;//    work2[((*pnt2)-1)*7+4] = i;\r
315                         }\r
316                     }else{\r
317                         wk_max++;\r
318                         if( wk_max > WORK_SIZE ) {\r
319                             throw new NyARException();//return (0);\r
320                         }\r
321                         work[wk_max-1] = wk_max;label_img[p2][i]=(short)wk_max;//work[wk_max-1] = *pnt2 = wk_max;\r
322                         work2[(wk_max-1)*7+0] = 1;\r
323                         work2[(wk_max-1)*7+1] = i;\r
324                         work2[(wk_max-1)*7+2] = j;\r
325                         work2[(wk_max-1)*7+3] = i;\r
326                         work2[(wk_max-1)*7+4] = i;\r
327                         work2[(wk_max-1)*7+5] = j;\r
328                         work2[(wk_max-1)*7+6] = j;\r
329                     }\r
330                 }else {\r
331                     label_img[p2][i]=0;//*pnt2 = 0;\r
332                 }\r
333             }\r
334         }\r
335         int j = 1;\r
336         for(int i = 0; i < wk_max; i++){//for(int i = 1; i <= wk_max; i++, wk++) {\r
337             work[i]=(work[i]==i+1)? j++: work[work[i]-1];//*wk = (*wk==i)? j++: work[(*wk)-1];\r
338         }\r
339         \r
340         int wlabel_num=j - 1;//*label_num = *wlabel_num = j - 1;\r
341 \r
342         if(wlabel_num==0){//if( *label_num == 0 ) {\r
343             //発見数0\r
344             return;\r
345         }\r
346 \r
347         putZero(warea,wlabel_num);//put_zero( (ARUint8 *)warea, *label_num *     sizeof(int) );\r
348         putZero(wpos,wlabel_num*2);//put_zero( (ARUint8 *)wpos,  *label_num * 2 * sizeof(double) );\r
349         for(int i = 0; i < wlabel_num; i++) {//for(i = 0; i < *label_num; i++) {\r
350             wclip[i][0] = lxsize;//wclip[i*4+0] = lxsize;\r
351             wclip[i][1] = 0;//wclip[i*4+1] = 0;\r
352             wclip[i][2] = lysize;//wclip[i*4+2] = lysize;\r
353             wclip[i][3] = 0;//wclip[i*4+3] = 0;\r
354         }\r
355         for(int i = 0; i < wk_max; i++) {\r
356             j = work[i] - 1;\r
357             warea[j]    += work2[i*7+0];\r
358             wpos[j*2+0] += work2[i*7+1];\r
359             wpos[j*2+1] += work2[i*7+2];\r
360             if( wclip[j][0] > work2[i*7+3] ){\r
361                 wclip[j][0] = work2[i*7+3];\r
362             }\r
363             if( wclip[j][1] < work2[i*7+4] ){\r
364                 wclip[j][1] = work2[i*7+4];\r
365             }\r
366             if( wclip[j][2] > work2[i*7+5] ){\r
367                 wclip[j][2] = work2[i*7+5];\r
368             }\r
369             if( wclip[j][3] < work2[i*7+6] ){\r
370                 wclip[j][3] = work2[i*7+6];\r
371             }\r
372         }\r
373 \r
374         for(int i = 0; i < wlabel_num; i++ ) {//for(int i = 0; i < *label_num; i++ ) {\r
375             wpos[i*2+0] /= warea[i];\r
376             wpos[i*2+1] /= warea[i];\r
377         }\r
378         \r
379         label_num=wlabel_num;\r
380         return;\r
381     }\r
382 }\r
383 \r