OSDN Git Service

[Backup]NyARToolkit for Java
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core / pickup / NyARColorPatt_O1.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.pickup;\r
32 \r
33 import jp.nyatla.nyartoolkit.NyARException;\r
34 import jp.nyatla.nyartoolkit.core.NyARMat;\r
35 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
36 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
37 import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
38 import jp.nyatla.nyartoolkit.core.types.*;\r
39 /**\r
40  * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
41  * 演算順序以外の最適化をしたもの\r
42  * \r
43  */\r
44 public class NyARColorPatt_O1 implements INyARColorPatt\r
45 {\r
46         private static final int AR_PATT_SAMPLE_NUM = 64;\r
47         \r
48         private int[] _patdata;\r
49         private NyARBufferReader _buf_reader;\r
50         private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
51 \r
52         private NyARIntSize _size;\r
53 \r
54         public NyARColorPatt_O1(int i_width, int i_height)\r
55         {\r
56                 //入力制限\r
57                 assert i_width<=64 && i_height<=64;\r
58                 \r
59                 this._size=new NyARIntSize(i_width,i_height);\r
60                 this._patdata = new int[i_height*i_width];\r
61                 this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
62                 this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
63                 return;\r
64         }\r
65 \r
66         public final int getWidth()\r
67         {\r
68                 return this._size.w;\r
69         }\r
70         public final int getHeight()\r
71         {\r
72                 return this._size.h;\r
73         }\r
74         public final NyARIntSize getSize()\r
75         {\r
76                 return  this._size;\r
77         }\r
78         public final INyARBufferReader getBufferReader()\r
79         {\r
80                 return this._buf_reader;\r
81         }\r
82         public final INyARRgbPixelReader getRgbPixelReader()\r
83         {\r
84                 return this._pixelreader;\r
85         }\r
86 \r
87         private final NyARMat __get_cpara_a = new NyARMat(8, 8);\r
88         private final NyARMat __get_cpara_b = new NyARMat(8, 1);\r
89         private final static double[][] __get__cpara_world = {{ 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
90         \r
91         final protected boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
92         {\r
93                 double[][] world = __get__cpara_world;\r
94                 NyARMat a = __get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
95                 double[][] a_array = a.getArray();\r
96                 NyARMat b = __get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
97                 double[][] b_array = b.getArray();\r
98                 double[] a_pt0, a_pt1;\r
99                 double[] world_pti;\r
100 \r
101                 for (int i = 0; i < 4; i++) {\r
102                         a_pt0 = a_array[i * 2];\r
103                         a_pt1 = a_array[i * 2 + 1];\r
104                         world_pti = world[i];\r
105 \r
106                         a_pt0[0] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
107                         a_pt0[1] = (double) world_pti[1];// a->m[i*16+1] = world[i][1];\r
108                         a_pt0[2] = 1.0;// a->m[i*16+2] = 1.0;\r
109                         a_pt0[3] = 0.0;// a->m[i*16+3] = 0.0;\r
110                         a_pt0[4] = 0.0;// a->m[i*16+4] = 0.0;\r
111                         a_pt0[5] = 0.0;// a->m[i*16+5] = 0.0;\r
112                         a_pt0[6] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
113                         a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// a->m[i*16+7]=-world[i][1]*vertex[i][0];\r
114                         a_pt1[0] = 0.0;// a->m[i*16+8] = 0.0;\r
115                         a_pt1[1] = 0.0;// a->m[i*16+9] = 0.0;\r
116                         a_pt1[2] = 0.0;// a->m[i*16+10] = 0.0;\r
117                         a_pt1[3] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
118                         a_pt1[4] = (double) world_pti[1];// a->m[i*16+12] = world[i][1];\r
119                         a_pt1[5] = 1.0;// a->m[i*16+13] = 1.0;\r
120                         a_pt1[6] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
121                         a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
122                         b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
123                         b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// b->m[i*2+1] =vertex[i][1];\r
124                 }\r
125                 if (!a.matrixSelfInv()) {\r
126                         return false;\r
127                 }\r
128 \r
129                 o_para.matrixMul(a, b);\r
130                 return true;\r
131         }       \r
132         private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
133         private final NyARMat __pickFromRaster_cpara_c = new NyARMat(8, 1);\r
134         \r
135         /**\r
136          * imageから、i_markerの位置にあるパターンを切り出して、保持します。 Optimize:STEP[769->]\r
137          * \r
138          * @param image\r
139          * @param i_marker\r
140          * @return 切り出しに失敗した\r
141          * @throws Exception\r
142          */\r
143         public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
144         {\r
145                 final NyARIntPoint2d[] local = i_square.imvertex;\r
146 \r
147                 // パターンの切り出しに失敗することもある。\r
148                 NyARMat cpara = this.__pickFromRaster_cpara_c;\r
149                 if (!get_cpara(i_square.imvertex, cpara)) {\r
150                         return false;\r
151                 }\r
152                 final double[][] para=cpara.getArray();\r
153                 final double para00=para[0*3+0][0];\r
154                 final double para01=para[0*3+1][0];\r
155                 final double para02=para[0*3+2][0];\r
156                 final double para10=para[1*3+0][0];\r
157                 final double para11=para[1*3+1][0];\r
158                 final double para12=para[1*3+2][0];\r
159                 final double para20=para[2*3+0][0];\r
160                 final double para21=para[2*3+1][0];\r
161                 final double para22=1.0;\r
162                 \r
163                 int lx1 = (int) ((local[0].x - local[1].x) * (local[0].x - local[1].x) + (local[0].y - local[1].y)* (local[0].y - local[1].y));\r
164                 int lx2 = (int) ((local[2].x - local[3].x) * (local[2].x - local[3].x) + (local[2].y - local[3].y)* (local[2].y - local[3].y));\r
165                 int ly1 = (int) ((local[1].x - local[2].x) * (local[1].x - local[2].x) + (local[1].y - local[2].y)* (local[1].y - local[2].y));\r
166                 int ly2 = (int) ((local[3].x - local[0].x) * (local[3].x - local[0].x) + (local[3].y - local[0].y)* (local[3].y - local[0].y));\r
167                 if (lx2 > lx1) {\r
168                         lx1 = lx2;\r
169                 }\r
170                 if (ly2 > ly1) {\r
171                         ly1 = ly2;\r
172                 }\r
173                 \r
174                 int sample_pixel_x = this._size.w;\r
175                 int sample_pixel_y = this._size.h;\r
176                 while (sample_pixel_x * sample_pixel_x < lx1 / 4) {\r
177                         sample_pixel_x *= 2;\r
178                 }\r
179                 while (sample_pixel_y * sample_pixel_y < ly1 / 4) {\r
180                         sample_pixel_y *= 2;\r
181                 }\r
182 \r
183                 if (sample_pixel_x > AR_PATT_SAMPLE_NUM) {\r
184                         sample_pixel_x = AR_PATT_SAMPLE_NUM;\r
185                 }\r
186                 if (sample_pixel_y > AR_PATT_SAMPLE_NUM) {\r
187                         sample_pixel_y = AR_PATT_SAMPLE_NUM;\r
188                 }\r
189 \r
190                 final int xdiv = sample_pixel_x / this._size.w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
191                 final int ydiv = sample_pixel_y / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
192 \r
193 \r
194                 int img_x = image.getWidth();\r
195                 int img_y = image.getHeight();\r
196 \r
197                 final double xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
198                 final double ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
199                 int r,g,b;\r
200                 int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
201 \r
202                 //ピクセルリーダーを取得\r
203                 INyARRgbPixelReader reader=image.getRgbPixelReader();\r
204                 final int xdiv_x_ydiv = xdiv * ydiv;\r
205 \r
206                 for(int iy=0;iy<this._size.h;iy++){\r
207                         for(int ix=0;ix<this._size.w;ix++){\r
208                                 r=g=b=0;\r
209                                 //1ピクセルを作成\r
210                                 for(int j=0;j<ydiv;j++){\r
211                                         final double yw = 102.5 + 5.0 * (iy*ydiv+j + 0.5) * ydiv2_reciprocal;                                           \r
212                                         for(int i=0;i<xdiv;i++){\r
213                                                 final double xw = 102.5 + 5.0 * (ix*xdiv+i + 0.5) * xdiv2_reciprocal;\r
214                                                 final double d = para20 * xw + para21 * yw+ para22;\r
215                                                 if (d == 0) {\r
216                                                         throw new NyARException();\r
217                                                 }\r
218                                                 final int xc = (int) ((para00 * xw + para01 * yw + para02) / d);\r
219                                                 final int yc = (int) ((para10 * xw + para11 * yw + para12) / d);\r
220         \r
221                                                 if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
222                                                         reader.getPixel(xc, yc, rgb_tmp);\r
223                                                         r += rgb_tmp[0];// R\r
224                                                         g += rgb_tmp[1];// G\r
225                                                         b += rgb_tmp[2];// B\r
226                                                         // System.out.println(xc+":"+yc+":"+rgb_tmp[0]+":"+rgb_tmp[1]+":"+rgb_tmp[2]);\r
227                                                 }\r
228                                         }\r
229                                 }\r
230                                 this._patdata[iy*this._size.w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
231                         }\r
232                 }\r
233                 return true;\r
234         }\r
235         \r
236 }