2 * PROJECT: NyARToolkit
\r
3 * --------------------------------------------------------------------------------
\r
4 * This work is based on the original ARToolKit developed by
\r
7 * HITLab, University of Washington, Seattle
\r
8 * http://www.hitl.washington.edu/artoolkit/
\r
10 * The NyARToolkit is Java version ARToolkit class library.
\r
11 * Copyright (C)2008 R.Iizuka
\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
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
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
27 * For further information please contact.
\r
28 * http://nyatla.jp/nyatoolkit/
\r
29 * <airmail(at)ebony.plala.or.jp>
\r
32 package jp.nyatla.nyartoolkit.core;
\r
34 import jp.nyatla.nyartoolkit.NyARException;
\r
35 import jp.nyatla.nyartoolkit.core.raster.*;
\r
41 * ラベリングクラス。NyARRasterをラベリングして、結果値を保持します。
\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
58 * ラベリング画像の幅。解析するラスタの幅より大きいこと。
\r
60 * ラベリング画像の高さ。解析するラスタの高さより大きいこと。
\r
62 public NyARLabeling(int i_width,int i_height)
\r
66 label_img=new short[height][width];
\r
73 public int getLabelNum()
\r
80 * @throws NyARException
\r
82 public int[] getLabelRef() throws NyARException
\r
85 throw new NyARException();
\r
92 * @throws NyARException
\r
94 public int[] getArea() throws NyARException
\r
97 throw new NyARException();
\r
102 * 検出したクリップ配列?よくわからぬ
\r
104 * @throws NyARException
\r
106 public int[][] getClip() throws NyARException
\r
109 throw new NyARException();
\r
116 * @throws NyARException
\r
118 public double[] getPos() throws NyARException
\r
121 throw new NyARException();
\r
128 * @throws NyARException
\r
130 public short[][] getLabelImg() throws NyARException
\r
133 throw new NyARException();
\r
138 * 配列の先頭からsize個をゼロクリアする
\r
142 private void putZero(int[] array,int size)
\r
144 for(int i=0;i<size;i++){
\r
149 * 配列の先頭からsize個をゼロクリアする
\r
153 private void putZero(double[] array,int size)
\r
155 for(int i=0;i<size;i++){
\r
160 * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR )
\r
162 * ラスタimageをラベリングして、結果を保存します。
\r
165 * @throws NyARException
\r
167 public void labeling(NyARRaster image,int thresh) throws NyARException
\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
180 warea=area;//warea = &wareaL[0];
\r
181 wclip=clip;//wclip = &wclipL[0];
\r
182 wpos=pos;//wpos = &wposL[0];
\r
184 lxsize=image.getWidth();//lxsize = arUtil_c.arImXsize;
\r
185 lysize=image.getHeight();//lysize = arUtil_c.arImYsize;
\r
187 for(int i = 0; i < lxsize; i++){
\r
189 label_img[lysize-1][i]=0;
\r
191 for(int i = 0; i < lysize; i++) {
\r
193 label_img[i][lxsize-1]=0;
\r
195 int nya_pnt_start_x_start,nya_pnt_start_y_start;
\r
196 int nya_poff_step;//スキャンステップ
\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
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
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
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
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
247 label_img[p2][i]=(short)m;//*pnt2 = m;
\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
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
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
274 label_img[p2][i]=(short)m;//*pnt2 = m;
\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
284 label_img[p2][i]=label_img[p1][i+1];//*pnt2 = *(pnt1+1);
\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
293 work2[p2_index+6] = j;//work2[((*pnt2)-1)*7+6] = j;
\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
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
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
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
318 if( wk_max > WORK_SIZE ) {
\r
319 throw new NyARException();//return (0);
\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
331 label_img[p2][i]=0;//*pnt2 = 0;
\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
340 int wlabel_num=j - 1;//*label_num = *wlabel_num = j - 1;
\r
342 if(wlabel_num==0){//if( *label_num == 0 ) {
\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
355 for(int i = 0; i < wk_max; i++) {
\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
363 if( wclip[j][1] < work2[i*7+4] ){
\r
364 wclip[j][1] = work2[i*7+4];
\r
366 if( wclip[j][2] > work2[i*7+5] ){
\r
367 wclip[j][2] = work2[i*7+5];
\r
369 if( wclip[j][3] < work2[i*7+6] ){
\r
370 wclip[j][3] = work2[i*7+6];
\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
379 label_num=wlabel_num;
\r