root/as3/FLARToolKit/trunk/src/org/libspark/flartoolkit/detector/FLARMultiMarkerDetector.as

リビジョン 4718, 12.9 kB (コミッタ: rokubou, コミット時期: 4 日 前)

FLARToolKit v4 core

Line 
1 /*
2  * PROJECT: FLARToolKit
3  * --------------------------------------------------------------------------------
4  * This work is based on the FLARToolKit developed by
5  *   R.Iizuka (nyatla)
6  * http://nyatla.jp/nyatoolkit/
7  *
8  * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
9  * Copyright (C)2008 Saqoosha
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  *
24  * For further information please contact.
25  *      http://www.libspark.org/wiki/saqoosha/FLARToolKit
26  *      <saq(at)saqoosha.net>
27  *
28  */
29 package org.libspark.flartoolkit.detector
30 {
31         import org.libspark.flartoolkit.core.*;
32         import org.libspark.flartoolkit.*;
33         import org.libspark.flartoolkit.core.transmat.*;
34         import org.libspark.flartoolkit.core.squaredetect.*;
35         import org.libspark.flartoolkit.core.rasterfilter.rgb2gs.*;
36         import org.libspark.flartoolkit.core.raster.*;
37         import org.libspark.flartoolkit.core.raster.rgb.*;
38         import org.libspark.flartoolkit.core.types.*;
39         import org.libspark.flartoolkit.core.pickup.*;
40         import org.libspark.flartoolkit.core.param.*;
41        
42         import org.libspark.flartoolkit.core.raster.*;
43         import org.libspark.flartoolkit.core.squaredetect.*;
44         import org.libspark.flartoolkit.core.*;
45         import org.libspark.flartoolkit.*;
46         import org.libspark.flartoolkit.core.raster.rgb.*;
47
48
49         public class FLARMultiMarkerDetector
50         {
51                 private var _is_continue:Boolean = false;
52                 private var _square_detect:FLDetector;
53                 protected var _transmat:IFLARTransMat;
54                 private var _offset:Vector.<FLARRectOffset>;
55
56
57                 /**
58                  * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。
59                  *
60                  * @param i_param
61                  * カメラパラメータを指定します。
62                  * @param i_code
63                  * 検出するマーカーのARCode配列を指定します。
64                  * 配列要素のインデックス番号が、そのままgetARCodeIndex関数で得られるARCodeインデックスになります。
65                  * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。
66                  * @param i_marker_width
67                  * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。
68                  * @param i_number_of_code
69                  * i_codeに含まれる、ARCodeの数を指定します。
70                  * @param i_input_raster_type
71                  * 入力ラスタのピクセルタイプを指定します。この値は、IFLARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。
72                  * @throws FLARException
73                  */
74                 public function FLARMultiMarkerDetector(i_param:FLARParam, i_code:Vector.<FLARCode>, i_marker_width:Vector.<Number>, i_number_of_code:int)
75                 {
76                         initInstance(i_param,i_code,i_marker_width,i_number_of_code);
77                         return;
78                 }
79                 protected function initInstance(
80                         i_ref_param:FLARParam,
81                         i_ref_code:Vector.<FLARCode>,
82                         i_marker_width:Vector.<Number>,
83                         i_number_of_code:int):void
84                 {
85
86                         var scr_size:FLARIntSize=i_ref_param.getScreenSize();
87                         // 解析オブジェクトを作る
88                         var cw:int = i_ref_code[0].getWidth();
89                         var ch:int = i_ref_code[0].getHeight();
90
91                         this._transmat = new FLARTransMat(i_ref_param);
92                         //FLARToolkitプロファイル
93                         this._square_detect =new FLDetector(new FLARColorPatt_Perspective(cw, ch,4,25),i_ref_code,i_number_of_code,i_ref_param);
94
95                         //実サイズ保存
96                         this._offset = FLARRectOffset.createArray(i_number_of_code);
97                         for(var i:int=0;i<i_number_of_code;i++){
98                                 this._offset[i].setSquare(i_marker_width[i]);
99                         }
100                         //2値画像バッファを作る
101                         this._bin_raster=new FLARBinRaster(scr_size.w,scr_size.h);
102                         return;         
103                 }
104                
105                 private var _bin_raster:FLARBinRaster;
106
107                 private var _tobin_filter:IFLARRgb2GsFilterArtkTh;
108                 private var _last_input_raster:IFLARRgbRaster=null;
109                 /**
110                  * i_imageにマーカー検出処理を実行し、結果を記録します。
111                  *
112                  * @param i_raster
113                  * マーカーを検出するイメージを指定します。
114                  * @param i_thresh
115                  * 検出閾値を指定します。0~255の範囲で指定してください。 通常は100~130くらいを指定します。
116                  * @return 見つかったマーカーの数を返します。 マーカーが見つからない場合は0を返します。
117                  * @throws FLARException
118                  */
119                 public function detectMarkerLite(i_raster:IFLARRgbRaster,i_threshold:int):int
120                 {
121                         // サイズチェック
122                         if (!this._bin_raster.getSize().isEqualSize_2(i_raster.getSize())) {
123                                 throw new FLARException();
124                         }
125                         if(this._last_input_raster!=i_raster){
126                                 this._tobin_filter=IFLARRgb2GsFilterArtkTh(i_raster.createInterface(IFLARRgb2GsFilterArtkTh));
127                                 this._last_input_raster=i_raster;
128                         }
129                         this._tobin_filter.doFilter(i_threshold,this._bin_raster);
130                         //detect
131                         this._square_detect.init(i_raster);
132                         this._square_detect.detectMarker(this._bin_raster,this._square_detect);
133
134                         //見付かった数を返す。
135                         return this._square_detect.result_stack.getLength();
136                 }
137
138                 /**
139                  * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。 直前に実行したdetectMarkerLiteが成功していないと使えません。
140                  *
141                  * @param i_index
142                  * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
143                  * @param o_result
144                  * 結果値を受け取るオブジェクトを指定してください。
145                  * @throws FLARException
146                  */
147                 public function getTransformMatrix(i_index:int,o_result:FLARTransMatResult):void
148                 {
149                         var result:FLARDetectMarkerResult = FLARDetectMarkerResult(this._square_detect.result_stack.getItem(i_index));
150                         // 一番一致したマーカーの位置とかその辺を計算
151                         if (_is_continue) {
152                                 _transmat.transMatContinue(result.square, this._offset[result.arcode_id], o_result,o_result);
153                         } else {
154                                 _transmat.transMat(result.square, this._offset[result.arcode_id], o_result);
155                         }
156                         return;
157                 }
158
159                 /**
160                  * i_indexのマーカーの一致度を返します。
161                  *
162                  * @param i_index
163                  * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
164                  * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。
165                  * @throws FLARException
166                  */
167                 public function getConfidence(i_index:int):Number
168                 {
169                         return this._square_detect.result_stack.getItem(i_index).confidence;
170                 }
171                 /**
172                  * i_indexのマーカーのARCodeインデックスを返します。
173                  *
174                  * @param i_index
175                  * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
176                  * @return
177                  */
178                 public function getARCodeIndex(i_index:int):int
179                 {
180                         return this._square_detect.result_stack.getItem(i_index).arcode_id;
181                 }
182
183                 /**
184                  * getTransmationMatrixの計算モードを設定します。
185                  *
186                  * @param i_is_continue
187                  * TRUEなら、transMatContinueを使用します。 FALSEなら、transMatを使用します。
188                  */
189                 public function setContinueMode(i_is_continue:Boolean):void
190                 {
191                         this._is_continue = i_is_continue;
192                 }
193         }
194
195 }
196
197 import org.libspark.flartoolkit.core.*;
198 import org.libspark.flartoolkit.*;
199 import org.libspark.flartoolkit.core.transmat.*;
200 import org.libspark.flartoolkit.core.types.stack.*;
201 import org.libspark.flartoolkit.core.squaredetect.*;
202 import org.libspark.flartoolkit.core.rasterfilter.rgb2gs.*;
203 import org.libspark.flartoolkit.core.raster.*;
204 import org.libspark.flartoolkit.core.raster.rgb.*;
205 import org.libspark.flartoolkit.core.types.*;
206 import org.libspark.flartoolkit.core.pickup.*;
207 import org.libspark.flartoolkit.core.match.*;
208 import org.libspark.flartoolkit.core.param.*;
209 import org.libspark.flartoolkit.core.transmat.*;
210
211
212 import org.libspark.flartoolkit.core.raster.*;
213 import org.libspark.flartoolkit.core.squaredetect.*;
214 import org.libspark.flartoolkit.core.*;
215 import org.libspark.flartoolkit.*;
216 import org.libspark.flartoolkit.core.raster.rgb.*;
217
218
219 class FLARDetectMarkerResult
220 {
221         public var arcode_id:int;
222         public var confidence:Number;
223         public var square:FLARSquare=new FLARSquare();
224 }
225
226
227 class FLARDetectMarkerResultStack extends FLARObjectStack
228 {
229         public function FLARDetectMarkerResultStack(i_length:int)
230         {
231                 super();
232                 this.initInstance(i_length);
233                 return;
234         }
235         protected override function createElement():Object
236         {
237                 return new FLARDetectMarkerResult();
238         }       
239 }       
240        
241 class FLDetector extends FLARSquareContourDetector_FlaFill implements FLARSquareContourDetector_CbHandler
242 {
243                 private static const AR_SQUARE_MAX:int = 300;
244        
245         //公開プロパティ
246         public var result_stack:FLARDetectMarkerResultStack=new FLARDetectMarkerResultStack(AR_SQUARE_MAX);
247         //参照インスタンス
248         public var _ref_raster:IFLARRgbRaster;
249         //所有インスタンス
250         private var _inst_patt:IFLARColorPatt;
251         private var _deviation_data:FLARMatchPattDeviationColorData;
252         private var _match_patt:Vector.<FLARMatchPatt_Color_WITHOUT_PCA>;
253         private var __detectMarkerLite_mr:FLARMatchPattResult=new FLARMatchPattResult();
254         private var _coordline:FLARCoord2Linear;
255
256         public function FLDetector(i_inst_patt:IFLARColorPatt,i_ref_code:Vector.<FLARCode>,i_num_of_code:int,i_param:FLARParam)
257         {
258                 super(i_param.getScreenSize());
259                 var cw:int = i_ref_code[0].getWidth();
260                 var ch:int = i_ref_code[0].getHeight();
261                 //FLARMatchPatt_Color_WITHOUT_PCA[]の作成
262                 this._match_patt=new Vector.<FLARMatchPatt_Color_WITHOUT_PCA>(i_num_of_code);
263                 this._match_patt[0]=new FLARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]);
264                 for (var i:int = 1; i < i_num_of_code; i++){
265                         //解像度チェック
266                         if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) {
267                                 throw new FLARException();
268                         }
269                         this._match_patt[i]=new FLARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);
270                 }
271                 this._inst_patt=i_inst_patt;
272                 this._coordline=new FLARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
273                 this._deviation_data=new FLARMatchPattDeviationColorData(cw,ch);
274                 return;
275         }
276         private var __ref_vertex:Vector.<FLARIntPoint2d> = FLARIntPoint2d.createArray(4);
277         /**
278          * 矩形が見付かるたびに呼び出されます。
279          * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
280          */
281         public function detectMarkerCallback(i_coord:FLARIntCoordinates, i_vertex_index:Vector.<int>):void
282         {
283                 var mr:FLARMatchPattResult=this.__detectMarkerLite_mr;
284                 //輪郭座標から頂点リストに変換
285                 var vertex:Vector.<FLARIntPoint2d>=this.__ref_vertex;
286                 vertex[0]=i_coord.items[i_vertex_index[0]];
287                 vertex[1]=i_coord.items[i_vertex_index[1]];
288                 vertex[2]=i_coord.items[i_vertex_index[2]];
289                 vertex[3]=i_coord.items[i_vertex_index[3]];
290        
291                 //画像を取得
292                 if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){
293                         return;
294                 }
295                 //取得パターンをカラー差分データに変換して評価する。
296                 this._deviation_data.setRaster(this._inst_patt);
297
298                 //最も一致するパターンを割り当てる。
299                 var square_index:int,direction:int;
300                 var confidence:Number;
301                 this._match_patt[0].evaluate(this._deviation_data,mr);
302                 square_index=0;
303                 direction=mr.direction;
304                 confidence = mr.confidence;
305                 var i:int;
306                 //2番目以降
307                 for(i=1;i<this._match_patt.length;i++){
308                         this._match_patt[i].evaluate(this._deviation_data,mr);
309                         if (confidence > mr.confidence) {
310                                 continue;
311                         }
312                         // もっと一致するマーカーがあったぽい
313                         square_index = i;
314                         direction = mr.direction;
315                         confidence = mr.confidence;
316                 }
317                 //最も一致したマーカ情報を、この矩形の情報として記録する。
318                 var result:FLARDetectMarkerResult = FLARDetectMarkerResult(this.result_stack.prePush());
319                 result.arcode_id = square_index;
320                 result.confidence = confidence;
321
322                 var sq:FLARSquare=result.square;
323                 //directionを考慮して、squareを更新する。
324                 for(i=0;i<4;i++){
325                         var idx:int=(i+4 - direction) % 4;
326                         this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]);
327                 }
328                 for (i = 0; i < 4; i++) {
329                         //直線同士の交点計算
330                         if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){
331                                 throw new FLARException();//ここのエラー復帰するならダブルバッファにすればOK
332                         }
333                 }
334         }
335         public function init(i_raster:IFLARRgbRaster):void
336         {
337                 this._ref_raster=i_raster;
338                 this.result_stack.clear();
339                
340         }
341 }
342                
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。