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
import jp.nyatla.nyartoolkit.NyARException;
37
import jp.nyatla.nyartoolkit.core.raster.NyARRaster;
38
 
39
/**
40
 * 24ビットカラーのマーカーを保持するために使うクラスです。
41
 * このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。
42
 * 演算順序を含む最適化をしたもの
43
 *
44
 */
45
public class NyARColorPatt_O3 implements NyARColorPatt
46
{
47
    private static final int AR_PATT_SAMPLE_NUM=64;//#define   AR_PATT_SAMPLE_NUM   64
48
    private int extpat[][][];
49
    private int width;
50
    private int height;
51
    public NyARColorPatt_O3(int i_width,int i_height)
52
    {
53
        this.width=i_width;
54
        this.height=i_height;
55
        this.extpat=new int[i_height][i_width][3];
56
    }
57
//    public void setSize(int i_new_width,int i_new_height)
58
//    {
59
//      int array_w=this.extpat[0].length;
60
//      int array_h=this.extpat.length;
61
//      //十分なサイズのバッファがあるか確認
62
//      if(array_w>=i_new_width && array_h>=i_new_height){
63
//          //OK 十分だ→サイズ調整のみ
64
//      }else{
65
//          //足りないよ→取り直し
66
//          this.extpat=new int[i_new_height][i_new_width][3];
67
//      }
68
//        this.width =i_new_width;
69
//        this.height=i_new_height;
70
//        return;
71
//    }    
72
    public int[][][] getPatArray()
73
    {
74
        return extpat;
75
    }
76
    public int getWidth()
77
    {
78
        return width;
79
    }
80
    public int getHeight()
81
    {
82
        return height;
83
    }
84
    private final NyARMat wk_get_cpara_a=new NyARMat(8,8);
85
    private final NyARMat wk_get_cpara_b=new NyARMat(8,1);
86
 
87
    /**
88
     * @param world
89
     * @param vertex
90
     * @param o_para
91
     * @throws NyARException
92
     */
93
    private boolean get_cpara(double vertex_0[], double vertex_1[],NyARMat o_para) throws NyARException
94
    {
95
        double world[][]=this.wk_pickFromRaster_world;
96
        NyARMat a =wk_get_cpara_a;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );
97
        double[][] a_array=a.getArray();
98
        NyARMat b =wk_get_cpara_b;//次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );
99
        double[][] b_array=b.getArray();
100
        double[] a_pt0,a_pt1,world_pti;
101
 
102
        for(int i = 0; i < 4; i++ ) {
103
            a_pt0=a_array[i*2];
104
            a_pt1=a_array[i*2+1];
105
            world_pti=world[i];
106
 
107
            a_pt0[0]=world_pti[0];//a->m[i*16+0]  = world[i][0];
108
            a_pt0[1]=world_pti[1];//a->m[i*16+1]  = world[i][1];
109
            a_pt0[2]=1.0;//a->m[i*16+2]  = 1.0;
110
            a_pt0[3]=0.0;//a->m[i*16+3]  = 0.0;
111
            a_pt0[4]=0.0;//a->m[i*16+4]  = 0.0;
112
            a_pt0[5]=0.0;//a->m[i*16+5]  = 0.0;
113
            a_pt0[6]=-world_pti[0] * vertex_0[i];//a->m[i*16+6]  = -world[i][0] * vertex[i][0];
114
            a_pt0[7]=-world_pti[1] * vertex_0[i];//a->m[i*16+7]  = -world[i][1] * vertex[i][0];
115
            a_pt1[0]=0.0;//a->m[i*16+8]  = 0.0;
116
            a_pt1[1]=0.0;//a->m[i*16+9]  = 0.0;
117
            a_pt1[2]=0.0;//a->m[i*16+10] = 0.0;
118
            a_pt1[3]=world_pti[0];//a->m[i*16+11] = world[i][0];
119
            a_pt1[4]=world_pti[1];//a->m[i*16+12] = world[i][1];
120
            a_pt1[5]=1.0;//a->m[i*16+13] = 1.0;
121
            a_pt1[6]=-world_pti[0] * vertex_1[i];//a->m[i*16+14] = -world[i][0] * vertex[i][1];
122
            a_pt1[7]=-world_pti[1] * vertex_1[i];//a->m[i*16+15] = -world[i][1] * vertex[i][1];
123
            b_array[i*2+0][0]=vertex_0[i];//b->m[i*2+0] = vertex[i][0];
124
            b_array[i*2+1][0]=vertex_1[i];//b->m[i*2+1] = vertex[i][1];
125
        }
126
        if(!a.matrixSelfInv()){
127
            return false;
128
        }          
129
 
130
        o_para.matrixMul(a, b);
131
        return true;
132
    }
