X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=lib%2Fsrc%2Fjp%2Fnyatla%2Fnyartoolkit%2Fdetector%2FNyARDetectMarker.java;fp=lib%2Fsrc%2Fjp%2Fnyatla%2Fnyartoolkit%2Fdetector%2FNyARDetectMarker.java;h=0743ac082c6ad0f3137a3e59a3d7098c594f6fd1;hb=67cb5162524c344149f566c3a4b839275445046c;hp=0000000000000000000000000000000000000000;hpb=23b3fefd13f932c92ce6e9c73f6c5b28007243e2;p=nyartoolkit-and%2Fnyartoolkit-and.git diff --git a/lib/src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java b/lib/src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java new file mode 100644 index 0000000..0743ac0 --- /dev/null +++ b/lib/src/jp/nyatla/nyartoolkit/detector/NyARDetectMarker.java @@ -0,0 +1,324 @@ +/* + * PROJECT: NyARToolkit + * -------------------------------------------------------------------------------- + * This work is based on the original ARToolKit developed by + * Hirokazu Kato + * Mark Billinghurst + * HITLab, University of Washington, Seattle + * http://www.hitl.washington.edu/artoolkit/ + * + * The NyARToolkit is Java edition ARToolKit class library. + * Copyright (C)2008-2009 Ryo Iizuka + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * For further information please contact. + * http://nyatla.jp/nyatoolkit/ + * or + * + */ +package jp.nyatla.nyartoolkit.detector; + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.*; +import jp.nyatla.nyartoolkit.core.match.*; +import jp.nyatla.nyartoolkit.core.param.NyARParam; +import jp.nyatla.nyartoolkit.core.pickup.*; +import jp.nyatla.nyartoolkit.core.raster.*; +import jp.nyatla.nyartoolkit.core.raster.rgb.*; +import jp.nyatla.nyartoolkit.core.transmat.*; +import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARCoord2Linear; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare; +import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareContourDetector_Rle; +import jp.nyatla.nyartoolkit.core.types.*; +import jp.nyatla.nyartoolkit.core.types.stack.NyARObjectStack; + + + + + +/** + * 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。 + * + */ +public class NyARDetectMarker +{ + private class RleDetector extends NyARSquareContourDetector_Rle + { + //公開プロパティ + public NyARDetectMarkerResultStack result_stack=new NyARDetectMarkerResultStack(NyARDetectMarker.AR_SQUARE_MAX); + //参照インスタンス + public INyARRgbRaster _ref_raster; + //所有インスタンス + private INyARColorPatt _inst_patt; + private NyARMatchPattDeviationColorData _deviation_data; + private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt; + private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult(); + private NyARCoord2Linear _coordline; + + public RleDetector(INyARColorPatt i_inst_patt,NyARCode[] i_ref_code,int i_num_of_code,NyARParam i_param) throws NyARException + { + super(i_param.getScreenSize()); + final int cw = i_ref_code[0].getWidth(); + final int ch = i_ref_code[0].getHeight(); + //NyARMatchPatt_Color_WITHOUT_PCA[]の作成 + this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA[i_num_of_code]; + this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]); + for (int i = 1; i < i_num_of_code; i++){ + //解像度チェック + if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) { + throw new NyARException(); + } + this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]); + } + this._inst_patt=i_inst_patt; + this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor()); + this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch); + return; + } + private NyARIntPoint2d[] __ref_vertex=new NyARIntPoint2d[4]; + /** + * 矩形が見付かるたびに呼び出されます。 + * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。 + */ + protected void onSquareDetect(NyARIntCoordinates i_coord,int[] i_vertex_index) throws NyARException + { + NyARMatchPattResult mr=this.__detectMarkerLite_mr; + //輪郭座標から頂点リストに変換 + NyARIntPoint2d[] vertex=this.__ref_vertex; + vertex[0]=i_coord.items[i_vertex_index[0]]; + vertex[1]=i_coord.items[i_vertex_index[1]]; + vertex[2]=i_coord.items[i_vertex_index[2]]; + vertex[3]=i_coord.items[i_vertex_index[3]]; + + //画像を取得 + if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){ + return; + } + //取得パターンをカラー差分データに変換して評価する。 + this._deviation_data.setRaster(this._inst_patt); + + //最も一致するパターンを割り当てる。 + int square_index,direction; + double confidence; + this._match_patt[0].evaluate(this._deviation_data,mr); + square_index=0; + direction=mr.direction; + confidence=mr.confidence; + //2番目以降 + for(int i=1;i mr.confidence) { + continue; + } + // もっと一致するマーカーがあったぽい + square_index = i; + direction = mr.direction; + confidence = mr.confidence; + } + //最も一致したマーカ情報を、この矩形の情報として記録する。 + final NyARDetectMarkerResult result = this.result_stack.prePush(); + result.arcode_id = square_index; + result.confidence = confidence; + + final NyARSquare sq=result.square; + //directionを考慮して、squareを更新する。 + for(int i=0;i<4;i++){ + int idx=(i+4 - direction) % 4; + this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coord,sq.line[i]); + } + for (int i = 0; i < 4; i++) { + //直線同士の交点計算 + if(!sq.line[i].crossPos(sq.line[(i + 3) % 4],sq.sqvertex[i])){ + throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK + } + } + } + public void init(INyARRgbRaster i_raster) + { + this._ref_raster=i_raster; + this.result_stack.clear(); + + } + } + private static final int AR_SQUARE_MAX = 300; + private boolean _is_continue = false; + private RleDetector _square_detect; + protected INyARTransMat _transmat; + private NyARRectOffset[] _offset; + + + /** + * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。 + * + * @param i_param + * カメラパラメータを指定します。 + * @param i_code + * 検出するマーカーのARCode配列を指定します。 + * 配列要素のインデックス番号が、そのままgetARCodeIndex関数で得られるARCodeインデックスになります。 + * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。 + * @param i_marker_width + * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。 + * @param i_number_of_code + * i_codeに含まれる、ARCodeの数を指定します。 + * @param i_input_raster_type + * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。 + * @throws NyARException + */ + public NyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width, int i_number_of_code,int i_input_raster_type) throws NyARException + { + initInstance(i_param,i_code,i_marker_width,i_number_of_code,i_input_raster_type); + return; + } + protected void initInstance( + NyARParam i_ref_param, + NyARCode[] i_ref_code, + double[] i_marker_width, + int i_number_of_code, + int i_input_raster_type) throws NyARException + { + + final NyARIntSize scr_size=i_ref_param.getScreenSize(); + // 解析オブジェクトを作る + final int cw = i_ref_code[0].getWidth(); + final int ch = i_ref_code[0].getHeight(); + + this._transmat = new NyARTransMat(i_ref_param); + //NyARToolkitプロファイル + this._square_detect =new RleDetector(new NyARColorPatt_Perspective_O2(cw, ch,4,25,i_input_raster_type),i_ref_code,i_number_of_code,i_ref_param); + this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type); + + //実サイズ保存 + this._offset = NyARRectOffset.createArray(i_number_of_code); + for(int i=0;i +{ + public NyARDetectMarkerResultStack(int i_length) throws NyARException + { + super(); + this.initInstance(i_length,NyARDetectMarkerResult.class); + return; + } + protected NyARDetectMarkerResult createElement() + { + return new NyARDetectMarkerResult(); + } +} \ No newline at end of file