OSDN Git Service

ライセンス文の更新
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src / jp / nyatla / nyartoolkit / core / pickup / NyARColorPatt_Perspective.java
1 /* \r
2  * PROJECT: NyARToolkit(Extension)\r
3  * --------------------------------------------------------------------------------\r
4  * The NyARToolkit is Java edition ARToolKit class library.\r
5  * Copyright (C)2008-2009 Ryo Iizuka\r
6  *\r
7  * This program is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU Lesser General Public License\r
9  * as published by the Free Software Foundation; either version 3\r
10  * of the License, or (at your option) any later version.\r
11  * \r
12  * This program is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
15  * GNU Lesser General Public License for more details\r
16  * \r
17  * You should have received a copy of the GNU Lesser General Public\r
18  * License along with this program. If not, see <http://www.gnu.org/licenses/>.\r
19  * \r
20  * For further information please contact.\r
21  *      http://nyatla.jp/nyatoolkit/\r
22  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
23  * \r
24  */\r
25 package jp.nyatla.nyartoolkit.core.pickup;\r
26 \r
27 import jp.nyatla.nyartoolkit.NyARException;\r
28 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
29 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
30 import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
31 import jp.nyatla.nyartoolkit.core.types.*;\r
32 import jp.nyatla.nyartoolkit.core.utils.NyARPerspectiveParamGenerator_O1;\r
33 \r
34 \r
35 /**\r
36  * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
37  * 任意解像度の矩形パターンを作成します。\r
38  *\r
39  */\r
40 public class NyARColorPatt_Perspective implements INyARColorPatt\r
41 {\r
42         protected int[] _patdata;\r
43         protected NyARIntPoint2d _pickup_lt=new NyARIntPoint2d();       \r
44         protected int _resolution;\r
45         protected NyARBufferReader _buf_reader;\r
46         protected NyARIntSize _size;\r
47         protected NyARPerspectiveParamGenerator_O1 _perspective_gen;\r
48         private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
49         private static final int LOCAL_LT=1;\r
50         \r
51         private void initializeInstance(int i_width, int i_height,int i_point_per_pix)\r
52         {\r
53                 assert i_width>2 && i_height>2;\r
54                 this._resolution=i_point_per_pix;       \r
55                 this._size=new NyARIntSize(i_width,i_height);\r
56                 this._patdata = new int[i_height*i_width];\r
57                 this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
58                 this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
59                 return;         \r
60         }\r
61         /**\r
62          * 例えば、64\r
63          * @param i_width\r
64          * 取得画像の解像度幅\r
65          * @param i_height\r
66          * 取得画像の解像度高さ\r
67          * @param i_point_per_pix\r
68          * 1ピクセルあたりの縦横サンプリング数。2なら2x2=4ポイントをサンプリングする。\r
69          */\r
70         public NyARColorPatt_Perspective(int i_width, int i_height,int i_point_per_pix)\r
71         {\r
72                 initializeInstance(i_width,i_height,i_point_per_pix);\r
73                 setEdgeSize(0,0,i_point_per_pix);\r
74                 return;\r
75         }\r
76         /**\r
77          * 例えば、64\r
78          * @param i_width\r
79          * 取得画像の解像度幅\r
80          * @param i_height\r
81          * 取得画像の解像度高さ\r
82          * @param i_edge_percentage\r
83          * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
84          */\r
85         public NyARColorPatt_Perspective(int i_width, int i_height,int i_resolution,int i_edge_percentage)\r
86         {\r
87                 //入力制限\r
88                 initializeInstance(i_width,i_height,i_resolution);\r
89                 setEdgeSizeByPercent(i_edge_percentage,i_edge_percentage,i_resolution);\r
90                 return;\r
91         }       \r
92         /**\r
93          * 矩形領域のエッジサイズを指定します。\r
94          * エッジの計算方法は以下の通りです。\r
95          * 1.マーカ全体を(i_x_edge*2+width)x(i_y_edge*2+height)の解像度でパラメタを計算します。\r
96          * 2.ピクセルの取得開始位置を(i_x_edge/2,i_y_edge/2)へ移動します。\r
97          * 3.開始位置から、width x height個のピクセルを取得します。\r
98          * \r
99          * ARToolKit標準マーカの場合は、width/2,height/2を指定してください。\r
100          * @param i_x_edge\r
101          * @param i_y_edge\r
102          */\r
103         public void setEdgeSize(int i_x_edge,int i_y_edge,int i_resolution)\r
104         {\r
105                 assert(i_x_edge>=0);\r
106                 assert(i_y_edge>=0);\r
107                 //Perspectiveパラメタ計算器を作成\r
108                 this._perspective_gen=new NyARPerspectiveParamGenerator_O1(\r
109                         LOCAL_LT,LOCAL_LT,\r
110                         (i_x_edge*2+this._size.w)*i_resolution,\r
111                         (i_y_edge*2+this._size.h)*i_resolution);\r
112                 //ピックアップ開始位置を計算\r
113                 this._pickup_lt.x=i_x_edge*i_resolution+LOCAL_LT;\r
114                 this._pickup_lt.y=i_y_edge*i_resolution+LOCAL_LT;\r
115                 return;\r
116         }\r
117         public void setEdgeSizeByPercent(int i_x_percent,int i_y_percent,int i_resolution)\r
118         {\r
119                 assert(i_x_percent>=0);\r
120                 assert(i_y_percent>=0);\r
121                 setEdgeSize(this._size.w*i_x_percent/50,this._size.h*i_y_percent/50,i_resolution);\r
122                 return;\r
123         }\r
124 \r
125         \r
126         public final int getWidth()\r
127         {\r
128                 return this._size.w;\r
129         }\r
130         public final int getHeight()\r
131         {\r
132                 return this._size.h;\r
133         }\r
134         public final NyARIntSize getSize()\r
135         {\r
136                 return  this._size;\r
137         }\r
138         public final INyARBufferReader getBufferReader()\r
139         {\r
140                 return this._buf_reader;\r
141         }\r
142         public final INyARRgbPixelReader getRgbPixelReader()\r
143         {\r
144                 return this._pixelreader;\r
145         }\r
146         private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
147         protected final double[] __pickFromRaster_cpara=new double[8];\r
148         /**\r
149          * \r
150          * @param image\r
151          * @param i_marker\r
152          * @return 切り出しに失敗した\r
153          * @throws Exception\r
154          */\r
155         public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
156         {\r
157                 //遠近法のパラメータを計算\r
158                 final double[] cpara = this.__pickFromRaster_cpara;\r
159                 if (!this._perspective_gen.getParam(i_square.imvertex, cpara)) {\r
160                         return false;\r
161                 }\r
162                 \r
163                 final int resolution=this._resolution;\r
164                 final int img_x = image.getWidth();\r
165                 final int img_y = image.getHeight();\r
166                 final int res_pix=resolution*resolution;\r
167 \r
168                 final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
169 \r
170                 //ピクセルリーダーを取得\r
171                 INyARRgbPixelReader reader=image.getRgbPixelReader();\r
172                 int p=0;\r
173                 for(int iy=0;iy<this._size.h*resolution;iy+=resolution){\r
174                         //解像度分の点を取る。\r
175                         for(int ix=0;ix<this._size.w*resolution;ix+=resolution){\r
176                                 int r,g,b;\r
177                                 r=g=b=0;\r
178                                 for(int i2y=iy;i2y<iy+resolution;i2y++){\r
179                                         int cy=this._pickup_lt.y+i2y;\r
180                                         for(int i2x=ix;i2x<ix+resolution;i2x++){\r
181                                                 //1ピクセルを作成\r
182                                                 int cx=this._pickup_lt.x+i2x;\r
183                                                 final double d=cpara[6]*cx+cpara[7]*cy+1.0;\r
184                                                 int x=(int)((cpara[0]*cx+cpara[1]*cy+cpara[2])/d);\r
185                                                 int y=(int)((cpara[3]*cx+cpara[4]*cy+cpara[5])/d);\r
186                                                 if(x<0){x=0;}\r
187                                                 if(x>=img_x){x=img_x-1;}\r
188                                                 if(y<0){y=0;}\r
189                                                 if(y>=img_y){y=img_y-1;}\r
190                                                 \r
191                                                 reader.getPixel(x, y, rgb_tmp);\r
192                                                 r+=rgb_tmp[0];\r
193                                                 g+=rgb_tmp[1];\r
194                                                 b+=rgb_tmp[2];\r
195                                         }\r
196                                 }\r
197                                 r/=res_pix;\r
198                                 g/=res_pix;\r
199                                 b/=res_pix;\r
200                                 this._patdata[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
201                                 p++;\r
202                         }\r
203                 }\r
204                         //ピクセル問い合わせ\r
205                         //ピクセルセット\r
206                 return true;\r
207         }\r
208 \r
209 }