133
 
134
  //   private final double[] wk_pickFromRaster_para=new double[9];//[3][3];
135
    private final double[][] wk_pickFromRaster_world={//double    world[4][2];
136
            {100.0,     100.0},
137
            {100.0+10.0,100.0},
138
            {100.0+10.0,100.0 + 10.0},
139
            {100.0,     100.0 + 10.0}
140
    };
141
    /**
142
     * pickFromRaster関数から使う変数です。
143
     *
144
     */
145
    private static void initValue_wk_pickFromRaster_ext_pat2(int[][][] i_ext_pat2,int i_width,int i_height)
146
    {
147
        int i,i2;
148
        int[][] pt2;
149
        int[]   pt1;
150
        for(i=i_height-1;i>=0;i--){
151
            pt2=i_ext_pat2[i];
152
            for(i2=i_width-1;i2>=0;i2--){
153
                pt1=pt2[i2];
154
                pt1[0]=0;
155
                pt1[1]=0;
156
                pt1[2]=0;
157
            }
158
        }
159
    }
160
    private final double[][] wk_pickFromRaster_local=new double[2][4];
161
    private final NyARMat wk_pickFromRaster_cpara=new NyARMat(8,1);
162
    /**
163
     * imageから、i_markerの位置にあるパターンを切り出して、保持します。
164
     * Optimize:STEP[769->750]
165
     * @param image
166
     * @param i_marker
167
     * @throws Exception
168
     */
169
    public boolean pickFromRaster(NyARRaster image, NyARMarker i_marker) throws NyARException
170
    {
171
        NyARMat cpara=this.wk_pickFromRaster_cpara;
172
        //localの計算
173
        int[] x_coord=i_marker.x_coord;
174
        int[] y_coord=i_marker.y_coord;
175
        int[] vertex=i_marker.mkvertex;
176
        double[] local_0=wk_pickFromRaster_local[0];//double    local[4][2];    
177
        double[] local_1=wk_pickFromRaster_local[1];//double    local[4][2];    
178
        for(int i = 0; i < 4; i++ ) {
179
            local_0[i] = x_coord[vertex[i]];
180
            local_1[i] = y_coord[vertex[i]];
181
        }
182
        //xdiv2,ydiv2の計算
183
        int xdiv2, ydiv2;
184
        int l1,l2;
185
        double w1,w2;
186
 
187
        //x計算
188
        w1=local_0[0] - local_0[1];
189
        w2=local_1[0] - local_1[1];
190
        l1 = (int)(w1*w1+w2*w2);
191
        w1=local_0[2] - local_0[3];
192
        w2=local_1[2] - local_1[3];
193
        l2 = (int)(w1*w1+w2*w2);
194
        if( l2 > l1 ){
195
            l1 = l2;
196
        }
197
        l1=l1/4;
198
        xdiv2 =this.width;
199
        while( xdiv2*xdiv2 < l1 ){
200
            xdiv2*=2;
201
        }
202
        if( xdiv2 > AR_PATT_SAMPLE_NUM)
203
        {
204
            xdiv2 =AR_PATT_SAMPLE_NUM;
205
        }
206
 
207
        //y計算
208
        w1=local_0[1] - local_0[2];
209
        w2=local_1[1] - local_1[2];
210
        l1 = (int)(w1*w1+ w2*w2);
211
        w1=local_0[3] - local_0[0];
212
        w2=local_1[3] - local_1[0];
213
        l2 = (int)(w1*w1+ w2*w2);
214
        if( l2 > l1 ){
215
            l1 = l2;
216
        }
217
        ydiv2 =this.height;
218
        l1=l1/4;
219
        while( ydiv2*ydiv2 < l1 ){
220
            ydiv2*=2;
221
        }
222
        if( ydiv2 >AR_PATT_SAMPLE_NUM)
223
        {
224
            ydiv2 = AR_PATT_SAMPLE_NUM;
225
        }      
226
 
227
        //cparaの計算
228
        if(!get_cpara(local_0,local_1,cpara)){
229
            return false;
230
        }
231
        updateExtpat(image,cpara,xdiv2,ydiv2);
232
 
233
        return true;
234
    }
