OSDN Git Service

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