OSDN Git Service

53cf6f7a4b5b7605798370ec17f296cbd91c426a
[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 /**\r
41  * QRコードの4頂点候補を探そうとするクラス。\r
42  * 未完成\r
43  *\r
44  */\r
45 public class NyARRasterDetector_QrCodeEdge\r
46 {\r
47         private NyARIntRectStack _result;\r
48 \r
49         public NyARRasterDetector_QrCodeEdge(int i_result_max)\r
50         {\r
51                 this._result = new NyARIntRectStack(i_result_max);\r
52                 return;\r
53         }\r
54 \r
55         public NyARIntRectStack geResult()\r
56         {\r
57                 return this._result;\r
58         }\r
59 \r
60         private boolean check_w1(int i_w1)\r
61         {\r
62                 return i_w1>=1;         \r
63         }\r
64         private boolean check_b1(int i_b1)\r
65         {\r
66                 return i_b1 >= 2;               \r
67         }\r
68         private boolean check_w2(int i_b1,int i_w2)\r
69         {\r
70                 int v=i_w2*100/i_b1;\r
71                 return (30<=v && v<=170);\r
72         }\r
73         private boolean check_b2(int i_b1,int i_b2)\r
74         {\r
75                 int v=i_b2*100/i_b1;\r
76                 //条件:(b1)/2の2~4倍\r
77                 return (200<=v && v<=400);\r
78         }\r
79         private boolean check_w3(int i_w2,int i_w3)\r
80         {\r
81                 int v=i_w3*100/i_w2;\r
82                 return (50<=v && v<=150);\r
83         }\r
84         private boolean check_b3(int i_b3,int i_b1)\r
85         {\r
86                 int v=i_b3*100/i_b1;\r
87                 return (50<=v && v<=150);\r
88         }       \r
89         public void analyzeRaster(INyARRaster i_input) throws NyARException\r
90         {\r
91                 INyARBufferReader buffer_reader=i_input.getBufferReader();\r
92                 assert (buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT2D_BIN_8));\r
93 \r
94                 // 結果をクリア\r
95                 this._result.clear();\r
96 \r
97                 NyARIntSize size = i_input.getSize();\r
98                 int x = 0;\r
99                 int w1, b1, w2, b2, w3, b3;\r
100                 w1 = b1 = w2 = b2 = w3 = b3 = 0;\r
101 \r
102                 NyARIntRect item;\r
103                 int[] line;\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 = ((int[][]) buffer_reader.getBuffer())[y];\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 (line[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 (line[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 (line[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 (line[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 (line[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 (line[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 = (NyARIntRect)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