235
    //かなり大きいワークバッファを取るな…。
236
    private double[] wk_updateExtpat_para00_xw;
237
    private double[] wk_updateExtpat_para10_xw;
238
    private double[] wk_updateExtpat_para20_xw;
239
    private int[] wk_updateExtpat_rgb_buf;
240
    private int[] wk_updateExtpat_x_rgb_index;
241
    private int[] wk_updateExtpat_y_rgb_index;
242
    private int[] wk_updateExtpat_i_rgb_index;
243
    private int wk_updateExtpat_buffer_size=0;
244
 
245
    /**
246
     * ワークバッファを予約する
247
     * @param i_xdiv2
248
     */
249
    private void reservWorkBuffers(int i_xdiv2)
250
    {
251
        if(this.wk_updateExtpat_buffer_size<i_xdiv2){
252
            wk_updateExtpat_para00_xw=new double[i_xdiv2];
253
            wk_updateExtpat_para10_xw=new double[i_xdiv2];
254
            wk_updateExtpat_para20_xw=new double[i_xdiv2];
255
            wk_updateExtpat_rgb_buf=new int[i_xdiv2*3];
256
            wk_updateExtpat_x_rgb_index=new int[i_xdiv2];
257
            wk_updateExtpat_y_rgb_index=new int[i_xdiv2];
258
            wk_updateExtpat_i_rgb_index=new int[i_xdiv2];
259
            this.wk_updateExtpat_buffer_size=i_xdiv2;
260
        }
261
        //十分なら何もしない。
262
        return;
263
    }
264
 
265
    private void updateExtpat(NyARRaster image,NyARMat i_cpara,int i_xdiv2,int i_ydiv2) throws NyARException
