OSDN Git Service

13854809a56155d58266e1d248f86f9ee995560f
[nyartoolkit-and/nyartoolkit-and.git] / lib / src.rpf / jp / nyatla / nyartoolkit / rpf / tracker / nyartk / NyARVectorReader_INT1D_GRAY_8.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 modify\r
8  * it under the terms of the GNU General Public License as published by\r
9  * the Free Software Foundation, either version 3 of the License, or\r
10  * (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 General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU General Public License\r
18  * 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.rpf.tracker.nyartk;\r
26 \r
27 import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
28 import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
29 import jp.nyatla.nyartoolkit.core.squaredetect.NyARContourPickup;\r
30 import jp.nyatla.nyartoolkit.core.types.*;\r
31 \r
32 \r
33 /**\r
34  * グレイスケールラスタに対する、特殊な画素アクセス手段を提供します。\r
35  *\r
36  */\r
37 public class NyARVectorReader_INT1D_GRAY_8 extends NyARVectorReader_Base\r
38 {\r
39         /**\r
40          * \r
41          * @param i_ref_raster\r
42          * 基本画像\r
43          * @param i_ref_raster_distortion\r
44          * 歪み解除オブジェクト(nullの場合歪み解除を省略)\r
45          * @param i_ref_rob_raster\r
46          * エッジ探索用のROB画像\r
47          * @param \r
48          */\r
49         public NyARVectorReader_INT1D_GRAY_8(NyARGrayscaleRaster i_ref_raster,NyARCameraDistortionFactor i_ref_raster_distortion,NyARGrayscaleRaster i_ref_rob_raster)\r
50         {\r
51                 super();\r
52                 assert (i_ref_raster.getBufferType() == NyARBufferType.INT1D_GRAY_8);\r
53                 assert (i_ref_rob_raster.getBufferType() == NyARBufferType.INT1D_GRAY_8);\r
54                 this.initInstance(i_ref_raster, i_ref_raster_distortion, i_ref_rob_raster,new NyARContourPickup());\r
55         }\r
56 \r
57         /**\r
58          * 画素の4近傍の画素ベクトルを取得します。 取得可能な範囲は、Rasterの1ドット内側です。 0 ,-1, 0 0, 0, 0 0 , x,\r
59          * 0 + -1, y,+1 0 ,+1, 0 0, 0, 0\r
60          * \r
61          * @param i_raster\r
62          * @param x\r
63          * @param y\r
64          * @param o_v\r
65          */\r
66 /*      未使用につきコメントアウト\r
67         public void getPixelVector4(int x, int y, NyARIntPoint2d o_v)\r
68         {\r
69                 assert ((x > 0) && (y > 0) && (x) < this._ref_base_raster.getWidth() && (y) < this._ref_base_raster.getHeight());\r
70                 int[] buf = (int[])(this._ref_base_raster.getBuffer());\r
71                 int w = this._ref_base_raster.getWidth();\r
72                 int idx = w * y + x;\r
73                 o_v.x = (buf[idx + 1] - buf[idx - 1]) >> 1;\r
74                 o_v.y = (buf[idx + w] - buf[idx - w]) >> 1;\r
75                 //歪み補正どうすんの\r
76         }\r
77 */\r
78         /**\r
79          * 画素の8近傍画素ベクトルを取得します。 取得可能な範囲は、Rasterの1ドット内側です。\r
80          *  -1,-2,-1    -1, 0,+1\r
81          *   0, y, 0 +  -2, x,+2\r
82          *  +1,+2,+1     -1, 0,+1\r
83          * \r
84          * @param i_raster\r
85          * @param x\r
86          * @param y\r
87          * @param o_v\r
88          */\r
89 /*  未使用につきコメントアウト\r
90         public void getPixelVector8(int x, int y, NyARIntPoint2d o_v) {\r
91                 assert ((x > 0) && (y > 0) && (x) < this._ref_base_raster.getWidth() && (y) < this._ref_base_raster.getHeight());\r
92                 int[] buf = (int[])this._ref_base_raster.getBuffer();\r
93                 int sw = this._ref_base_raster.getWidth();\r
94                 int idx_0 = sw * y + x;\r
95                 int idx_p1 = idx_0 + sw;\r
96                 int idx_m1 = idx_0 - sw;\r
97                 int b = buf[idx_m1 - 1];\r
98                 int d = buf[idx_m1 + 1];\r
99                 int h = buf[idx_p1 - 1];\r
100                 int f = buf[idx_p1 + 1];\r
101                 o_v.x = ((buf[idx_0 + 1] - buf[idx_0 - 1]) >> 1)\r
102                                 + ((d - b + f - h) >> 2);\r
103                 o_v.y = ((buf[idx_p1] - buf[idx_m1]) >> 1) + ((f - d + h - b) >> 2);\r
104                 //歪み補正どうするの?\r
105         }\r
106 */\r
107         /**\r
108          * RECT範囲内の画素ベクトルの合計値と、ベクトルのエッジ中心を取得します。 320*240の場合、\r
109          * RECTの範囲は(x>=0 && x<319 x+w>=0 && x+w<319),(y>=0 && y<239 x+w>=0 && x+w<319)となります。\r
110          * @param ix\r
111          * ピクセル取得を行う位置を設定します。\r
112          * @param iy\r
113          * ピクセル取得を行う位置を設定します。\r
114          * @param iw\r
115          * ピクセル取得を行う範囲を設定します。\r
116          * @param ih\r
117          * ピクセル取得を行う範囲を設定します。\r
118          * @param o_posvec\r
119          * エッジ中心とベクトルを返します。\r
120          * @return\r
121          * ベクトルの強度を返します。強度値は、差分値の二乗の合計です。\r
122          */\r
123         public final int getAreaVector33(int ix, int iy, int iw, int ih,NyARVecLinear2d o_posvec)\r
124         {\r
125                 assert (ih >= 3 && iw >= 3);\r
126                 assert ((ix >= 0) && (iy >= 0) && (ix + iw) <= this._ref_base_raster.getWidth() && (iy + ih) <= this._ref_base_raster.getHeight());\r
127                 int[] buf =(int[])this._ref_base_raster.getBuffer();\r
128                 int stride =this._ref_base_raster.getWidth();\r
129                 // x=(Σ|Vx|*Xn)/n,y=(Σ|Vy|*Yn)/n\r
130                 // x=(ΣVx)^2/(ΣVx+ΣVy)^2,y=(ΣVy)^2/(ΣVx+ΣVy)^2\r
131                 int sum_x, sum_y, sum_wx, sum_wy, sum_vx, sum_vy;\r
132                 sum_x = sum_y = sum_wx = sum_wy = sum_vx = sum_vy = 0;\r
133                 int lw=iw - 3;\r
134                 int vx, vy;\r
135                 for (int i = ih - 3; i >= 0; i--) {\r
136                         int idx_0 = stride * (i + 1 + iy) + (iw - 3 + 1 + ix);\r
137                         for (int i2 = lw; i2 >= 0; i2--){\r
138                                 // 1ビット分のベクトルを計算\r
139                                 int idx_p1 = idx_0 + stride;\r
140                                 int idx_m1 = idx_0 - stride;\r
141                                 int b = buf[idx_m1 - 1];\r
142                                 int d = buf[idx_m1 + 1];\r
143                                 int h = buf[idx_p1 - 1];\r
144                                 int f = buf[idx_p1 + 1];\r
145                                 vx = ((buf[idx_0 + 1] - buf[idx_0 - 1]) >> 1)+ ((d - b + f - h) >> 2);\r
146                                 vy = ((buf[idx_p1] - buf[idx_m1]) >> 1)+ ((f - d + h - b) >> 2);\r
147                                 idx_0--;\r
148 \r
149                                 // 加重はvectorの絶対値\r
150                                 int wx = vx * vx;\r
151                                 int wy = vy * vy;\r
152                                 sum_wx += wx; //加重値\r
153                                 sum_wy += wy; //加重値\r
154                                 sum_vx += wx * vx; //加重*ベクトルの積\r
155                                 sum_vy += wy * vy; //加重*ベクトルの積\r
156                                 sum_x += wx * (i2 + 1);//位置\r
157                                 sum_y += wy * (i + 1); //\r
158                         }\r
159                 }\r
160                 //x,dx,y,dyの計算\r
161                 double xx,yy;\r
162                 if (sum_wx == 0) {\r
163                         xx = ix + (iw >> 1);\r
164                         o_posvec.dx = 0;\r
165                 } else {\r
166                         xx = ix+(double) sum_x / sum_wx;\r
167                         o_posvec.dx = (double) sum_vx / sum_wx;\r
168                 }\r
169                 if (sum_wy == 0) {\r
170                         yy = iy + (ih >> 1);\r
171                         o_posvec.dy = 0;\r
172                 } else {\r
173                         yy = iy+(double) sum_y / sum_wy;\r
174                         o_posvec.dy = (double) sum_vy / sum_wy;\r
175                 }\r
176                 //必要なら歪みを解除\r
177                 if(this._factor!=null){\r
178                         this._factor.observ2Ideal(xx, yy, o_posvec);\r
179                 }else{\r
180                         o_posvec.x=xx;\r
181                         o_posvec.y=yy;\r
182                 }\r
183                 //加重平均の分母を返却\r
184                 return sum_wx+sum_wy;\r
185         }\r
186         public final int getAreaVector22(int ix, int iy, int iw, int ih,NyARVecLinear2d o_posvec)\r
187         {\r
188                 assert (ih >= 3 && iw >= 3);\r
189                 assert ((ix >= 0) && (iy >= 0) && (ix + iw) <= this._ref_base_raster.getWidth() && (iy + ih) <= this._ref_base_raster.getHeight());\r
190                 int[] buf =(int[])this._ref_base_raster.getBuffer();\r
191                 int stride =this._ref_base_raster.getWidth();\r
192                 int sum_x, sum_y, sum_wx, sum_wy, sum_vx, sum_vy;\r
193                 sum_x = sum_y = sum_wx = sum_wy = sum_vx = sum_vy = 0;\r
194                 int vx, vy;\r
195                 int ll=iw-1;\r
196                 for (int i = 0; i<ih-1; i++) {\r
197                         int idx_0 = stride * (i+iy) + ix+1;\r
198                         int a=buf[idx_0-1];\r
199                         int b=buf[idx_0];\r
200                         int c=buf[idx_0+stride-1];\r
201                         int d=buf[idx_0+stride];\r
202                         for (int i2 = 0; i2<ll; i2++){\r
203                                 // 1ビット分のベクトルを計算\r
204                                 vx=(b-a+d-c)>>2;\r
205                                 vy=(c-a+d-b)>>2;\r
206                                 idx_0++;\r
207                                 a=b;\r
208                                 c=d;\r
209                                 b=buf[idx_0];\r
210                                 d=buf[idx_0+stride];\r
211 \r
212                                 // 加重はvectorの絶対値\r
213                                 int wx = vx * vx;\r
214                                 sum_wx += wx; //加重値\r
215                                 sum_vx += wx * vx; //加重*ベクトルの積\r
216                                 sum_x += wx * i2;//位置\r
217 \r
218                                 int wy = vy * vy;\r
219                                 sum_wy += wy; //加重値\r
220                                 sum_vy += wy * vy; //加重*ベクトルの積\r
221                                 sum_y += wy * i; //\r
222                         }\r
223                 }\r
224                 //x,dx,y,dyの計算\r
225                 double xx,yy;\r
226                 if (sum_wx == 0) {\r
227                         xx = ix + (iw >> 1);\r
228                         o_posvec.dx = 0;\r
229                 } else {\r
230                         xx = ix+(double) sum_x / sum_wx;\r
231                         o_posvec.dx = (double) sum_vx / sum_wx;\r
232                 }\r
233                 if (sum_wy == 0) {\r
234                         yy = iy + (ih >> 1);\r
235                         o_posvec.dy = 0;\r
236                 } else {\r
237                         yy = iy+(double) sum_y / sum_wy;\r
238                         o_posvec.dy = (double) sum_vy / sum_wy;\r
239                 }\r
240                 //必要なら歪みを解除\r
241                 if(this._factor!=null){\r
242                         this._factor.observ2Ideal(xx, yy, o_posvec);\r
243                 }else{\r
244                         o_posvec.x=xx;\r
245                         o_posvec.y=yy;\r
246                 }\r
247                 //加重平均の分母を返却\r
248                 return sum_wx+sum_wy;\r
249         }\r
250 }