OSDN Git Service

522ca915c1d664b7c7be0d4d526569c1c3a724ff
[nyartoolkit-and/nyartoolkit-and.git] / lib / src / jp / nyatla / nyartoolkit / core / match / NyARMatchPattDeviationColorData.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.match;\r
32 \r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
36 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
37 import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
38 import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
39 \r
40 /**\r
41  * このクラスは、RGBカラーの差分画像を格納します。\r
42  * 差分画像は、p[i]=((255-画素[i])-画像全体の平均値)のピクセルで構成されている、平均値との差分値です。\r
43  * {@link NyARMatchPatt_BlackWhite}の入力値と使います。\r
44  * <p>使い方 - \r
45  * {@link #setRaster}関数で、差分画像を作成し、プロパティ取得関数でその情報を得ます。\r
46  * </p>\r
47  */\r
48 public class NyARMatchPattDeviationColorData\r
49 {\r
50         private int[] _data;\r
51         private double _pow;\r
52         private NyARIntSize _size;\r
53         //\r
54         private int _optimize_for_mod;\r
55         /**\r
56          * この関数は、画素データを格納した配列を返します。\r
57          * {@link NyARMatchPatt_Color_WITHOUT_PCA#evaluate}関数等から使います。\r
58          * R,G,Bの順番で、直列にデータを格納します。\r
59          */     \r
60         public int[] refData()\r
61         {\r
62                 return this._data;\r
63         }\r
64         /**\r
65          * この関数は、差分画像の強度値を返します。\r
66          * 強度値は、差分画像の画素を二乗した値の合計です。\r
67          * @return\r
68          * 0&lt;nの強度値。\r
69          */     \r
70         public double getPow()\r
71         {\r
72                 return this._pow;\r
73         }\r
74         /**\r
75          * コンストラクタです。\r
76          * 差分画像のサイズを指定して、インスタンスを生成します。\r
77          * @param i_width\r
78          * 差分画像のサイズ\r
79          * @param i_height\r
80          * 差分画像のサイズ\r
81          */                       \r
82         public NyARMatchPattDeviationColorData(int i_width,int i_height)\r
83         {\r
84                 this._size=new NyARIntSize(i_width,i_height);\r
85                 int number_of_pix=this._size.w*this._size.h;\r
86                 this._data=new int[number_of_pix*3];\r
87                 this._optimize_for_mod=number_of_pix-(number_of_pix%8); \r
88                 return;\r
89         }\r
90 \r
91         \r
92         /**\r
93          * この関数は、ラスタから差分画像を生成して、格納します。\r
94          * @param i_buffer\r
95          * 差分画像の元画像。サイズは、このインスタンスと同じである必要があります。\r
96          * {@link NyARBufferType#INT1D_X8R8G8B8_32}形式のバッファを持つラスタの場合、他の形式よりも\r
97          * 何倍か高速に動作します。\r
98          */\r
99         public void setRaster(INyARRgbRaster i_raster) throws NyARException\r
100         {\r
101                 assert(i_raster.getSize().isEqualSize(this._size));\r
102                 switch(i_raster.getBufferType())\r
103                 {\r
104                 case NyARBufferType.INT1D_X8R8G8B8_32:\r
105                         this._pow=setRaster_INT1D_X8R8G8B8_32((int[])i_raster.getBuffer(),this._size.w*this._size.h,this._optimize_for_mod,this._data);\r
106                         break;\r
107                 default:\r
108                         this._pow=setRaster_ANY(i_raster.getRgbPixelReader(),this._size,this._size.w*this._size.h,this._data);\r
109                         break;\r
110                 }\r
111                 return;\r
112         }\r
113         /**\r
114          * この関数は、元画像を回転してから、差分画像を生成して、格納します。\r
115          * 制限として、この関数はあまり高速ではありません。連続使用するときは、最適化を検討してください。\r
116          * @param i_reader\r
117          * 差分画像の元画像。サイズは、このインスタンスと同じである必要があります。\r
118          * @param i_direction\r
119          * 右上の位置です。0=1象限、1=2象限、、2=3象限、、3=4象限の位置に対応します。\r
120          * @throws NyARException\r
121          */\r
122         public final void setRaster(INyARRgbRaster i_raster,int i_direction) throws NyARException\r
123         {\r
124                 int width=this._size.w;\r
125                 int height=this._size.h;\r
126                 int i_number_of_pix=width*height;\r
127                 INyARRgbPixelReader reader=i_raster.getRgbPixelReader();\r
128                 int[] rgb=new int[3];\r
129                 int[] dout=this._data;\r
130                 int ave;//<PV/>\r
131                 //<平均値計算>\r
132                 ave = 0;\r
133                 for(int y=height-1;y>=0;y--){\r
134                         for(int x=width-1;x>=0;x--){\r
135                                 reader.getPixel(x,y,rgb);\r
136                                 ave += rgb[0]+rgb[1]+rgb[2];\r
137                         }\r
138                 }\r
139                 //<平均値計算>\r
140                 ave=i_number_of_pix*255*3-ave;\r
141                 ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算\r
142 \r
143                 int sum = 0,w_sum;\r
144                 int input_ptr=i_number_of_pix*3-1;\r
145                 switch(i_direction)\r
146                 {\r
147                 case 0:\r
148                         for(int y=height-1;y>=0;y--){\r
149                                 for(int x=width-1;x>=0;x--){\r
150                                         reader.getPixel(x,y,rgb);\r
151                                         w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
152                                         w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
153                                         w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
154                                 }\r
155                         }\r
156                         break;\r
157                 case 1:\r
158                         for(int x=0;x<width;x++){\r
159                                 for(int y=height-1;y>=0;y--){\r
160                                         reader.getPixel(x,y,rgb);\r
161                                         w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
162                                         w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
163                                         w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
164                                 }\r
165                         }\r
166                         break;\r
167                 case 2:\r
168                         for(int y=0;y<height;y++){\r
169                                 for(int x=0;x<width;x++){\r
170                                         reader.getPixel(x,y,rgb);\r
171                                         w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
172                                         w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
173                                         w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
174                                 }\r
175                         }\r
176                         break;\r
177                 case 3:\r
178                         for(int x=width-1;x>=0;x--){\r
179                                 for(int y=0;y<height;y++){\r
180                                         reader.getPixel(x,y,rgb);\r
181                                         w_sum = (ave - rgb[2]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
182                                         w_sum = (ave - rgb[1]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
183                                         w_sum = (ave - rgb[0]) ;dout[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
184                                 }\r
185                         }\r
186                         break;\r
187                         \r
188                 }\r
189                 //<差分値計算>\r
190                 //<差分値計算(FORの1/8展開)/>\r
191                 final double p=Math.sqrt((double) sum);\r
192                 this._pow=(p!=0.0?p:0.0000001);\r
193         }       \r
194         \r
195         \r
196         \r
197         \r
198         \r
199         /**\r
200          * INT1D_X8R8G8B8_32形式の入力ドライバ。\r
201          * @param i_buf\r
202          * @param i_number_of_pix\r
203          * @param i_for_mod\r
204          * @param o_out\r
205          * pow値\r
206          * @return\r
207          */\r
208         private static final double setRaster_INT1D_X8R8G8B8_32(int[] i_buf,int i_number_of_pix,int i_for_mod,int[] o_out)\r
209         {\r
210                 //i_buffer[XRGB]→差分[R,G,B]変換                  \r
211                 int i;\r
212                 int ave;//<PV/>\r
213                 int rgb;//<PV/>\r
214                 //<平均値計算(FORの1/8展開)>\r
215                 ave = 0;\r
216                 for(i=i_number_of_pix-1;i>=i_for_mod;i--){\r
217                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
218                 }\r
219                 for (;i>=0;) {\r
220                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
221                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
222                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
223                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
224                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
225                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
226                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
227                         rgb = i_buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
228                 }\r
229                 //<平均値計算(FORの1/8展開)/>\r
230                 ave=i_number_of_pix*255*3-ave;\r
231                 ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算\r
232 \r
233                 int sum = 0,w_sum;\r
234                 int input_ptr=i_number_of_pix*3-1;\r
235                 //<差分値計算(FORの1/8展開)>\r
236                 for (i = i_number_of_pix-1; i >= i_for_mod;i--) {\r
237                         rgb = i_buf[i];\r
238                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
239                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
240                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
241                 }\r
242                 for (; i >=0;) {\r
243                         rgb = i_buf[i];i--;\r
244                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
245                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
246                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
247                         rgb = i_buf[i];i--;\r
248                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
249                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
250                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
251                         rgb = i_buf[i];i--;\r
252                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
253                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
254                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
255                         rgb = i_buf[i];i--;\r
256                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
257                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
258                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
259                         rgb = i_buf[i];i--;\r
260                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
261                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
262                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
263                         rgb = i_buf[i];i--;\r
264                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
265                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
266                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
267                         rgb = i_buf[i];i--;\r
268                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
269                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
270                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
271                         rgb = i_buf[i];i--;\r
272                         w_sum = (ave - (rgb & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
273                         w_sum = (ave - ((rgb >> 8) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
274                         w_sum = (ave - ((rgb >> 16) & 0xff)) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
275                 }\r
276                 //<差分値計算(FORの1/8展開)/>\r
277                 final double p=Math.sqrt((double) sum);\r
278                 return p!=0.0?p:0.0000001;\r
279         }\r
280         /**\r
281          * ANY形式の入力ドライバ。\r
282          * @param i_buf\r
283          * @param i_number_of_pix\r
284          * @param i_for_mod\r
285          * @param o_out\r
286          * pow値\r
287          * @return\r
288          * @throws NyARException \r
289          */\r
290         private static final double setRaster_ANY(INyARRgbPixelReader i_reader,NyARIntSize i_size,int i_number_of_pix,int[] o_out) throws NyARException\r
291         {\r
292                 int width=i_size.w;\r
293                 int[] rgb=new int[3];\r
294                 int ave;//<PV/>\r
295                 //<平均値計算>\r
296                 ave = 0;\r
297                 for(int y=i_size.h-1;y>=0;y--){\r
298                         for(int x=width-1;x>=0;x--){\r
299                                 i_reader.getPixel(x,y,rgb);\r
300                                 ave += rgb[0]+rgb[1]+rgb[2];\r
301                         }\r
302                 }\r
303                 //<平均値計算>\r
304                 ave=i_number_of_pix*255*3-ave;\r
305                 ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算\r
306 \r
307                 int sum = 0,w_sum;\r
308                 int input_ptr=i_number_of_pix*3-1;\r
309                 //<差分値計算>\r
310                 for(int y=i_size.h-1;y>=0;y--){\r
311                         for(int x=width-1;x>=0;x--){\r
312                                 i_reader.getPixel(x,y,rgb);\r
313                                 w_sum = (ave - rgb[2]) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
314                                 w_sum = (ave - rgb[1]) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
315                                 w_sum = (ave - rgb[0]) ;o_out[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
316                         }\r
317                 }\r
318                 //<差分値計算(FORの1/8展開)/>\r
319                 final double p=Math.sqrt((double) sum);\r
320                 return p!=0.0?p:0.0000001;\r
321         }       \r
322 }\r