OSDN Git Service

89d908ad89a19d82e9a6dfe016cfee37f84bab50
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src / jp / nyatla / nyartoolkit / core2 / rasteranalyzer / NyARRasterDetector_QrCodeEdge.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 edition ARToolKit class library.\r
11  * Copyright (C)2008-2009 Ryo Iizuka\r
12  *\r
13  * This program is free software: you can redistribute it and/or modify\r
14  * it under the terms of the GNU General Public License as published by\r
15  * the Free Software Foundation, either version 3 of the License, or\r
16  * (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 program.  If not, see <http://www.gnu.org/licenses/>.\r
25  * \r
26  * For further information please contact.\r
27  *      http://nyatla.jp/nyatoolkit/\r
28  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
29  * \r
30  */\r
31 package jp.nyatla.nyartoolkit.core2.rasteranalyzer;\r
32 \r
33 import jp.nyatla.nyartoolkit.NyARException;\r
34 import jp.nyatla.nyartoolkit.core.raster.*;\r
35 import jp.nyatla.nyartoolkit.core.types.stack.*;\r
36 import jp.nyatla.nyartoolkit.core.types.*;\r
37 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
38 \r
39 /**\r
40  * QRコードの4頂点候補を探そうとするクラス。\r
41  * 未完成\r
42  *\r
43  */\r
44 public class NyARRasterDetector_QrCodeEdge\r
45 {\r
46         private NyARIntRectStack _result;\r
47 \r
48         public NyARRasterDetector_QrCodeEdge(int i_result_max)\r
49         {\r
50                 this._result = new NyARIntRectStack(i_result_max);\r
51                 return;\r
52         }\r
53 \r
54         public NyARIntRectStack geResult()\r
55         {\r
56                 return this._result;\r
57         }\r
58 \r
59         private boolean check_w1(int i_w1)\r
60         {\r
61                 return i_w1>=1;         \r
62         }\r
63         private boolean check_b1(int i_b1)\r
64         {\r
65                 return i_b1 >= 2;               \r
66         }\r
67         private boolean check_w2(int i_b1,int i_w2)\r
68         {\r
69                 int v=i_w2*100/i_b1;\r
70                 return (30<=v && v<=170);\r
71         }\r
72         private boolean check_b2(int i_b1,int i_b2)\r
73         {\r
74                 int v=i_b2*100/i_b1;\r
75                 //条件:(b1)/2の2~4倍\r
76                 return (200<=v && v<=400);\r
77         }\r
78         private boolean check_w3(int i_w2,int i_w3)\r
79         {\r
80                 int v=i_w3*100/i_w2;\r
81                 return (50<=v && v<=150);\r
82         }\r
83         private boolean check_b3(int i_b3,int i_b1)\r
84         {\r
85                 int v=i_b3*100/i_b1;\r
86                 return (50<=v && v<=150);\r
87         }       \r
88         public void analyzeRaster(INyARRaster i_input) throws NyARException\r
89         {\r
90                 INyARBufferReader buffer_reader=i_input.getBufferReader();\r
91                 assert (buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8));\r
92 \r
93                 // 結果をクリア\r
94                 this._result.clear();\r
95 \r
96                 NyARIntSize size = i_input.getSize();\r
97                 int x = 0;\r
98                 int w1, b1, w2, b2, w3, b3;\r
99                 w1 = b1 = w2 = b2 = w3 = b3 = 0;\r
100 \r
101                 NyARIntRect item;\r
102                 int[] raster_buf=(int[])buffer_reader.getBuffer();\r
103                 int line_ptr;\r
104                 int s_pos, b2_spos,b3_spos;\r
105                 b2_spos=0;\r
106                 for (int y = size.h - 1-8; y >= 8; y--) {\r
107                         line_ptr = y*size.w;\r
108                         x = size.w - 1;\r
109                         s_pos=0;\r
110                         int token_id=0;\r
111                         while(x>=0){\r
112                                 switch(token_id){\r
113                                 case 0:\r
114                                         // w1の特定\r
115                                         w1 = 0;\r
116                                         for (; x >= 0; x--) {\r
117                                                 if (raster_buf[line_ptr+x] == 0) {\r
118                                                         // 検出条件確認:w1は2以上欲しいな。\r
119                                                         if (!check_w1(w1)) {\r
120                                                                 // 条件不十分\r
121                                                                 continue;\r
122                                                         }else{\r
123                                                                 // 検出→次段処理へ\r
124                                                                 token_id=1;\r
125                                                         }\r
126                                                         break;\r
127                                                 }\r
128                                                 w1++;\r
129                                         }\r
130                                         break;\r
131                                 case 1:\r
132                                         // b1の特定\r
133                                         b1 = 0;\r
134                                         s_pos = x;\r
135                                         for (; x >= 0; x--) {\r
136                                                 if (raster_buf[line_ptr+x] > 0) {\r
137                                                         // 検出条件確認:b1は1以上欲しいな。\r
138                                                         if (!check_b1(b1)){\r
139                                                                 //条件不十分→白検出からやり直し\r
140                                                                 token_id=0;\r
141                                                         }else{\r
142                                                                 // 検出→次段処理へ\r
143                                                                 token_id=2;\r
144                                                         }\r
145                                                         break;\r
146                                                 }\r
147                                                 b1++;\r
148                                         }\r
149                                         break;\r
150                                 case 2:\r
151                                         // w2の特定\r
152                                         w2 = 0;\r
153                                         for (; x >= 0; x--) {\r
154                                                 if (raster_buf[line_ptr+x] == 0) {\r
155                                                         // 検出条件確認:w2*10/b1は80-120以上欲しいな。\r
156                                                         if (!check_w2(b1,w2)) {\r
157                                                                 //条件不十分→w2→w1として、b1を解析\r
158                                                                 w1=w2;\r
159                                                                 token_id=1;\r
160                                                         }else{\r
161                                                                 // 検出→次段処理へ\r
162 //                                                              w1=w2;\r
163 //                                                              token_id=11;\r
164                                                                 token_id=3;\r
165                                                         }\r
166                                                         break;\r
167                                                 }\r
168                                                 w2++;\r
169                                         }\r
170                                         break;\r
171                                 case 3:\r
172                                         // b2の特定\r
173                                         b2 = 0;\r
174                                         b2_spos=x;\r
175                                         for (; x >= 0; x--) {\r
176                                                 if (raster_buf[line_ptr+x] > 0){\r
177                                                         //条件:(w1+b1)/2の2~4倍\r
178 \r
179                                                         if (!check_b2(b1,b2)) {\r
180                                                                 // b2->b1と仮定して解析しなおす。\r
181                                                                 if(check_w1(w2) && check_b1(b2)){\r
182                                                                         w1 = w2;\r
183                                                                         b1 = b2;\r
184                                                                         s_pos=b2_spos;\r
185                                                                         token_id=2;\r
186                                                                 }else{\r
187                                                                         \r
188                                                                         token_id=0;\r
189                                                                 }\r
190                                                         }else{\r
191                                                                 // 検出→次段処理へ\r
192 //                                                              token_id=10;\r
193                                                                 token_id=4;\r
194                                                         }\r
195                                                         break;\r
196                                                 }\r
197                                                 b2++;\r
198                                         }\r
199                                         break;\r
200                                 case 4:\r
201                                         // w3の特定\r
202                                         w3 = 0;\r
203                                         for (; x >= 0; x--) {\r
204                                                 if (raster_buf[line_ptr+x] == 0){\r
205                                                         if (!check_w3(w2,w3)) {\r
206                                                                 //w2→w1,b2->b1として解析しなおす。\r
207                                                                 if(check_w1(w2) && check_b1(b2)){\r
208                                                                         w1 = w2;\r
209                                                                         b1 = b2;\r
210                                                                         s_pos=b2_spos;\r
211                                                                         token_id=2;\r
212                                                                 }else{\r
213                                                                         token_id=0;\r
214                                                                 }\r
215                                                         }else{\r
216                                                                 // 検出→次段処理へ\r
217 //                                                              w1=w3;\r
218 //                                                              token_id=10;\r
219                                                                 token_id=5;\r
220                                                         }\r
221                                                         break;\r
222                                                 }\r
223                                                 w3++;\r
224                                         }\r
225                                         break;\r
226                                 case 5:\r
227                                         // b3の特定\r
228                                         b3 = 0;\r
229                                         b3_spos=x;\r
230                                         for (; x >= 0; x--) {\r
231                                                 if (raster_buf[line_ptr+x] > 0) {\r
232                                                         // 検出条件確認\r
233                                                         if (!check_b3(b3,b1)) {\r
234                                                                 if(check_w1(w2) && check_b1(b2)){\r
235                                                                 //条件不十分→b3->b1,w3->w1として再解析\r
236                                                                         w1=w3;\r
237                                                                         b1=b3;\r
238                                                                         s_pos=b3_spos;\r
239                                                                         token_id=2;\r
240                                                                 }else{\r
241                                                                         token_id=0;\r
242                                                                 }\r
243                                                         }else{\r
244                                                                 // 検出→次段処理へ\r
245                                                                 token_id=10;\r
246                                                         }\r
247                                                         break;\r
248                                                 }\r
249                                                 b3++;\r
250                                         }\r
251                                         break;\r
252                                 case 10:\r
253                                         /* コード特定→保管 */\r
254                                         item = this._result.prePush();\r
255                                         item.x = x;\r
256                                         item.y = y;\r
257                                         item.w =s_pos-x;\r
258                                         item.h=0;\r
259                                         /* 最大個数? */\r
260                                         /* 次のコードを探す */\r
261                                         token_id=0;\r
262                                         break;\r
263                                 default:\r
264                                         throw new NyARException();\r
265                                 }\r
266                         }\r
267                 }\r
268                 return;\r
269         }\r
270 }\r