266
    {
267
        int img_x=image.getWidth();
268
        int img_y=image.getHeight();
269
        final int[][][] L_extpat=this.extpat;
270
        final int L_WIDTH=this.width;
271
        final int L_HEIGHT=this.height;
272
        /*wk_pickFromRaster_ext_pat2ワーク変数を初期化する。*/
273
        //int[][][] ext_pat2=wk_pickFromRaster_ext_pat2;//ARUint32  ext_pat2[AR_PATT_SIZE_Y][AR_PATT_SIZE_X][3];
274
        int extpat_j[][],extpat_j_i[];
275
        //int ext_pat2_j[][],ext_pat2_j_i[];
276
 
277
        initValue_wk_pickFromRaster_ext_pat2(L_extpat,L_WIDTH,L_HEIGHT);
278
 
279
        double[][] cpara_array=i_cpara.getArray();
280
        double para21_x_yw,para01_x_yw,para11_x_yw;
281
        double para00,para01,para02,para10,para11,para12,para20,para21;
282
        para00 = cpara_array[0*3+0][0];//para[i][0] = c->m[i*3+0];
283
        para01 = cpara_array[0*3+1][0];//para[i][1] = c->m[i*3+1];
284
        para02 = cpara_array[0*3+2][0];//para[i][2] = c->m[i*3+2];
285
        para10 = cpara_array[1*3+0][0];//para[i][0] = c->m[i*3+0];
286
        para11 = cpara_array[1*3+1][0];//para[i][1] = c->m[i*3+1];
287
        para12 = cpara_array[1*3+2][0];//para[i][2] = c->m[i*3+2];
288
        para20 = cpara_array[2*3+0][0];//para[2][0] = c->m[2*3+0];
289
        para21 = cpara_array[2*3+1][0];//para[2][1] = c->m[2*3+1];
290
 
291
 
292
        double          d,yw;
293
        int             xc, yc;
294
        int i,j;
295
        //      arGetCode_put_zero(ext_pat2);//put_zero( (ARUint8 *)ext_pat2, AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3*sizeof(ARUint32) );
296
        int xdiv = i_xdiv2/L_WIDTH;//xdiv = xdiv2/Config.AR_PATT_SIZE_X;
297
        int ydiv = i_ydiv2/L_HEIGHT;//ydiv = ydiv2/Config.AR_PATT_SIZE_Y;
298
 
299
        //計算バッファを予約する
300
        this.reservWorkBuffers(i_xdiv2);       
301
        double[] para00_xw=this.wk_updateExtpat_para00_xw;
302
        double[] para10_xw=this.wk_updateExtpat_para10_xw;
303
        double[] para20_xw=this.wk_updateExtpat_para20_xw;
304
        int[] x_rgb_index=this.wk_updateExtpat_x_rgb_index;
305
        int[] y_rgb_index=this.wk_updateExtpat_y_rgb_index;
306
        int[] i_rgb_index=this.wk_updateExtpat_i_rgb_index;
307
        int[] rgb_buf=this.wk_updateExtpat_rgb_buf;
308
        double xw;
309
        for(i=0;i<i_xdiv2;i++){
310
            xw= 102.5 + 5.0 * ((double)i+0.5) /i_xdiv2;
311
            para20_xw[i]=para20*xw;
312
            para00_xw[i]=para00*xw;
313
            para10_xw[i]=para10*xw;
314
        }
315
 
316
        int index_num;
317
 
318
 
319
        for(j = 0; j < i_ydiv2; j++ ) {
320
            yw = 102.5 + 5.0 * ((double)j+0.5) /i_ydiv2;
321
            para21_x_yw=para21*yw+1.0;
322
            para11_x_yw=para11*yw+para12;
323
            para01_x_yw=para01*yw+para02;
324
            extpat_j=L_extpat[j/ydiv];
325
            index_num=0;
326
            //ステップ1.RGB取得用のマップを作成
327
            for(i = 0; i < i_xdiv2; i++ ) {
328
                d = para20_xw[i] + para21_x_yw;
329
                if( d == 0 ){
330
                    throw new NyARException();
331
                }
332
                xc = (int)((para00_xw[i] + para01_x_yw)/d);
333
                yc = (int)((para10_xw[i] + para11_x_yw)/d);
334
                //範囲外は無視
335
                if(xc<0 || xc >=img_x || yc<0 || yc >=img_y){
336
                    continue;
337
                }
338
//              ピクセル値の計算
339
//              image.getPixel(xc,yc,rgb_buf);
340
//                ext_pat2_j_i=ext_pat2_j[i/xdiv];
341
//                ext_pat2_j_i[0] += rgb_buf[0];//R
342
//                ext_pat2_j_i[1] += rgb_buf[1];//G
343
//                ext_pat2_j_i[2] += rgb_buf[2];//B
344
 
345
                x_rgb_index[index_num]=xc;
346
                y_rgb_index[index_num]=yc;
347
                i_rgb_index[index_num]=i/xdiv;
348
                index_num++;
349
            }
350
//          //ステップ2.ピクセル配列を取得
351
            image.getPixelSet(x_rgb_index,y_rgb_index,index_num,rgb_buf);
352
//          //ピクセル値の計算
353
            for(i=index_num-1;i>=0;i--){
354
                extpat_j_i=extpat_j[i_rgb_index[i]];
355
                extpat_j_i[0] += rgb_buf[i*3+0];//R
356
                extpat_j_i[1] += rgb_buf[i*3+1];//G
357
                extpat_j_i[2] += rgb_buf[i*3+2];//B
358
            }
359
        }
360
        /*<Optimize>*/
361
        int xdiv_x_ydiv=xdiv*ydiv;
362
        for(j =L_HEIGHT-1; j>=0; j--){
363
            extpat_j=L_extpat[j];
364
            for(i = L_WIDTH-1; i>=0; i--){                              // PRL 2006-06-08.
365
                extpat_j_i=extpat_j[i];
366
                extpat_j_i[0]/=(xdiv_x_ydiv);//ext_pat[j][i][0] = (byte)(ext_pat2[j][i][0] / (xdiv*ydiv));
367
                extpat_j_i[1]/=(xdiv_x_ydiv);//ext_pat[j][i][1] = (byte)(ext_pat2[j][i][1] / (xdiv*ydiv));
368
                extpat_j_i[2]/=(xdiv_x_ydiv);//ext_pat[j][i][2] = (byte)(ext_pat2[j][i][2] / (xdiv*ydiv));
369
            }
370
        }
371
        return;
372
    }
373
}