OSDN Git Service

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