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

リビジョン 4718, 12.2 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 flash.display.*;
32         import org.libspark.flartoolkit.core.param.*;
33         import org.libspark.flartoolkit.core.match.*;
34         import org.libspark.flartoolkit.core.pickup.*;
35         import org.libspark.flartoolkit.core.squaredetect.*;
36         import org.libspark.flartoolkit.core.transmat.*;
37         import org.libspark.flartoolkit.core.raster.*;
38         import org.libspark.flartoolkit.core.rasterfilter.rgb2gs.*;
39         import org.libspark.flartoolkit.core.raster.rgb.*;
40         import org.libspark.flartoolkit.core.*;
41         import org.libspark.flartoolkit.core.types.*;
42         import org.libspark.flartoolkit.nyidmarker.data.*;
43         import org.libspark.flartoolkit.nyidmarker.*;
44         import jp.nyatla.as3utils.*;
45         import org.libspark.flartoolkit.core.squaredetect.*;
46         import org.libspark.flartoolkit.core.raster.*;
47         import org.libspark.flartoolkit.core.analyzer.histogram.*;
48         import org.libspark.flartoolkit.core.rasterdriver.*;
49         import org.libspark.flartoolkit.core.rasterfilter.* ;
50         public class FLSingleNyIdMarkerProcesser
51         {
52                 public var tag:Object;
53
54                 /**
55                  * ロスト遅延の管理
56                  */
57                 private var _lost_delay_count:int = 0;
58                 private var _lost_delay:int = 5;
59
60                 private var _square_detect:FLDetector;
61                 protected var _transmat:IFLARTransMat;
62                 private var _offset:FLARRectOffset;
63                 private var _is_active:Boolean;
64                 private var _current_threshold:int=110;
65                 // [AR]検出結果の保存用
66                 private var _bin_raster:FLARBinRaster;
67                 private var _gs_raster:FLARGrayscaleRaster;
68                 private var _data_current:INyIdMarkerData;
69                 private var _threshold_detect:FLARHistogramAnalyzer_SlidePTile;
70                 private var _hist:FLARHistogram=new FLARHistogram(256);
71                 private var _histmaker:IFLARHistogramFromRaster;
72
73                 public function FLSingleNyIdMarkerProcesser()
74                 {
75                         return;
76                 }
77                 private var _initialized:Boolean=false;
78                 protected function initInstance(i_param:FLARParam, i_encoder:INyIdMarkerDataEncoder ,i_marker_width:Number):void
79                 {
80                         //初期化済?
81                         NyAS3Utils.assert(this._initialized==false);
82                        
83                         var scr_size:FLARIntSize  = i_param.getScreenSize();
84                         // 解析オブジェクトを作る
85                         this._square_detect = new FLDetector(
86                                 i_param,
87                                 i_encoder);
88                         this._transmat = new FLARTransMat(i_param);
89
90                         // 2値画像バッファを作る
91                         this._gs_raster = new FLARGrayscaleRaster(scr_size.w, scr_size.h,FLARBufferType.OBJECT_AS3_BitmapData,true);
92                         this._bin_raster = new FLARBinRaster(scr_size.w, scr_size.h);
93                         this._histmaker=IFLARHistogramFromRaster(this._gs_raster.createInterface(IFLARHistogramFromRaster));
94                         //ワーク用のデータオブジェクトを2個作る
95                         this._data_current=i_encoder.createDataInstance();
96                         this._threshold_detect=new FLARHistogramAnalyzer_SlidePTile(15);
97                         this._initialized=true;
98                         this._is_active=false;
99                         this._offset=new FLARRectOffset();
100                         this._offset.setSquare(i_marker_width);
101                         return;                 
102                 }
103
104                 public function setMarkerWidth(i_width:int):void
105                 {
106                         this._offset.setSquare(i_width);
107                         return;
108                 }
109
110                 public function reset(i_is_force:Boolean):void
111                 {
112                         if (i_is_force == false && this._is_active){
113                                 // 強制書き換えでなければイベントコール
114                                 this.onLeaveHandler();
115                         }
116                         //マーカ無効
117                         this._is_active=false;
118                         return;
119                 }
120                 private var _last_input_raster:IFLARRgbRaster;
121                 private var _togs_filter:FLARRgb2GsFilter;
122                 private var _tobin_filter:FLARGs2BinFilter;
123
124                 public function detectMarker(i_raster:IFLARRgbRaster):void
125                 {
126                         // サイズチェック
127                         if (!this._gs_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h)) {
128                                 throw new FLARException();
129                         }
130                         // ラスタをGSへ変換する。
131                         if(this._last_input_raster!=i_raster){
132                                 this._togs_filter = FLARRgb2GsFilter(i_raster.createInterface(FLARRgb2GsFilter));
133                                 this._tobin_filter = FLARGs2BinFilter(this._gs_raster.createInterface(FLARGs2BinFilter));
134                                 this._last_input_raster=i_raster;
135                         }
136                         this._togs_filter.convert(this._gs_raster);
137                         this._tobin_filter.convert(this._current_threshold,this._bin_raster);
138
139                         // スクエアコードを探す(第二引数に指定したマーカ、もしくは新しいマーカを探す。)
140                         this._square_detect.init(this._gs_raster,this._is_active?this._data_current:null);
141                         this._square_detect.detectMarker(this._bin_raster,this._square_detect);
142
143                         // 認識状態を更新(マーカを発見したなら、current_dataを渡すかんじ)
144                         var is_id_found:Boolean=updateStatus(this._square_detect.square,this._square_detect.marker_data);
145
146                         //閾値フィードバック(detectExistMarkerにもあるよ)
147                         if(is_id_found){
148                                 //マーカがあれば、マーカの周辺閾値を反映
149                                 this._current_threshold=(this._current_threshold+this._square_detect.threshold)/2;
150                         }else{
151                                 //マーカがなければ、探索+DualPTailで基準輝度検索
152                                 this._histmaker.createHistogram_2(4,this._hist);
153                                 var th:int= this._threshold_detect.getThreshold(this._hist);
154                                 this._current_threshold=(this._current_threshold+th)/2;
155                         }
156                 }
157
158                
159                 private var __FLARSquare_result:FLARTransMatResult = new FLARTransMatResult();
160
161                 /**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。
162                  */
163                 private function updateStatus(i_square:FLARSquare,i_marker_data:INyIdMarkerData):Boolean
164                 {
165                         var is_id_found:Boolean=false;
166                         var result:FLARTransMatResult = this.__FLARSquare_result;
167                         if (!this._is_active) {// 未認識中
168                                 if (i_marker_data==null) {// 未認識から未認識の遷移
169                                         // なにもしないよーん。
170                                         this._is_active=false;
171                                 } else {// 未認識から認識の遷移
172                                         this._data_current.copyFrom(i_marker_data);
173                                         // イベント生成
174                                         // OnEnter
175                                         this.onEnterHandler(this._data_current);
176                                         // 変換行列を作成
177                                         this._transmat.transMat(i_square, this._offset, result);
178                                         // OnUpdate
179                                         this.onUpdateHandler(i_square, result);
180                                         this._lost_delay_count = 0;
181                                         this._is_active=true;
182                                         is_id_found=true;
183                                 }
184                         } else {// 認識中
185                                 if (i_marker_data==null) {
186                                         // 認識から未認識の遷移
187                                         this._lost_delay_count++;
188                                         if (this._lost_delay < this._lost_delay_count) {
189                                                 // OnLeave
190                                                 this.onLeaveHandler();
191                                                 this._is_active=false;
192                                         }
193                                 } else if(this._data_current.isEqual(i_marker_data)) {
194                                         //同じidの再認識
195                                         this._transmat.transMatContinue(i_square, this._offset, result,result);
196                                         // OnUpdate
197                                         this.onUpdateHandler(i_square, result);
198                                         this._lost_delay_count = 0;
199                                         is_id_found=true;
200                                 } else {// 異なるコードの認識→今はサポートしない。
201                                         throw new  FLARException();
202                                 }
203                         }
204                         return is_id_found;
205                 }       
206                 //通知ハンドラ
207                 protected function onEnterHandler(i_code:INyIdMarkerData):void
208                 {
209                         throw new FLARException("onEnterHandler not implemented.");
210                 }
211                 protected function onLeaveHandler():void
212                 {
213                         throw new FLARException("onLeaveHandler not implemented.");
214                 }
215                 protected function onUpdateHandler(i_square:FLARSquare, result:FLARTransMatResult):void
216                 {
217                         throw new FLARException("onUpdateHandler not implemented.");
218                 }
219         }
220 }
221 import org.libspark.flartoolkit.core.param.*;
222 import org.libspark.flartoolkit.core.match.*;
223 import org.libspark.flartoolkit.core.pickup.*;
224 import org.libspark.flartoolkit.core.squaredetect.*;
225 import org.libspark.flartoolkit.core.transmat.*;
226 import org.libspark.flartoolkit.core.raster.*;
227 import org.libspark.flartoolkit.core.raster.rgb.*;
228 import org.libspark.flartoolkit.core.*;
229 import org.libspark.flartoolkit.core.types.*;
230 import org.libspark.flartoolkit.*;
231 import org.libspark.flartoolkit.nyidmarker.data.*;
232 import org.libspark.flartoolkit.nyidmarker.*;
233 import org.libspark.flartoolkit.core.raster.*;
234 import org.libspark.flartoolkit.core.squaredetect.*;
235
236 /**
237  * detectMarkerのコールバック関数
238  */
239 class FLDetector extends FLARSquareContourDetector_FlaFill implements FLARSquareContourDetector_CbHandler
240 {
241         //公開プロパティ
242         public var square:FLARSquare=new FLARSquare();
243         public var marker_data:INyIdMarkerData;
244         public var threshold:int;
245
246        
247         //参照
248         private var _ref_gs_raster:FLARGrayscaleRaster;
249         //所有インスタンス
250         private var _current_data:INyIdMarkerData;
251         private var _id_pickup:NyIdMarkerPickup = new NyIdMarkerPickup();
252         private var _coordline:FLARCoord2Linear;
253         private var _encoder:INyIdMarkerDataEncoder;
254
255        
256         private var _data_temp:INyIdMarkerData;
257         private var _prev_data:INyIdMarkerData;
258        
259         public function FLDetector(i_param:FLARParam,i_encoder:INyIdMarkerDataEncoder)
260         {
261                 super(i_param.getScreenSize());
262                 this._coordline=new FLARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
263                 this._data_temp=i_encoder.createDataInstance();
264                 this._current_data=i_encoder.createDataInstance();
265                 this._encoder=i_encoder;
266                 return;
267         }
268         private var __ref_tmp_vertex:Vector.<FLARIntPoint2d>=FLARIntPoint2d.createArray(4);
269         /**
270          * Initialize call back handler.
271          */
272         public function init(i_gs_raster:FLARGrayscaleRaster,i_prev_data:INyIdMarkerData):void
273         {
274                 this.marker_data = null;
275                 this._ref_gs_raster = i_gs_raster;
276                 this._prev_data=i_prev_data;
277         }
278         private var _marker_param:NyIdMarkerParam=new NyIdMarkerParam();
279         private var _marker_data:NyIdMarkerPattern =new NyIdMarkerPattern();
280
281         /**
282          * 矩形が見付かるたびに呼び出されます。
283          * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
284          */
285         public function detectMarkerCallback(i_coord:FLARIntCoordinates,i_vertex_index:Vector.<int>):void
286         {
287                 //既に発見済なら終了
288                 if(this.marker_data!=null){
289                         return;
290                 }
291                 //輪郭座標から頂点リストに変換
292                 var vertex:Vector.<FLARIntPoint2d>=this.__ref_tmp_vertex;
293                 vertex[0]=i_coord.items[i_vertex_index[0]];
294                 vertex[1]=i_coord.items[i_vertex_index[1]];
295                 vertex[2]=i_coord.items[i_vertex_index[2]];
296                 vertex[3] = i_coord.items[i_vertex_index[3]];
297                
298                 var param:NyIdMarkerParam=this._marker_param;
299                 var patt_data:NyIdMarkerPattern=this._marker_data;                     
300                 // 評価基準になるパターンをイメージから切り出す
301                 if (!this._id_pickup.pickFromRaster_2(this._ref_gs_raster.getGsPixelDriver(),vertex, patt_data, param)){
302                         return;
303                 }
304                 //エンコード
305                 if(!this._encoder.encode(patt_data,this._data_temp)){
306                         return;
307                 }
308
309                 //継続認識要求されている?
310                 if (this._prev_data==null){
311                         //継続認識要求なし
312                         this._current_data.copyFrom(this._data_temp);
313                 }else{
314                         //継続認識要求あり
315                         if(!this._prev_data.isEqual((this._data_temp))){
316                                 return;//認識請求のあったIDと違う。
317                         }
318                 }
319                 //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。
320                 //ココから先はこの条件でしか実行されない。
321                 var sq:FLARSquare=this.square;
322                 //directionを考慮して、squareを更新する。
323                 var i:int;
324                 for(i=0;i<4;i++){
325                         var idx:int=(i+4 - param.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                 this.threshold=param.threshold;
335                 this.marker_data=this._current_data;//みつかった。
336         }
337 }               
338        
339        
340        
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。