OSDN Git Service

1e5114a02b0aa0ee7bac16b205a0c9c6db9341ec
[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_GLAY_8 implements ICreateHistgramImpl\r
54         {\r
55                 public int _v_interval;\r
56                 public CreateHistgramImpl_INT1D_GLAY_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                         int sum=0;\r
64                         final int[] input=(int[]) i_reader.getBuffer();\r
65                         for (int y = i_size.h-1; y >=0 ; y-=this._v_interval){\r
66                                 sum+=i_size.w;\r
67                                 int pt=y*i_size.w;\r
68                                 for (int x = i_size.w-1; x >=0; x--) {\r
69                                         o_histgram[input[pt]]++;\r
70                                         pt++;\r
71                                 }\r
72                         }\r
73                         return sum;\r
74                 }\r
75         }\r
76         final class CreateHistgramImpl_BYTE1D_RGB_24 implements ICreateHistgramImpl\r
77         {\r
78                 private int _v_interval;\r
79                 public CreateHistgramImpl_BYTE1D_RGB_24(int i_v_interval)\r
80                 {\r
81                         this._v_interval=i_v_interval;\r
82                         return;\r
83                 }\r
84                 public int createHistgramImpl(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram)\r
85                 {\r
86                         final byte[] input=(byte[]) i_reader.getBuffer();\r
87                         final int pix_count=i_size.w;\r
88                         final int pix_mod_part=pix_count-(pix_count%8);\r
89                         int sum=0;\r
90                         for (int y = i_size.h-1; y >=0 ; y-=this._v_interval) {\r
91                                 sum+=i_size.w;\r
92                                 int pt=y*i_size.w*3;\r
93                                 int x,v;\r
94                                 for (x = pix_count-1; x >=pix_mod_part; x--) {\r
95                                         v=((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3;\r
96                                         o_histgram[v]++;\r
97                                         pt+=3;\r
98                                 }\r
99                                 //タイリング\r
100                                 for (;x>=0;x-=8){\r
101                                         v=((input[pt+ 0]& 0xff)+(input[pt+ 1]& 0xff)+(input[pt+ 2]& 0xff))/3;\r
102                                         o_histgram[v]++;\r
103                                         v=((input[pt+ 3]& 0xff)+(input[pt+ 4]& 0xff)+(input[pt+ 5]& 0xff))/3;\r
104                                         o_histgram[v]++;\r
105                                         v=((input[pt+ 6]& 0xff)+(input[pt+ 7]& 0xff)+(input[pt+ 8]& 0xff))/3;\r
106                                         o_histgram[v]++;\r
107                                         v=((input[pt+ 9]& 0xff)+(input[pt+10]& 0xff)+(input[pt+11]& 0xff))/3;\r
108                                         o_histgram[v]++;\r
109                                         v=((input[pt+12]& 0xff)+(input[pt+13]& 0xff)+(input[pt+14]& 0xff))/3;\r
110                                         o_histgram[v]++;\r
111                                         v=((input[pt+15]& 0xff)+(input[pt+16]& 0xff)+(input[pt+17]& 0xff))/3;\r
112                                         o_histgram[v]++;\r
113                                         v=((input[pt+18]& 0xff)+(input[pt+19]& 0xff)+(input[pt+20]& 0xff))/3;\r
114                                         o_histgram[v]++;\r
115                                         v=((input[pt+21]& 0xff)+(input[pt+22]& 0xff)+(input[pt+23]& 0xff))/3;\r
116                                         o_histgram[v]++;\r
117                                         pt+=3*8;\r
118                                 }\r
119                         }\r
120                         return sum;             \r
121                 }\r
122         }\r
123         private int _persentage;\r
124         private int _threshold;\r
125         private ICreateHistgramImpl _histgram;\r
126         \r
127         /**\r
128          * @param i_persentage\r
129          * 0<=50であること。白/黒マーカーの場合は10~20を推奨 正の場合、黒点を基準にします。 負の場合、白点を基準にします。\r
130          * (CMOSカメラの場合、基準点は白点の方が良い)\r
131          */\r
132         public NyARRasterThresholdAnalyzer_SlidePTile(int i_persentage,int i_raster_format,int i_vertical_interval) throws NyARException\r
133         {\r
134                 assert (0 <= i_persentage && i_persentage <= 50);\r
135                 this._persentage = i_persentage;\r
136                 switch(i_raster_format){\r
137                 case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
138                 case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
139                         this._histgram=new CreateHistgramImpl_BYTE1D_RGB_24(i_vertical_interval);\r
140                         break;\r
141                 case INyARBufferReader.BUFFERFORMAT_INT1D_GLAY_8:\r
142                         this._histgram=new CreateHistgramImpl_INT1D_GLAY_8(i_vertical_interval);\r
143                         break;\r
144                 default:\r
145                         throw new NyARException();\r
146                 }\r
147         }\r
148         public void setVerticalInterval(int i_step)\r
149         {\r
150                 return;//未実装一号\r
151         }\r
152 \r
153 \r
154         private int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram) throws NyARException\r
155         {\r
156                 //最大画像サイズの制限\r
157                 assert i_size.w*i_size.h<0x40000000;\r
158 \r
159                 int[] histgram = o_histgram;\r
160                 \r
161                 //ヒストグラム作成              \r
162                 for (int i = 0; i < 256; i++) {\r
163                         o_histgram[i] = 0;\r
164                 }\r
165                 int sum_of_pixel=this._histgram.createHistgramImpl(i_reader, i_size, o_histgram);\r
166 \r
167                 // 閾値ピクセル数確定\r
168                 final int th_pixcels = sum_of_pixel * this._persentage / 100;\r
169                 int th_wk;\r
170                 int th_w, th_b;\r
171 \r
172                 // 黒点基準\r
173                 th_wk = th_pixcels;\r
174                 for (th_b = 0; th_b < 254; th_b++) {\r
175                         th_wk -= histgram[th_b];\r
176                         if (th_wk <= 0) {\r
177                                 break;\r
178                         }\r
179                 }\r
180                 // 白点基準\r
181                 th_wk = th_pixcels;\r
182                 for (th_w = 255; th_w > 1; th_w--) {\r
183                         th_wk -= histgram[th_w];\r
184                         if (th_wk <= 0) {\r
185                                 break;\r
186                         }\r
187                 }\r
188                 // 閾値の保存\r
189                 return (th_w + th_b) / 2;\r
190         }\r
191 \r
192         public void analyzeRaster(INyARRaster i_input) throws NyARException\r
193         {\r
194                 final INyARBufferReader buffer_reader=i_input.getBufferReader();        \r
195                 assert (buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GLAY_8));\r
196 \r
197                 int[] histgram = new int[256];\r
198                 // 閾値の基準値を出す。\r
199                 this._threshold = createHistgram(buffer_reader,i_input.getSize(), histgram);\r
200                 return;\r
201         }\r
202 \r
203         /**\r
204          * ヒストグラムをラスタに書き出す。\r
205          * \r
206          * @param i_output\r
207          */\r
208         public void debugDrawHistgramMap(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
209         {\r
210                 INyARBufferReader in_buffer_reader=i_input.getBufferReader();   \r
211                 INyARBufferReader out_buffer_reader=i_output.getBufferReader(); \r
212                 assert (in_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GLAY_8));\r
213                 assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GLAY_8));\r
214 \r
215                 NyARIntSize size = i_output.getSize();\r
216 \r
217                 int[] out_buf = (int[]) out_buffer_reader.getBuffer();\r
218                 // 0で塗りつぶし\r
219                 for (int y = 0; y < size.h; y++) {\r
220                         for (int x = 0; x < size.w; x++) {\r
221                                 out_buf[y* size.w+x] = 0;\r
222                         }\r
223                 }\r
224                 // ヒストグラムを計算\r
225                 int[] histgram = new int[256];\r
226                 int threshold = createHistgram(in_buffer_reader,i_input.getSize(), histgram);\r
227                 for (int i = 255; i > 0; i--) {\r
228                         histgram[i] = Math.abs(histgram[i]);\r
229                 }\r
230 \r
231                 // ヒストグラムの最大値を出す\r
232                 int max_v = 0;\r
233                 for (int i = 0; i < 255; i++) {\r
234                         if (max_v < histgram[i]) {\r
235                                 max_v = histgram[i];\r
236                         }\r
237                 }\r
238                 // 目盛り\r
239                 for (int i = 0; i < size.h; i++) {\r
240                         out_buf[i* size.w+0] = 128;\r
241                         out_buf[i* size.w+128] = 128;\r
242                         out_buf[i* size.w+255] = 128;\r
243                 }\r
244                 // スケーリングしながら描画\r
245                 for (int i = 0; i < 255; i++) {\r
246                         out_buf[(histgram[i] * (size.h - 1) / max_v)* size.w+i] = 255;\r
247                 }\r
248                 // 値\r
249                 for (int i = 0; i < size.h; i++) {\r
250                         out_buf[i* size.w+threshold] = 255;\r
251                 }\r
252                 return;\r
253         }\r
254 \r
255         public int getThreshold()\r
256         {\r
257                 return this._threshold;\r
258         }\r
259 \r
260         public int getThreshold(int i_x, int i_y)\r
261         {\r
262                 return this._threshold;\r
263         }\r
264 }\r