Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
203 chris 1
/*
2
 * PROJECT: NyARToolkit
3
 * --------------------------------------------------------------------------------
4
 * This work is based on the original ARToolKit developed by
5
 *   Hirokazu Kato
6
 *   Mark Billinghurst
7
 *   HITLab, University of Washington, Seattle
8
 * http://www.hitl.washington.edu/artoolkit/
9
 *
10
 * The NyARToolkit is Java version ARToolkit class library.
11
 * Copyright (C)2008 R.Iizuka
12
 *
13
 * This program is free software; you can redistribute it and/or
14
 * modify it under the terms of the GNU General Public License
15
 * as published by the Free Software Foundation; either version 2
16
 * of the License, or (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this framework; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 *
27
 * For further information please contact.
28
 *      http://nyatla.jp/nyatoolkit/
29
 *      <airmail(at)ebony.plala.or.jp>
30
 *
31
 */
32
package jp.nyatla.nyartoolkit.core;
33
 
34
 
35
 
36
 
37
import jp.nyatla.nyartoolkit.NyARException;
38
 
39
 
40
 
41
 
42
/**
43
 * イメージからマーカー情報を検出するクラス。
44
 * このクラスは、arDetectMarker2.cとの置き換えになります。
45
 * ラベリング済みのラスタデータからマーカー位置を検出して、結果を保持します。
46
 *
47
 */
