root/as3/FLARToolKit/trunk/src/org/libspark/flartoolkit/processor/FLSingleARMarkerProcesser.as

リビジョン 4718, 14.5 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.processor
30 {
31         import org.libspark.flartoolkit.core.match.*;
32         import org.libspark.flartoolkit.core.pickup.*;
33         import org.libspark.flartoolkit.core.squaredetect.*;
34         import org.libspark.flartoolkit.core.transmat.*;
35         import org.libspark.flartoolkit.core.raster.*;
36         import org.libspark.flartoolkit.core.raster.rgb.*;
37         import org.libspark.flartoolkit.core.*;
38         import org.libspark.flartoolkit.core.types.*;
39         import org.libspark.flartoolkit.*;
40         import jp.nyatla.as3utils.*;
41        
42        
43         import org.libspark.flartoolkit.core.raster.*;
44         import org.libspark.flartoolkit.core.squaredetect.*;
45         import org.libspark.flartoolkit.core.*;
46         import org.libspark.flartoolkit.*;
47         import org.libspark.flartoolkit.core.param.*;
48         import org.libspark.flartoolkit.core.raster.rgb.*;
49         import org.libspark.flartoolkit.core.analyzer.histogram.*;     
50         import org.libspark.flartoolkit.core.rasterdriver.*;
51         import org.libspark.flartoolkit.core.rasterfilter.rgb2gs.*;
52         import org.libspark.flartoolkit.core.rasterfilter.* ;
53         /**
54          * このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。
55          * マーカの出現・移動・消滅を、イベントで通知することができます。
56          * クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを
57          * 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。
58          *
59          * イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。
60          * マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。
61          * 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave
62          * イベントが発生します。
63          *
64          */
65         public class FLSingleARMarkerProcesser
66         {
67                 /**オーナーが自由に使えるタグ変数です。
68                  */
69                 public var tag:Object;
70
71                 private var _lost_delay_count:int = 0;
72
73                 private var _lost_delay:int = 5;
74
75                 protected var _transmat:IFLARTransMat;
76
77                 private var _offset:FLARRectOffset;
78                 private var _threshold:int = 110;
79                 // [AR]検出結果の保存用
80                 private var _bin_raster:FLARBinRaster;
81                 private var _gs_raster:FLARGrayscaleRaster;
82                
83                 protected var _current_arcode_index:int = -1;
84                
85                 public function FLSingleARMarkerProcesser()
86                 {
87                         return;
88                 }
89
90                 private var _initialized:Boolean=false;
91
92                 protected function initInstance(i_param:FLARParam):void
93                 {
94                         //初期化済?
95                         NyAS3Utils.assert(this._initialized==false);
96                        
97                         var scr_size:FLARIntSize = i_param.getScreenSize();
98                         // 解析オブジェクトを作る
99                         this._transmat = new FLARTransMat(i_param);
100                         this._thdetect=new FLARHistogramAnalyzer_SlidePTile(15);
101
102                         // 2値画像バッファを作る
103                         this._bin_raster = new FLARBinRaster(scr_size.w, scr_size.h);
104                         this._gs_raster = new FLARGrayscaleRaster(scr_size.w, scr_size.h,FLARBufferType.OBJECT_AS3_BitmapData,true);
105                         this._initialized=true;
106                         //コールバックハンドラ
107                         this._detectmarker=new DetectSquare(i_param);
108                         this._offset=new FLARRectOffset();
109                         return;
110                 }
111
112                 /*自動・手動の設定が出来ないので、コメントアウト
113                 public void setThreshold(int i_threshold)
114                 {
115                         this._threshold = i_threshold;
116                         return;
117                 }*/
118
119                 /**検出するマーカコードの配列を指定します。 検出状態でこの関数を実行すると、
120                  * オブジェクト状態に強制リセットがかかります。
121                  */
122                 public function setARCodeTable(i_ref_code_table:Vector.<FLARCode>,i_code_resolution:int,i_marker_width:Number):void
123                 {
124                         if (this._current_arcode_index != -1) {
125                                 // 強制リセット
126                                 reset(true);
127                         }
128                         var tmp_ncode:Vector.<FLARCode> = new Vector.<FLARCode>(i_ref_code_table.length);
129                         for (var i:int = 0; i < tmp_ncode.length; i++) {
130                                 tmp_ncode[i] = i_ref_code_table[i];
131                         }
132                        
133                         //検出するマーカセット、情報、検出器を作り直す。(1ピクセル4ポイントサンプリング,マーカのパターン領域は50%)
134                         this._detectmarker.setFLARCodeTable(tmp_ncode,i_code_resolution);
135                         this._offset.setSquare(i_marker_width);
136                         return;
137                 }
138                 private var _detectmarker:DetectSquare;
139                 private var _last_input_raster:IFLARRaster=null;
140                
141                 private var _togs_filter:FLARRgb2GsFilter;
142                 private var _tobin_filter:FLARGs2BinFilter;
143                 private var _histmaker:IFLARHistogramFromRaster;
144                 private var _thdetect:FLARHistogramAnalyzer_SlidePTile;
145                 private var _hist:FLARHistogram = new FLARHistogram(256);
146                
147                 public function reset(i_is_force:Boolean):void
148                 {
149                         if (this._current_arcode_index != -1 && i_is_force == false) {
150                                 // 強制書き換えでなければイベントコール
151                                 this.onLeaveHandler();
152                         }
153                         // カレントマーカをリセット
154                         this._current_arcode_index = -1;
155                         return;
156                 }
157                 public function detectMarker(i_raster:FLARRgbRaster):void
158                 {
159                         // サイズチェック                     
160                         NyAS3Utils.assert(this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h));
161                         if(this._last_input_raster!=i_raster){
162                                 this._histmaker=IFLARHistogramFromRaster(this._gs_raster.createInterface(IFLARHistogramFromRaster));
163                                 this._togs_filter=FLARRgb2GsFilter(i_raster.createInterface(FLARRgb2GsFilter));
164                                 this._tobin_filter=FLARGs2BinFilter(this._gs_raster.createInterface(FLARGs2BinFilter));
165                                 this._last_input_raster=i_raster;
166                         }
167
168                         //GSイメージへの変換とヒストグラムの生成
169                         this._togs_filter.convert(this._gs_raster);
170                         this._tobin_filter.convert(this._threshold,this._bin_raster);
171                         this._histmaker.createHistogram_2(4, this._hist);
172                        
173                         // スクエアコードを探す
174                         this._detectmarker.init(i_raster,this._current_arcode_index);
175                         this._detectmarker.detectMarker(this._bin_raster,this._detectmarker);
176                        
177                         // 認識状態を更新
178                         this.updateStatus(this._detectmarker.square,this._detectmarker.code_index);
179                        
180                        
181                         return;
182                 }
183                 /**
184                  *
185                  * @param i_new_detect_cf
186                  * @param i_exist_detect_cf
187                  */
188                 public function setConfidenceThreshold(i_new_cf:Number,i_exist_cf:Number):void
189                 {
190                         this._detectmarker.cf_threshold_exist=i_exist_cf;
191                         this._detectmarker.cf_threshold_new=i_new_cf;
192                 }
193                 private var __FLARSquare_result:FLARTransMatResult = new FLARTransMatResult();
194
195                 /**     オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。
196                  *      戻り値は、「実際にマーカを発見する事ができたか」です。クラスの状態とは異なります。
197                  */
198                 private function updateStatus(i_square:FLARSquare,i_code_index:int):Boolean
199                 {
200                         var result:FLARTransMatResult = this.__FLARSquare_result;
201                         if (this._current_arcode_index < 0) {// 未認識中
202                                 if (i_code_index < 0) {// 未認識から未認識の遷移
203                                         // なにもしないよーん。
204                                         return false;
205                                 } else {// 未認識から認識の遷移
206                                         this._current_arcode_index = i_code_index;
207                                         // イベント生成
208                                         // OnEnter
209                                         this.onEnterHandler(i_code_index);
210                                         // 変換行列を作成
211                                         this._transmat.transMat(i_square, this._offset, result);
212                                         // OnUpdate
213                                         this.onUpdateHandler(i_square, result);
214                                         this._lost_delay_count = 0;
215                                         return true;
216                                 }
217                         } else {// 認識中
218                                 if (i_code_index < 0) {// 認識から未認識の遷移
219                                         this._lost_delay_count++;
220                                         if (this._lost_delay < this._lost_delay_count) {
221                                                 // OnLeave
222                                                 this._current_arcode_index = -1;
223                                                 this.onLeaveHandler();
224                                         }
225                                         return false;
226                                 } else if (i_code_index == this._current_arcode_index) {// 同じARCodeの再認識
227                                         // イベント生成
228                                         // 変換行列を作成
229                                         this._transmat.transMatContinue(i_square, this._offset, result,result);
230                                         // OnUpdate
231                                         this.onUpdateHandler(i_square, result);
232                                         this._lost_delay_count = 0;
233                                         return true;
234                                 } else {// 異なるコードの認識→今はサポートしない。
235                                         throw new  FLARException();
236                                 }
237                         }
238                 }
239
240                 protected function onEnterHandler(i_code:int):void
241                 {
242                         throw new FLARException("onEnterHandler not implemented.");
243                 }
244
245                 protected function onLeaveHandler():void
246                 {
247                         throw new FLARException("onLeaveHandler not implemented.");
248                 }
249
250                 protected function onUpdateHandler(i_square:FLARSquare, result:FLARTransMatResult):void
251                 {
252                         throw new FLARException("onUpdateHandler not implemented.");
253                 }
254         }
255 }
256 import org.libspark.flartoolkit.core.param.*;
257 import org.libspark.flartoolkit.core.match.*;
258 import org.libspark.flartoolkit.core.pickup.*;
259 import org.libspark.flartoolkit.core.squaredetect.*;
260 import org.libspark.flartoolkit.core.transmat.*;
261 import org.libspark.flartoolkit.core.raster.*;
262 import org.libspark.flartoolkit.core.raster.rgb.*;
263 import org.libspark.flartoolkit.core.*;
264 import org.libspark.flartoolkit.core.types.*;
265 import org.libspark.flartoolkit.*;
266 import org.libspark.flartoolkit.core.squaredetect.*;
267
268 /**
269  * detectMarkerのコールバック関数
270  */
271 class DetectSquare extends FLARSquareContourDetector_FlaFill implements FLARSquareContourDetector_CbHandler
272 {
273         //公開プロパティ
274         public var square:FLARSquare=new FLARSquare();
275         public var confidence:Number=0.0;
276         public var code_index:int=-1;           
277         public var cf_threshold_new:Number = 0.50;
278         public var cf_threshold_exist:Number = 0.30;
279        
280         //参照
281         private var _ref_raster:IFLARRgbRaster;
282         //所有インスタンス
283         private var _inst_patt:IFLARColorPatt;
284         private var _deviation_data:FLARMatchPattDeviationColorData;
285         private var _match_patt:Vector.<FLARMatchPatt_Color_WITHOUT_PCA>;
286         private var __detectMarkerLite_mr:FLARMatchPattResult=new FLARMatchPattResult();
287         private var _coordline:FLARCoord2Linear;
288         public function DetectSquare(i_param:FLARParam)
289         {
290                 super(i_param.getScreenSize());
291                 this._match_patt = null;
292                 this._coordline=new FLARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
293                 return;
294         }
295         public function setFLARCodeTable(i_ref_code:Vector.<FLARCode>,i_code_resolution:int):void
296         {
297                 /*unmanagedで実装するときは、ここでリソース解放をすること。*/
298                 this._deviation_data=new FLARMatchPattDeviationColorData(i_code_resolution,i_code_resolution);
299                 this._inst_patt=new FLARColorPatt_Perspective(i_code_resolution,i_code_resolution,4,25);
300                 this._match_patt = new Vector.<FLARMatchPatt_Color_WITHOUT_PCA>(i_ref_code.length);
301                 for(var i:int=0;i<i_ref_code.length;i++){
302                         this._match_patt[i]=new FLARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);
303                 }
304         }
305         private var __ref_vertex:Vector.<FLARIntPoint2d>=FLARIntPoint2d.createArray(4);
306         private var _target_id:int;
307
308         /**
309          * Initialize call back handler.
310          */
311         public function init(i_raster:IFLARRgbRaster,i_target_id:int):void
312         {
313                 this._ref_raster = i_raster;
314                 this._target_id=i_target_id;
315                 this.code_index=-1;
316                 this.confidence = Number.MIN_VALUE;
317         }
318
319         /**
320          * 矩形が見付かるたびに呼び出されます。
321          * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
322          */
323         public function detectMarkerCallback(i_coord:FLARIntCoordinates,i_vertex_index:Vector.<int>):void
324         {
325                 if (this._match_patt==null) {
326                         return;
327                 }
328                 //輪郭座標から頂点リストに変換
329                 var vertex:Vector.<FLARIntPoint2d>=this.__ref_vertex;
330                 vertex[0]=i_coord.items[i_vertex_index[0]];
331                 vertex[1]=i_coord.items[i_vertex_index[1]];
332                 vertex[2]=i_coord.items[i_vertex_index[2]];
333                 vertex[2]=i_coord.items[i_vertex_index[3]];
334
335        
336                 //画像を取得
337                 if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){
338                         return;//取得失敗
339                 }
340                 //取得パターンをカラー差分データに変換して評価する。
341                 this._deviation_data.setRaster(this._inst_patt);
342
343                
344                 //code_index,dir,c1にデータを得る。
345                 var mr:FLARMatchPattResult=this.__detectMarkerLite_mr;
346                 var lcode_index:int = 0;
347                 var dir:int = 0;
348                 var c1:Number = 0;
349                 var i:int;
350                 for (i = 0; i < this._match_patt.length; i++) {
351                         this._match_patt[i].evaluate(this._deviation_data,mr);
352                         var c2:Number = mr.confidence;
353                         if (c1 < c2) {
354                                 lcode_index = i;
355                                 c1 = c2;
356                                 dir = mr.direction;
357                         }
358                 }
359                
360                 //認識処理
361                 if (this._target_id == -1) { // マーカ未認識
362                         //現在は未認識
363                         if (c1 < this.cf_threshold_new) {
364                                 return;
365                         }
366                         if (this.confidence > c1) {
367                                 // 一致度が低い。
368                                 return;
369                         }
370                         //認識しているマーカIDを保存
371                         this.code_index=lcode_index;
372                 }else{
373                         //現在はマーカ認識中                             
374                         // 現在のマーカを認識したか?
375                         if (lcode_index != this._target_id) {
376                                 // 認識中のマーカではないので無視
377                                 return;
378                         }
379                         //認識中の閾値より大きいか?
380                         if (c1 < this.cf_threshold_exist) {
381                                 return;
382                         }
383                         //現在の候補よりも一致度は大きいか?
384                         if (this.confidence>c1) {
385                                 return;
386                         }
387                         this.code_index=this._target_id;
388                 }
389                 //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。
390                 //ココから先はこの条件でしか実行されない。
391                
392                 //一致率の高い矩形があれば、方位を考慮して頂点情報を作成
393                 this.confidence=c1;
394                 var sq:FLARSquare=this.square;
395                 //directionを考慮して、squareを更新する。
396                 for(i=0;i<4;i++){
397                         var idx:int=(i+4 - dir) % 4;
398                         this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]);
399                 }
400                 for (i = 0; i < 4; i++) {
401                         //直線同士の交点計算
402                         if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){
403                                 throw new FLARException();//ここのエラー復帰するならダブルバッファにすればOK
404                         }
405                 }
406         }
407 }       
408        
409        
410        
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。