OSDN Git Service

962ce04fb617b57a6eb40569ab240b790c4ba0ca
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / nyatla / nyartoolkit / core2 / rasteranalyzer / threshold / NyARRasterThresholdAnalyzer_SlidePTile.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.core2.rasteranalyzer.threshold;\r
26 \r
27 import jp.nyatla.nyartoolkit.NyARException;\r
28 import jp.nyatla.nyartoolkit.core.raster.*;\r
29 import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
30 import jp.nyatla.nyartoolkit.core.types.*;\r
31 \r
32 \r
33 /**\r
34  * 明点と暗点をPタイル法で検出して、その中央値を閾値とする。\r
35  * \r
36  * \r
37  */\r
38 public class NyARRasterThresholdAnalyzer_SlidePTile implements INyARRasterThresholdAnalyzer\r
39 {\r
40         interface ICreateHistgramImpl{\r
41                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram);\r
42         }\r
43         /**\r
44          * Glayscale(MAX256)のヒストグラム計算クラス\r
45          */\r
46         final class CreateHistgramImpl_INT1D_GRAY_8 implements ICreateHistgramImpl\r
47         {\r
48                 public int _v_interval;\r
49                 public CreateHistgramImpl_INT1D_GRAY_8(int i_v_interval)\r
50                 {\r
51                         this._v_interval=i_v_interval;\r
52                         return;\r
53                 }\r
54                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram)\r
55                 {\r
56                         assert (i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
57 \r
58                         int sum=0;\r
59                         final int[] input=(int[]) i_reader.getBuffer();\r
60                         for (int y = i_size.h-1; y >=0 ; y-=this._v_interval){\r
61                                 sum+=i_size.w;\r
62                                 int pt=y*i_size.w;\r
63                                 for (int x = i_size.w-1; x >=0; x--) {\r
64                                         o_histgram[input[pt]]++;\r
65                                         pt++;\r
66                                 }\r
67                         }\r
68                         return sum;\r
69                 }\r
70         }\r
71         /**\r
72          * RGB24bitのヒストグラム計算クラス\r
73          *\r
74          */\r
75         final class CreateHistgramImpl_BYTE1D_RGB_24 implements ICreateHistgramImpl\r
76         {\r
77                 private int _v_interval;\r
78                 public CreateHistgramImpl_BYTE1D_RGB_24(int i_v_interval)\r
79                 {\r
80                         this._v_interval=i_v_interval;\r
81                         return;\r
82                 }\r
83                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram)\r
84                 {\r
85                         assert (\r
86                                 i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24)||\r
87                                 i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24));\r
88                         \r
89                         final byte[] input=(byte[]) i_reader.getBuffer();\r
90                         final int pix_count=i_size.w;\r
91                         final int pix_mod_part=pix_count-(pix_count%8);\r
92                         int sum=0;\r
93                         for (int y = i_size.h-1; y >=0 ; y-=this._v_interval) {\r
94                                 sum+=i_size.w;\r
95                                 int pt=y*i_size.w*3;\r
96                                 int x,v;\r
97                                 for (x = pix_count-1; x >=pix_mod_part; x--) {\r
98                                         v=((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3;\r
99                                         o_histgram[v]++;\r
100                                         pt+=3;\r
101                                 }\r
102                                 //タイリング\r
103                                 for (;x>=0;x-=8){\r
104                                         v=((input[pt+ 0]& 0xff)+(input[pt+ 1]& 0xff)+(input[pt+ 2]& 0xff))/3;\r
105                                         o_histgram[v]++;\r
106                                         v=((input[pt+ 3]& 0xff)+(input[pt+ 4]& 0xff)+(input[pt+ 5]& 0xff))/3;\r
107                                         o_histgram[v]++;\r
108                                         v=((input[pt+ 6]& 0xff)+(input[pt+ 7]& 0xff)+(input[pt+ 8]& 0xff))/3;\r
109                                         o_histgram[v]++;\r
110                                         v=((input[pt+ 9]& 0xff)+(input[pt+10]& 0xff)+(input[pt+11]& 0xff))/3;\r
111                                         o_histgram[v]++;\r
112                                         v=((input[pt+12]& 0xff)+(input[pt+13]& 0xff)+(input[pt+14]& 0xff))/3;\r
113                                         o_histgram[v]++;\r
114                                         v=((input[pt+15]& 0xff)+(input[pt+16]& 0xff)+(input[pt+17]& 0xff))/3;\r
115                                         o_histgram[v]++;\r
116                                         v=((input[pt+18]& 0xff)+(input[pt+19]& 0xff)+(input[pt+20]& 0xff))/3;\r
117                                         o_histgram[v]++;\r
118                                         v=((input[pt+21]& 0xff)+(input[pt+22]& 0xff)+(input[pt+23]& 0xff))/3;\r
119                                         o_histgram[v]++;\r
120                                         pt+=3*8;\r
121                                 }\r
122                         }\r
123                         return sum;             \r
124                 }\r
125         }\r
126         /**\r
127          * BYTE1D_B8G8R8X8_32のヒストグラム計算クラス\r
128          *\r
129          */     \r
130     final class CreateHistgramImpl_BYTE1D_B8G8R8X8_32 implements ICreateHistgramImpl\r
131     {\r
132         private int _v_interval;\r
133         public CreateHistgramImpl_BYTE1D_B8G8R8X8_32(int i_v_interval)\r
134         {\r
135             this._v_interval = i_v_interval;\r
136             return;\r
137         }\r
138         public int createHistgramImpl(INyARBufferReader i_reader, NyARIntSize i_size, int[] o_histgram)\r
139         {\r
140             assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32));\r
141             byte[] input = (byte[])i_reader.getBuffer();\r
142             int pix_count = i_size.w;\r
143             int pix_mod_part = pix_count - (pix_count % 8);\r
144             int sum = 0;\r
145             for (int y = i_size.h - 1; y >= 0; y -= this._v_interval)\r
146             {\r
147                 sum += i_size.w;\r
148                 int pt = y * i_size.w * 4;\r
149                 int x, v;\r
150                 for (x = pix_count - 1; x >= pix_mod_part; x--)\r
151                 {\r
152                     v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3;\r
153                     o_histgram[v]++;\r
154                     pt += 4;\r
155                 }\r
156                 //タイリング\r
157                 for (; x >= 0; x -= 8)\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                     v = ((input[pt + 4] & 0xff) + (input[pt + 5] & 0xff) + (input[pt + 6] & 0xff)) / 3;\r
162                     o_histgram[v]++;\r
163                     v = ((input[pt + 8] & 0xff) + (input[pt + 9] & 0xff) + (input[pt + 10] & 0xff)) / 3;\r
164                     o_histgram[v]++;\r
165                     v = ((input[pt + 12] & 0xff) + (input[pt + 13] & 0xff) + (input[pt + 14] & 0xff)) / 3;\r
166                     o_histgram[v]++;\r
167                     v = ((input[pt + 16] & 0xff) + (input[pt + 17] & 0xff) + (input[pt + 18] & 0xff)) / 3;\r
168                     o_histgram[v]++;\r
169                     v = ((input[pt + 20] & 0xff) + (input[pt + 21] & 0xff) + (input[pt + 22] & 0xff)) / 3;\r
170                     o_histgram[v]++;\r
171                     v = ((input[pt + 24] & 0xff) + (input[pt + 25] & 0xff) + (input[pt + 26] & 0xff)) / 3;\r
172                     o_histgram[v]++;\r
173                     v = ((input[pt + 28] & 0xff) + (input[pt + 29] & 0xff) + (input[pt + 30] & 0xff)) / 3;\r
174                     o_histgram[v]++;\r
175                     pt += 4 * 8;\r
176                 }\r
177             }\r
178             return sum;\r
179         }\r
180     }   \r
181         /**\r
182          * BYTE1D_X8R8G8B8_32のヒストグラム計算クラス\r
183          *\r
184          */     \r
185     final class CreateHistgramImpl_BYTE1D_X8R8G8B8_32 implements ICreateHistgramImpl\r
186     {\r
187         private int _v_interval;\r
188         public CreateHistgramImpl_BYTE1D_X8R8G8B8_32(int i_v_interval)\r
189         {\r
190             this._v_interval = i_v_interval;\r
191             return;\r
192         }\r
193         public int createHistgramImpl(INyARBufferReader i_reader, NyARIntSize i_size, int[] o_histgram)\r
194         {\r
195             assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32));\r
196             byte[] input = (byte[])i_reader.getBuffer();\r
197             int pix_count = i_size.w;\r
198             int pix_mod_part = pix_count - (pix_count % 8);\r
199             int sum = 0;\r
200             for (int y = i_size.h - 1; y >= 0; y -= this._v_interval)\r
201             {\r
202                 sum += i_size.w;\r
203                 int pt = y * i_size.w * 4;\r
204                 int x, v;\r
205                 for (x = pix_count - 1; x >= pix_mod_part; x--)\r
206                 {\r
207                     v = ((input[pt + 1] & 0xff) + (input[pt + 2] & 0xff) + (input[pt + 3] & 0xff)) / 3;\r
208                     o_histgram[v]++;\r
209                     pt += 4;\r
210                 }\r
211                 //タイリング\r
212                 for (; x >= 0; x -= 8)\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                     v = ((input[pt + 5] & 0xff) + (input[pt + 6] & 0xff) + (input[pt + 7] & 0xff)) / 3;\r
217                     o_histgram[v]++;\r
218                     v = ((input[pt + 9] & 0xff) + (input[pt + 10] & 0xff) + (input[pt + 11] & 0xff)) / 3;\r
219                     o_histgram[v]++;\r
220                     v = ((input[pt + 13] & 0xff) + (input[pt + 14] & 0xff) + (input[pt + 15] & 0xff)) / 3;\r
221                     o_histgram[v]++;\r
222                     v = ((input[pt + 17] & 0xff) + (input[pt + 18] & 0xff) + (input[pt + 19] & 0xff)) / 3;\r
223                     o_histgram[v]++;\r
224                     v = ((input[pt + 21] & 0xff) + (input[pt + 22] & 0xff) + (input[pt + 23] & 0xff)) / 3;\r
225                     o_histgram[v]++;\r
226                     v = ((input[pt + 25] & 0xff) + (input[pt + 26] & 0xff) + (input[pt + 27] & 0xff)) / 3;\r
227                     o_histgram[v]++;\r
228                     v = ((input[pt + 29] & 0xff) + (input[pt + 30] & 0xff) + (input[pt + 31] & 0xff)) / 3;\r
229                     o_histgram[v]++;\r
230                     pt += 4 * 8;\r
231                 }\r
232             }\r
233             return sum;\r
234         }\r
235     }\r
236     \r
237         /**\r
238          * WORD1D_R5G6B5_16LEのヒストグラム計算クラス\r
239          *\r
240          */     \r
241     final class CreateHistgramImpl_WORD1D_R5G6B5_16LE implements ICreateHistgramImpl\r
242     {\r
243         private int _v_interval;\r
244         public CreateHistgramImpl_WORD1D_R5G6B5_16LE(int i_v_interval)\r
245         {\r
246             this._v_interval = i_v_interval;\r
247             return;\r
248         }\r
249         public int createHistgramImpl(INyARBufferReader i_reader, NyARIntSize i_size, int[] o_histgram)\r
250         {\r
251             assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_WORD1D_R5G6B5_16LE));\r
252             short[] input = (short[])i_reader.getBuffer();\r
253             int pix_count = i_size.w;\r
254             int pix_mod_part = pix_count - (pix_count % 8);\r
255             int sum = 0;\r
256             for (int y = i_size.h - 1; y >= 0; y -= this._v_interval)\r
257             {\r
258                 sum += i_size.w;\r
259                 int pt = y * i_size.w;\r
260                 int x, v;\r
261                 for (x = pix_count - 1; x >= pix_mod_part; x--)\r
262                 {\r
263                     v =(int)input[pt];\r
264                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
265                     o_histgram[v]++;\r
266                     pt++;\r
267                 }\r
268                 //タイリング\r
269                 for (; x >= 0; x -= 8)\r
270                 {\r
271                     v =(int)input[pt];pt++;\r
272                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
273                     o_histgram[v]++;\r
274                     v =(int)input[pt];pt++;\r
275                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
276                     o_histgram[v]++;\r
277                     v =(int)input[pt];pt++;\r
278                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
279                     o_histgram[v]++;\r
280                     v =(int)input[pt];pt++;\r
281                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
282                     o_histgram[v]++;\r
283                     v =(int)input[pt];pt++;\r
284                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
285                     o_histgram[v]++;\r
286                     v =(int)input[pt];pt++;\r
287                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
288                     o_histgram[v]++;\r
289                     v =(int)input[pt];pt++;\r
290                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
291                     o_histgram[v]++;\r
292                     v =(int)input[pt];pt++;\r
293                     v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
294                     o_histgram[v]++;\r
295                 }\r
296             }\r
297             return sum;\r
298         }\r
299     }\r
300 \r
301     \r
302     \r
303     \r
304 \r
305     private int _persentage;\r
306         private int _threshold;\r
307         private ICreateHistgramImpl _histgram;\r
308         \r
309         /**\r
310          * @param i_persentage\r
311          * 0<=50であること。白/黒マーカーの場合は10~20を推奨 正の場合、黒点を基準にします。 負の場合、白点を基準にします。\r
312          * (CMOSカメラの場合、基準点は白点の方が良い)\r
313          */\r
314         public NyARRasterThresholdAnalyzer_SlidePTile(int i_persentage,int i_raster_format,int i_vertical_interval) throws NyARException\r
315         {\r
316                 assert (0 <= i_persentage && i_persentage <= 50);\r
317                 this._persentage = i_persentage;\r
318         switch (i_raster_format)\r
319         {\r
320             case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
321             case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
322                 this._histgram = new CreateHistgramImpl_BYTE1D_RGB_24(i_vertical_interval);\r
323                 break;\r
324             case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
325                 this._histgram = new CreateHistgramImpl_INT1D_GRAY_8(i_vertical_interval);\r
326                 break;\r
327             case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
328                 this._histgram = new CreateHistgramImpl_BYTE1D_B8G8R8X8_32(i_vertical_interval);\r
329                 break;\r
330                 case INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32:\r
331                         this._histgram = new CreateHistgramImpl_BYTE1D_X8R8G8B8_32(i_vertical_interval);\r
332                         break;\r
333                 case INyARBufferReader.BUFFERFORMAT_WORD1D_R5G6B5_16LE:\r
334                         this._histgram=new CreateHistgramImpl_WORD1D_R5G6B5_16LE(i_vertical_interval);\r
335                         break;\r
336             default:\r
337                 throw new NyARException();\r
338         }\r
339         }\r
340         public void setVerticalInterval(int i_step)\r
341         {\r
342                 return;//未実装一号\r
343         }\r
344 \r
345         private int[] _histgram_buf=new int[256];\r
346         public void analyzeRaster(INyARRaster i_input) throws NyARException\r
347         {\r
348                 final int[] histgram = this._histgram_buf;\r
349                 final NyARIntSize size=i_input.getSize();\r
350                 \r
351                 //最大画像サイズの制限\r
352                 assert size.w*size.h<0x40000000;\r
353 \r
354                 //ヒストグラム初期化\r
355                 for (int i = 0; i < 256; i++) {\r
356                         histgram[i] = 0;\r
357                 }\r
358                 int sum_of_pixel=this._histgram.createHistgramImpl(i_input.getBufferReader(), size, histgram);\r
359 \r
360                 // 閾値ピクセル数確定\r
361                 final int th_pixcels = sum_of_pixel * this._persentage / 100;\r
362                 int th_wk;\r
363                 int th_w, th_b;\r
364 \r
365                 // 黒点基準\r
366                 th_wk = th_pixcels;\r
367                 for (th_b = 0; th_b < 254; th_b++) {\r
368                         th_wk -= histgram[th_b];\r
369                         if (th_wk <= 0) {\r
370                                 break;\r
371                         }\r
372                 }\r
373                 // 白点基準\r
374                 th_wk = th_pixcels;\r
375                 for (th_w = 255; th_w > 1; th_w--) {\r
376                         th_wk -= histgram[th_w];\r
377                         if (th_wk <= 0) {\r
378                                 break;\r
379                         }\r
380                 }\r
381                 // 閾値の保存\r
382                 this._threshold = (th_w + th_b) / 2;\r
383                 return;\r
384         }\r
385         public int getThreshold()\r
386         {\r
387                 return this._threshold;\r
388         }\r
389 \r
390         public int getThreshold(int i_x, int i_y)\r
391         {\r
392                 return this._threshold;\r
393         }\r
394 }\r