OSDN Git Service

[Backup]NyARToolkit for Java
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src / jp / nyatla / nyartoolkit / core2 / rasteranalyzer / threshold / NyARRasterThresholdAnalyzer_SlidePTile.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 version ARToolkit class library.\r
11  * Copyright (C)2008 R.Iizuka\r
12  *\r
13  * This program is free software; you can redistribute it and/or\r
14  * modify it under the terms of the GNU General Public License\r
15  * as published by the Free Software Foundation; either version 2\r
16  * of the License, or (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 framework; if not, write to the Free Software\r
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
26  * \r
27  * For further information please contact.\r
28  *      http://nyatla.jp/nyatoolkit/\r
29  *      <airmail(at)ebony.plala.or.jp>\r
30  * \r
31  */\r
32 package jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold;\r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.raster.*;\r
36 import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
37 import jp.nyatla.nyartoolkit.core.types.*;\r
38 \r
39 \r
40 /**\r
41  * 明点と暗点をPタイル法で検出して、その中央値を閾値とする。\r
42  * \r
43  * \r
44  */\r
45 public class NyARRasterThresholdAnalyzer_SlidePTile implements INyARRasterThresholdAnalyzer\r
46 {\r
47         interface ICreateHistgramImpl{\r
48                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram);\r
49         }\r
50         /**\r
51          * Glayscale(MAX256)のヒストグラム計算クラス\r
52          */\r
53         final class CreateHistgramImpl_INT1D_GRAY_8 implements ICreateHistgramImpl\r
54         {\r
55                 public int _v_interval;\r
56                 public CreateHistgramImpl_INT1D_GRAY_8(int i_v_interval)\r
57                 {\r
58                         this._v_interval=i_v_interval;\r
59                         return;\r
60                 }\r
61                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram)\r
62                 {\r
63                         assert (i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
64 \r
65                         int sum=0;\r
66                         final int[] input=(int[]) i_reader.getBuffer();\r
67                         for (int y = i_size.h-1; y >=0 ; y-=this._v_interval){\r
68                                 sum+=i_size.w;\r
69                                 int pt=y*i_size.w;\r
70                                 for (int x = i_size.w-1; x >=0; x--) {\r
71                                         o_histgram[input[pt]]++;\r
72                                         pt++;\r
73                                 }\r
74                         }\r
75                         return sum;\r
76                 }\r
77         }\r
78         /**\r
79          * RGB24bitのヒストグラム計算クラス\r
80          *\r
81          */\r
82         final class CreateHistgramImpl_BYTE1D_RGB_24 implements ICreateHistgramImpl\r
83         {\r
84                 private int _v_interval;\r
85                 public CreateHistgramImpl_BYTE1D_RGB_24(int i_v_interval)\r
86                 {\r
87                         this._v_interval=i_v_interval;\r
88                         return;\r
89                 }\r
90                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram)\r
91                 {\r
92                         assert (\r
93                                 i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24)||\r
94                                 i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24));\r
95                         \r
96                         final byte[] input=(byte[]) i_reader.getBuffer();\r
97                         final int pix_count=i_size.w;\r
98                         final int pix_mod_part=pix_count-(pix_count%8);\r
99                         int sum=0;\r
100                         for (int y = i_size.h-1; y >=0 ; y-=this._v_interval) {\r
101                                 sum+=i_size.w;\r
102                                 int pt=y*i_size.w*3;\r
103                                 int x,v;\r
104                                 for (x = pix_count-1; x >=pix_mod_part; x--) {\r
105                                         v=((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3;\r
106                                         o_histgram[v]++;\r
107                                         pt+=3;\r
108                                 }\r
109                                 //タイリング\r
110                                 for (;x>=0;x-=8){\r
111                                         v=((input[pt+ 0]& 0xff)+(input[pt+ 1]& 0xff)+(input[pt+ 2]& 0xff))/3;\r
112                                         o_histgram[v]++;\r
113                                         v=((input[pt+ 3]& 0xff)+(input[pt+ 4]& 0xff)+(input[pt+ 5]& 0xff))/3;\r
114                                         o_histgram[v]++;\r
115                                         v=((input[pt+ 6]& 0xff)+(input[pt+ 7]& 0xff)+(input[pt+ 8]& 0xff))/3;\r
116                                         o_histgram[v]++;\r
117                                         v=((input[pt+ 9]& 0xff)+(input[pt+10]& 0xff)+(input[pt+11]& 0xff))/3;\r
118                                         o_histgram[v]++;\r
119                                         v=((input[pt+12]& 0xff)+(input[pt+13]& 0xff)+(input[pt+14]& 0xff))/3;\r
120                                         o_histgram[v]++;\r
121                                         v=((input[pt+15]& 0xff)+(input[pt+16]& 0xff)+(input[pt+17]& 0xff))/3;\r
122                                         o_histgram[v]++;\r
123                                         v=((input[pt+18]& 0xff)+(input[pt+19]& 0xff)+(input[pt+20]& 0xff))/3;\r
124                                         o_histgram[v]++;\r
125                                         v=((input[pt+21]& 0xff)+(input[pt+22]& 0xff)+(input[pt+23]& 0xff))/3;\r
126                                         o_histgram[v]++;\r
127                                         pt+=3*8;\r
128                                 }\r
129                         }\r
130                         return sum;             \r
131                 }\r
132         }\r
133         /**\r
134          * BYTE1D_B8G8R8X8_32のヒストグラム計算クラス\r
135          *\r
136          */     \r
137     final class CreateHistgramImpl_BYTE1D_B8G8R8X8_32 implements ICreateHistgramImpl\r
138     {\r
139         private int _v_interval;\r
140         public CreateHistgramImpl_BYTE1D_B8G8R8X8_32(int i_v_interval)\r
141         {\r
142             this._v_interval = i_v_interval;\r
143             return;\r
144         }\r
145         public int createHistgramImpl(INyARBufferReader i_reader, NyARIntSize i_size, int[] o_histgram)\r
146         {\r
147             assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32));\r
148             byte[] input = (byte[])i_reader.getBuffer();\r
149             int pix_count = i_size.w;\r
150             int pix_mod_part = pix_count - (pix_count % 8);\r
151             int sum = 0;\r
152             for (int y = i_size.h - 1; y >= 0; y -= this._v_interval)\r
153             {\r
154                 sum += i_size.w;\r
155                 int pt = y * i_size.w * 4;\r
156                 int x, v;\r
157                 for (x = pix_count - 1; x >= pix_mod_part; x--)\r
158                 {\r
159                     v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3;\r
160                     o_histgram[v]++;\r
161                     pt += 4;\r
162                 }\r
163                 //タイリング\r
164                 for (; x >= 0; x -= 8)\r
165                 {\r
166                     v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3;\r
167                     o_histgram[v]++;\r
168                     v = ((input[pt + 4] & 0xff) + (input[pt + 5] & 0xff) + (input[pt + 6] & 0xff)) / 3;\r
169                     o_histgram[v]++;\r
170                     v = ((input[pt + 8] & 0xff) + (input[pt + 9] & 0xff) + (input[pt + 10] & 0xff)) / 3;\r
171                     o_histgram[v]++;\r
172                     v = ((input[pt + 12] & 0xff) + (input[pt + 13] & 0xff) + (input[pt + 14] & 0xff)) / 3;\r
173                     o_histgram[v]++;\r
174                     v = ((input[pt + 16] & 0xff) + (input[pt + 17] & 0xff) + (input[pt + 18] & 0xff)) / 3;\r
175                     o_histgram[v]++;\r
176                     v = ((input[pt + 20] & 0xff) + (input[pt + 21] & 0xff) + (input[pt + 22] & 0xff)) / 3;\r
177                     o_histgram[v]++;\r
178                     v = ((input[pt + 24] & 0xff) + (input[pt + 25] & 0xff) + (input[pt + 26] & 0xff)) / 3;\r
179                     o_histgram[v]++;\r
180                     v = ((input[pt + 28] & 0xff) + (input[pt + 29] & 0xff) + (input[pt + 30] & 0xff)) / 3;\r
181                     o_histgram[v]++;\r
182                     pt += 4 * 8;\r
183                 }\r
184             }\r
185             return sum;\r
186         }\r
187     }   \r
188         /**\r
189          * BYTE1D_B8G8R8X8_32のヒストグラム計算クラス\r
190          *\r
191          */     \r
192     final class CreateHistgramImpl_BYTE1D_X8R8G8B8_32 implements ICreateHistgramImpl\r
193     {\r
194         private int _v_interval;\r
195         public CreateHistgramImpl_BYTE1D_X8R8G8B8_32(int i_v_interval)\r
196         {\r
197             this._v_interval = i_v_interval;\r
198             return;\r
199         }\r
200         public int createHistgramImpl(INyARBufferReader i_reader, NyARIntSize i_size, int[] o_histgram)\r
201         {\r
202             assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32));\r
203             byte[] input = (byte[])i_reader.getBuffer();\r
204             int pix_count = i_size.w;\r
205             int pix_mod_part = pix_count - (pix_count % 8);\r
206             int sum = 0;\r
207             for (int y = i_size.h - 1; y >= 0; y -= this._v_interval)\r
208             {\r
209                 sum += i_size.w;\r
210                 int pt = y * i_size.w * 4;\r
211                 int x, v;\r
212                 for (x = pix_count - 1; x >= pix_mod_part; x--)\r
213                 {\r
214                     v = ((input[pt + 1] & 0xff) + (input[pt + 2] & 0xff) + (input[pt + 3] & 0xff)) / 3;\r
215                     o_histgram[v]++;\r
216                     pt += 4;\r
217                 }\r
218                 //タイリング\r
219                 for (; x >= 0; x -= 8)\r
220                 {\r
221                     v = ((input[pt + 1] & 0xff) + (input[pt + 2] & 0xff) + (input[pt + 3] & 0xff)) / 3;\r
222                     o_histgram[v]++;\r
223                     v = ((input[pt + 5] & 0xff) + (input[pt + 6] & 0xff) + (input[pt + 7] & 0xff)) / 3;\r
224                     o_histgram[v]++;\r
225                     v = ((input[pt + 9] & 0xff) + (input[pt + 10] & 0xff) + (input[pt + 11] & 0xff)) / 3;\r
226                     o_histgram[v]++;\r
227                     v = ((input[pt + 13] & 0xff) + (input[pt + 14] & 0xff) + (input[pt + 15] & 0xff)) / 3;\r
228                     o_histgram[v]++;\r
229                     v = ((input[pt + 17] & 0xff) + (input[pt + 18] & 0xff) + (input[pt + 19] & 0xff)) / 3;\r
230                     o_histgram[v]++;\r
231                     v = ((input[pt + 21] & 0xff) + (input[pt + 22] & 0xff) + (input[pt + 23] & 0xff)) / 3;\r
232                     o_histgram[v]++;\r
233                     v = ((input[pt + 25] & 0xff) + (input[pt + 26] & 0xff) + (input[pt + 27] & 0xff)) / 3;\r
234                     o_histgram[v]++;\r
235                     v = ((input[pt + 29] & 0xff) + (input[pt + 30] & 0xff) + (input[pt + 31] & 0xff)) / 3;\r
236                     o_histgram[v]++;\r
237                     pt += 4 * 8;\r
238                 }\r
239             }\r
240             return sum;\r
241         }\r
242     }   \r
243 \r
244     private int _persentage;\r
245         private int _threshold;\r
246         private ICreateHistgramImpl _histgram;\r
247         \r
248         /**\r
249          * @param i_persentage\r
250          * 0<=50であること。白/黒マーカーの場合は10~20を推奨 正の場合、黒点を基準にします。 負の場合、白点を基準にします。\r
251          * (CMOSカメラの場合、基準点は白点の方が良い)\r
252          */\r
253         public NyARRasterThresholdAnalyzer_SlidePTile(int i_persentage,int i_raster_format,int i_vertical_interval) throws NyARException\r
254         {\r
255                 assert (0 <= i_persentage && i_persentage <= 50);\r
256                 this._persentage = i_persentage;\r
257         switch (i_raster_format)\r
258         {\r
259             case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
260             case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
261                 this._histgram = new CreateHistgramImpl_BYTE1D_RGB_24(i_vertical_interval);\r
262                 break;\r
263             case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
264                 this._histgram = new CreateHistgramImpl_INT1D_GRAY_8(i_vertical_interval);\r
265                 break;\r
266             case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
267                 this._histgram = new CreateHistgramImpl_BYTE1D_B8G8R8X8_32(i_vertical_interval);\r
268                 break;\r
269                 case INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32:\r
270                         this._histgram = new CreateHistgramImpl_BYTE1D_X8R8G8B8_32(i_vertical_interval);\r
271                         break;\r
272             default:\r
273                 throw new NyARException();\r
274         }\r
275         }\r
276         public void setVerticalInterval(int i_step)\r
277         {\r
278                 return;//未実装一号\r
279         }\r
280 \r
281         private int[] _histgram_buf=new int[256];\r
282         public void analyzeRaster(INyARRaster i_input) throws NyARException\r
283         {\r
284                 final int[] histgram = this._histgram_buf;\r
285                 final NyARIntSize size=i_input.getSize();\r
286                 \r
287                 //最大画像サイズの制限\r
288                 assert size.w*size.h<0x40000000;\r
289 \r
290                 //ヒストグラム初期化\r
291                 for (int i = 0; i < 256; i++) {\r
292                         histgram[i] = 0;\r
293                 }\r
294                 int sum_of_pixel=this._histgram.createHistgramImpl(i_input.getBufferReader(), size, histgram);\r
295 \r
296                 // 閾値ピクセル数確定\r
297                 final int th_pixcels = sum_of_pixel * this._persentage / 100;\r
298                 int th_wk;\r
299                 int th_w, th_b;\r
300 \r
301                 // 黒点基準\r
302                 th_wk = th_pixcels;\r
303                 for (th_b = 0; th_b < 254; th_b++) {\r
304                         th_wk -= histgram[th_b];\r
305                         if (th_wk <= 0) {\r
306                                 break;\r
307                         }\r
308                 }\r
309                 // 白点基準\r
310                 th_wk = th_pixcels;\r
311                 for (th_w = 255; th_w > 1; th_w--) {\r
312                         th_wk -= histgram[th_w];\r
313                         if (th_wk <= 0) {\r
314                                 break;\r
315                         }\r
316                 }\r
317                 // 閾値の保存\r
318                 this._threshold = (th_w + th_b) / 2;\r
319                 return;\r
320         }\r
321         public int getThreshold()\r
322         {\r
323                 return this._threshold;\r
324         }\r
325 \r
326         public int getThreshold(int i_x, int i_y)\r
327         {\r
328                 return this._threshold;\r
329         }\r
330 }\r