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 edition ARToolKit class library.
\r
11 * Copyright (C)2008-2009 Ryo Iizuka
\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
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 program. If not, see <http://www.gnu.org/licenses/>.
\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
31 package jp.nyatla.nyartoolkit.core.match;
\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
41 * このクラスは、RGBカラーの差分画像を格納します。
\r
42 * 差分画像は、p[i]=((255-画素[i])-画像全体の平均値)のピクセルで構成されている、平均値との差分値です。
\r
43 * {@link NyARMatchPatt_BlackWhite}の入力値と使います。
\r
45 * {@link #setRaster}関数で、差分画像を作成し、プロパティ取得関数でその情報を得ます。
\r
48 public class NyARMatchPattDeviationColorData
\r
50 private int[] _data;
\r
51 private double _pow;
\r
52 private NyARIntSize _size;
\r
54 private int _optimize_for_mod;
\r
56 * この関数は、画素データを格納した配列を返します。
\r
57 * {@link NyARMatchPatt_Color_WITHOUT_PCA#evaluate}関数等から使います。
\r
58 * R,G,Bの順番で、直列にデータを格納します。
\r
60 public int[] refData()
\r
65 * この関数は、差分画像の強度値を返します。
\r
66 * 強度値は、差分画像の画素を二乗した値の合計です。
\r
70 public double getPow()
\r
76 * 差分画像のサイズを指定して、インスタンスを生成します。
\r
82 public NyARMatchPattDeviationColorData(int i_width,int i_height)
\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
93 * この関数は、ラスタから差分画像を生成して、格納します。
\r
95 * 差分画像の元画像。サイズは、このインスタンスと同じである必要があります。
\r
96 * {@link NyARBufferType#INT1D_X8R8G8B8_32}形式のバッファを持つラスタの場合、他の形式よりも
\r
99 public void setRaster(INyARRgbRaster i_raster) throws NyARException
\r
101 assert(i_raster.getSize().isEqualSize(this._size));
\r
102 switch(i_raster.getBufferType())
\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
108 this._pow=setRaster_ANY(i_raster.getRgbPixelReader(),this._size,this._size.w*this._size.h,this._data);
\r
114 * この関数は、元画像を回転してから、差分画像を生成して、格納します。
\r
115 * 制限として、この関数はあまり高速ではありません。連続使用するときは、最適化を検討してください。
\r
117 * 差分画像の元画像。サイズは、このインスタンスと同じである必要があります。
\r
118 * @param i_direction
\r
119 * 右上の位置です。0=1象限、1=2象限、、2=3象限、、3=4象限の位置に対応します。
\r
120 * @throws NyARException
\r
122 public final void setRaster(INyARRgbRaster i_raster,int i_direction) throws NyARException
\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
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
140 ave=i_number_of_pix*255*3-ave;
\r
141 ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算
\r
144 int input_ptr=i_number_of_pix*3-1;
\r
145 switch(i_direction)
\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
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
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
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
190 //<差分値計算(FORの1/8展開)/>
\r
191 final double p=Math.sqrt((double) sum);
\r
192 this._pow=(p!=0.0?p:0.0000001);
\r
200 * INT1D_X8R8G8B8_32形式の入力ドライバ。
\r
202 * @param i_number_of_pix
\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
210 //i_buffer[XRGB]→差分[R,G,B]変換
\r
214 //<平均値計算(FORの1/8展開)>
\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
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
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
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
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
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
276 //<差分値計算(FORの1/8展開)/>
\r
277 final double p=Math.sqrt((double) sum);
\r
278 return p!=0.0?p:0.0000001;
\r
283 * @param i_number_of_pix
\r
288 * @throws NyARException
\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
292 int width=i_size.w;
\r
293 int[] rgb=new int[3];
\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
304 ave=i_number_of_pix*255*3-ave;
\r
305 ave =255-(ave/ (i_number_of_pix * 3));//(255-R)-ave を分解するための事前計算
\r
308 int input_ptr=i_number_of_pix*3-1;
\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
318 //<差分値計算(FORの1/8展開)/>
\r
319 final double p=Math.sqrt((double) sum);
\r
320 return p!=0.0?p:0.0000001;
\r