48
public class NyARDetectMarker {
49
    private static final int AR_AREA_MAX=100000;//#define   AR_AREA_MAX      100000
50
    private static final int AR_AREA_MIN=70;//#define   AR_AREA_MIN          70
51
 
52
//    private final NyARMarker[] marker_holder;     //マーカーデータの保持配列
53
//    private final NyARMarker[] marker_info2_array;//マーカーデータのインデックス配列
54
//    private int marker_num;
55
    private int width,height;
56
    /**
57
     * 最大i_squre_max個のマーカーを検出するクラスを作成する。
58
     * @param i_width
59
     * @param i_height
60
     */
61
    public NyARDetectMarker(int i_width,int i_height)
62
    {
63
        this.width =i_width;
64
        this.height=i_height;
65
 
66
//      this.marker_holder=new NyARMarker[i_squre_max];
67
//      this.marker_info2_array=new NyARMarker[i_squre_max];
68
//      //先にマーカーホルダにオブジェクトを作っておく
69
//      for(int i=0;i<i_squre_max;i++){
70
//          this.marker_holder[i]=new NyARMarker();
71
//      }
72
    }
73
    private static final int AR_CHAIN_MAX=10000;
74
    private final int[] wk_arGetContour_xdir={0,  1, 1, 1, 0,-1,-1,-1};
75
    private final int[] wk_arGetContour_ydir={-1,-1, 0, 1, 1, 1, 0,-1};
76
    private final int[] wk_arGetContour_xcoord=new int[AR_CHAIN_MAX];
77
    private final int[] wk_arGetContour_ycoord=new int[AR_CHAIN_MAX];
78
    /**
79
     * int arGetContour( ARInt16 *limage, int *label_ref,int label, int clip[4], ARMarkerInfo2 *marker_info2 )
80
     * 関数の代替品
81
     * detectMarker関数から使う関数です。o_markerにlabelとclipで示される1個のマーカーを格納します。
82
     * marker_holder[i_holder_num]にオブジェクトが無ければまず新規に作成し、もし
83
     * 既に存在すればそこにマーカー情報を上書きして記録します。
84
     * Optimize:STEP[369->336]
85
     * @param o_marker
86
     * @param limage
87
     * @param label_ref
88
     * @param label
89
     * @param clip
90
     * @throws NyARException
91
     */
92
    private final void arGetContour(NyARMarker o_marker,int[][] limage, int[] label_ref,int i_labelnum, NyARLabel i_label) throws NyARException
93
    {
94
        final int[] xcoord=wk_arGetContour_xcoord;
95
        final int[] ycoord=wk_arGetContour_ycoord;
96
        final int[] xdir=wk_arGetContour_xdir; //static int      xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
97
        final int[] ydir=wk_arGetContour_ydir;//static int      ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
98
        //ShortPointer p1;//ARInt16         *p1;
99
        int coord_num;
100
        int             sx=0, sy=0, dir;
101
        int             dmax, d, v1=0;
102
        int             i, j,w;
103
 
104
        int[] limage_j;
105
        j = i_label.clip2;
106
        limage_j=limage[j];
107
        final int clip1=i_label.clip1;
108
        //p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 = &(limage[j*xsize+clip[0]]);
109
        for( i = i_label.clip0; i <= clip1; i++){//for( i = clip[0]; i <= clip[1]; i++, p1++ ) {
110
            w=limage_j[i];
111
            if(w > 0 && label_ref[w-1] == i_labelnum ) {//if( *p1 > 0 && label_ref[(*p1)-1] == label ) {
112
                sx = i;
113
                sy = j;
114
                break;
115
            }
116
        }
117
        if(i>clip1){//if( i > clip[1] ) {
118
            System.out.println("??? 1");//printf();
119
            throw new NyARException();//return(-1);
120
        }
121
 
122
//      //マーカーホルダが既に確保済みかを調べる
123
//      if(marker_holder[i_holder_num]==null){
124
//          //確保していなければ確保
125
//          marker_holder[i_holder_num]=new NyARMarker();
126
//      }
127
 
128
 
129
        coord_num=1;//marker_info2->coord_num = 1;
130
        xcoord[0]=sx;//marker_info2->x_coord[0] = sx;
131
        ycoord[0]=sy;//marker_info2->y_coord[0] = sy;
132
        dir = 5;
133
 
134
        int r,c;
135
        c=xcoord[0];
136
        r=ycoord[0];
137
        dmax=0;
138
        //本家はdmaxの作成とxcoordの作成を別のループでやってるけど、非効率なので統合
139
        for(;;){
140
            //xcoord[1]-xcoord[n]までのデータを作る。
141
 
142
//          1個前のxcoordとycoordはループ後半で格納される。
143
//          c=xcoord[coord_num-1];
144
//          r=ycoord[coord_num-1];
145
            //p1 = &(limage[marker_info2->y_coord[marker_info2->coord_num-1] * xsize+ marker_info2->x_coord[marker_info2->coord_num-1]]);
146
            dir = (dir+5)%8;
147
            for(i=0;i<8;i++) {
148
                if(limage[r+ydir[dir]][c+xdir[dir]]>0){//if( p1[ydir[dir]*xsize+xdir[dir]] > 0 ){
149
                    break;
150
                }
151
                dir = (dir+1)%8;       
152
            }
153
            if( i == 8 ){
154
                System.out.println("??? 2");//printf("??? 2\n");
155
                throw new NyARException();//return(-1);
156
            }
157
//          xcoordとycoordをc,rにも保存
158
            c= c + xdir[dir];//marker_info2->x_coord[marker_info2->coord_num]= marker_info2->x_coord[marker_info2->coord_num-1] + xdir[dir];
159
            r= r + ydir[dir];//marker_info2->y_coord[marker_info2->coord_num]= marker_info2->y_coord[marker_info2->coord_num-1] + ydir[dir];
160
            xcoord[coord_num]=c;//marker_info2->x_coord[marker_info2->coord_num]= marker_info2->x_coord[marker_info2->coord_num-1] + xdir[dir];
161
            ycoord[coord_num]=r;//marker_info2->y_coord[marker_info2->coord_num]= marker_info2->y_coord[marker_info2->coord_num-1] + ydir[dir];
162
            if(c == sx && r == sy ){
163
                break;
164
            }
165
            //dmaxの計算
166
            d=(c-sx)*(c-sx)+(r-sy)*(r-sy);
167
            if( d > dmax ) {
168
                dmax = d;
169
                v1 = coord_num;
170
            }
171
            //終了条件判定
172
            coord_num++;
173
            if(coord_num == AR_CHAIN_MAX-1){//if( marker_info2.coord_num == Config.AR_CHAIN_MAX-1 ){
174
                System.out.println("??? 3");//printf("??? 3\n");
175
                throw new NyARException();//return(-1);
176
            }
177
        }
178
//
179
//      dmax = 0;
180
//      for(i=1;i<coord_num;i++) {//    for(i=1;i<marker_info2->coord_num;i++) {
181
//          d = (xcoord[i]-sx)*(xcoord[i]-sx)+ (ycoord[i]-sy)*(ycoord[i]-sy);//   d = (marker_info2->x_coord[i]-sx)*(marker_info2->x_coord[i]-sx)+ (marker_info2->y_coord[i]-sy)*(marker_info2->y_coord[i]-sy);
182
//          if( d > dmax ) {
183
//              dmax = d;
184
//              v1 = i;
185
//          }
186
//      }
187
        //NyARMarkerへcoord情報をセット
188
        //coordの並び替えと保存はNyARMarkerへ移動
189
        o_marker.setCoordXY(v1,coord_num,xcoord,ycoord);
190
        return;
191
    }
192
 
193
    /**
194
     * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double factor, int *marker_num )
195
     * 関数の代替品
196
     * ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。
197
     * 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
198
     *
199
     * @param i_labeling
200
     * ラベリング済みの情報を持つラベリングオブジェクト
201
     * @param i_factor
202
     * 何かの閾値?
203
     * @param o_marker_list
204
     * 抽出したマーカーを格納するリスト
205
     * @throws NyARException
206
     */
207
    public final void detectMarker(NyARLabeling i_labeling,double i_factor,NyARMarkerList o_marker_list) throws NyARException
208
    {
209
        int label_area;
210
        int i;
211
        int xsize, ysize;
212
        NyARLabel[] labels=i_labeling.getLabel();
213
//      int[] warea     =i_labeling.getArea();
214
        int label_num   =i_labeling.getLabelNum();
215
//      int[][] wclip   =i_labeling.getClip();
216
//      double[] wpos   =i_labeling.getPos();
217
        int[][] limage=i_labeling.getLabelImg();
218
        int[] label_ref =i_labeling.getLabelRef();
219
 
220
        //マーカーホルダをリセット
221
        o_marker_list.reset();
222
//      marker_num=0;
223
        xsize =width;
224
        ysize =height;
225
//      マーカーをmarker_holderに蓄積する。
226
        NyARMarker current_marker=o_marker_list.getCurrentHolder();
227
        NyARLabel label_pt;
228
        for(i=0; i<label_num; i++ ){
229
            label_pt=labels[i];
230
            label_area=label_pt.area;
231
            if(label_area < AR_AREA_MIN || label_area > AR_AREA_MAX ){
232
                continue;
233
            }
234
            if( label_pt.clip0 == 1 || label_pt.clip1 == xsize-2 ){//if( wclip[i*4+0] == 1 || wclip[i*4+1] == xsize-2 ){
235
                continue;
236
            }
237
            if( label_pt.clip2 == 1 || label_pt.clip3 == ysize-2 ){//if( wclip[i*4+2] == 1 || wclip[i*4+3] == ysize-2 ){
238
                continue;
239
            }
240
            //ret = arGetContour( limage, label_ref, i+1,&(wclip[i*4]), &(marker_info2[marker_num2]));
241
            arGetContour(current_marker,limage, label_ref, i+1,label_pt);
242
 
243
            if(!current_marker.checkSquare(label_area,i_factor,label_pt.pos_x,label_pt.pos_y)){
244
                //後半で整理するからここはいらない。//         marker_holder[marker_num2]=null;
245
                continue;
246
            }
247
//          この3行はcheckSquareの最終段に含める。
248
//          marker_holder[marker_num2].area   = warea[i];
249
//          marker_holder[marker_num2].pos[0] = wpos[i*2+0];
250
//          marker_holder[marker_num2].pos[1] = wpos[i*2+1];
251
            //マーカー検出→次のホルダを取得
252
            current_marker=o_marker_list.getNextHolder();
253
            //マーカーリストが上限に達したか確認
254
            if(current_marker==null){
255
                break;
256
            }
257
        }
258
        //マーカーリストを整理(重なり処理とかはマーカーリストに責務押し付け)
259
        o_marker_list.updateMarkerArray();
260
//      重なり処理かな?
261
//      double[] pos_j,pos_i;
262
//      for(i=0; i < marker_num2; i++ ){
263
//          pos_i=marker_holder[i].pos;
264
//          for(j=i+1; j < marker_num2; j++ ) {
265
//              pos_j=marker_holder[j].pos;
266
//              d = (pos_i[0] - pos_j[0])*(pos_i[0] - pos_j[0])+
267
//              (pos_i[1] - pos_j[1])*(pos_i[1] - pos_j[1]);
268
//              if(marker_holder[i].area >marker_holder[j].area ) {
269
//                  if( d <marker_holder[i].area / 4 ) {
270
//                      marker_holder[j].area = 0;
271
//                  }
272
//              }else{
273
//                  if( d < marker_holder[j].area / 4 ) {
274
//                      marker_holder[i].area = 0;
275
//                  }
276
//              }
277
//          }
278
//      }
279
//      みつかったマーカーを整理する。
280
//      エリアが0のマーカーを外した配列を作って、その数もついでに計算
281
//      for(i=0;i<marker_num2;i++){
282
//          if(marker_holder[i].area==0.0){
283
//              continue;
284
//          }
285
//          marker_info2_array[marker_num]=marker_holder[i];
286
//          marker_num++;
287
//      }        
288
//      for( i=0; i < marker_num2; i++ ) {
289
//      if( marker_info2_array[i].area == 0.0 ) {
290
//      for( j=i+1; j < marker_num2; j++ ){
291
//      marker_info2_array[j-1] = marker_info2_array[j];
292
//      }
293
//      marker_num2--;
294
//      }
295
//      }
296
//      発見したマーカー数をセット
297
//      marker_num=marker_num2;//*marker_num = marker_num2;
298
//      return( &(marker_info2[0]) );
299
        return;
300
    }
301
 
302
}