Beispiel #1
0
        /**
         * 予想位置を基準に四角形をトレースして、一定の基準をクリアするかを評価します。
         * @param i_reader
         * @param i_edge_size
         * @param i_prevsq
         * @return
         * @throws NyARException
         */
        private bool traceSquareLine(INyARVectorReader i_reader, int i_edge_size, NyARRectTargetStatus i_prevsq, NyARLinear[] o_line)
        {
            NyARDoublePoint2d    p1, p2;
            VecLinearCoordinates vecpos = this._ref_my_pool._vecpos;

            //NyARIntRect i_rect
            p1 = i_prevsq.estimate_vertex[0];
            int dist_limit = i_edge_size * i_edge_size;

            //強度敷居値(セルサイズ-1)
            //		int min_th=i_edge_size*2+1;
            //		min_th=(min_th*min_th);
            for (int i = 0; i < 4; i++)
            {
                p2 = i_prevsq.estimate_vertex[(i + 1) % 4];

                //クリップ付きで予想位置周辺の直線のトレース
                i_reader.traceLineWithClip(p1, p2, i_edge_size, vecpos);

                //クラスタリングして、傾きの近いベクトルを探す。(限界は10度)
                this._ref_my_pool._vecpos_op.margeResembleCoords(vecpos);
                //基本的には1番でかいベクトルだよね。だって、直線状に取るんだもの。

                int vid = vecpos.getMaxCoordIndex();
                //データ品質規制(強度が多少強くないと。)
                //			if(vecpos.items[vid].sq_dist<(min_th)){
                //				return false;
                //			}
                //@todo:パラメタ調整
                //角度規制(元の線分との角度を確認)
                if (vecpos.items[vid].getAbsVecCos(i_prevsq.vertex[i], i_prevsq.vertex[(i + 1) % 4]) < NyARMath.COS_DEG_5)
                {
                    //System.out.println("CODE1");
                    return(false);
                }
                //@todo:パラメタ調整
                //予想点からさほど外れていない点であるか。(検出点の移動距離を計算する。)
                double dist;
                dist = vecpos.items[vid].sqDistBySegmentLineEdge(i_prevsq.vertex[i], i_prevsq.vertex[i]);
                if (dist < dist_limit)
                {
                    o_line[i].setVectorWithNormalize(vecpos.items[vid]);
                }
                else
                {
                    //System.out.println("CODE2:"+dist+","+dist_limit);
                    return(false);
                }
                //頂点ポインタの移動
                p1 = p2;
            }
            return(true);
        }
Beispiel #2
0
        /**
         * 状況に応じて矩形選択手法を切り替えます。
         * @param i_vec_reader
         * サンプリングデータの基本画像にリンクしたVectorReader
         * @param i_source
         * サンプリングデータ
         * @param i_prev_status
         * 前回の状態を格納したオブジェクト
         * @return
         * @throws NyARException
         */
        public bool setValueByAutoSelect(INyARVectorReader i_vec_reader, LowResolutionLabelingSamplerOut.Item i_source, NyARRectTargetStatus i_prev_status)
        {
            int current_detect_type = DT_SQDAILY;
            //移動速度による手段の切り替え
            int sq_v_ave_limit = i_prev_status.estimate_sum_sq_vertex_velocity_ave / 4;

            //速度が小さい時か、前回LineLogが成功したときはDT_LIDAILY
            if (((sq_v_ave_limit < 10) && (i_prev_status.detect_type == DT_SQDAILY)) || (i_prev_status.detect_type == DT_LIDAILY))
            {
                current_detect_type = DT_LIDAILY;
            }

            //前回の動作ログによる手段の切り替え
            switch (current_detect_type)
            {
            case DT_LIDAILY:
                //LineLog->
                if (setValueByLineLog(i_vec_reader, i_prev_status))
                {
                    //うまくいった。
                    this.detect_type = DT_LIDAILY;
                    return(true);
                }
                if (i_source != null)
                {
                    if (setValueWithDeilyCheck(i_vec_reader, i_source, i_prev_status))
                    {
                        //うまくいった
                        this.detect_type = DT_SQDAILY;
                        return(true);
                    }
                }
                break;

            case DT_SQDAILY:
                if (i_source != null)
                {
                    if (setValueWithDeilyCheck(i_vec_reader, i_source, i_prev_status))
                    {
                        this.detect_type = DT_SQDAILY;
                        return(true);
                    }
                }
                break;

            default:
                break;
            }
            //前回の動作ログを書き換え
            i_prev_status.detect_type = DT_FAILED;
            return(false);
        }
Beispiel #3
0
        /**
         * 輪郭からの単独検出
         * @param i_raster
         * @param i_prev_status
         * @return
         * @throws NyARException
         */
        public bool setValueByLineLog(INyARVectorReader i_vec_reader, NyARRectTargetStatus i_prev_status)
        {
            //検出範囲からカーネルサイズの2乗値を計算。検出領域の二乗距離の1/(40*40) (元距離の1/40)
            int d = ((int)i_prev_status.estimate_rect.getDiagonalSqDist() / (NyARMath.SQ_40));
            //二乗移動速度からカーネルサイズを計算。
            int v_ave_limit = i_prev_status.estimate_sum_sq_vertex_velocity_ave;

            //
            if (v_ave_limit > d)
            {
                //移動カーネルサイズより、検出範囲カーネルのほうが大きかったらエラー(動きすぎ)
                return(false);
            }
            d = (int)Math.Sqrt(d);
            //最低でも2だよね。
            if (d < 2)
            {
                d = 2;
            }
            //最大カーネルサイズ(5)を超える場合は5にする。
            if (d > 5)
            {
                d = 5;
            }

            //ライントレースの試行

            NyARLinear[] sh_l = this._ref_my_pool._line;
            if (!traceSquareLine(i_vec_reader, d, i_prev_status, sh_l))
            {
                return(false);
            }
            else
            {
            }
            //4点抽出
            for (int i = 3; i >= 0; i--)
            {
                if (!sh_l[i].crossPos(sh_l[(i + 3) % 4], this.vertex[i]))
                {
                    //四角が作れない。
                    return(false);
                }
            }

            //頂点並び順の調整
            rotateVertexL(this.vertex, checkVertexShiftValue(i_prev_status.vertex, this.vertex));
            //差分パラメータのセット
            setEstimateParam(i_prev_status);
            return(true);
        }
Beispiel #4
0
        /**
         * i_new_targetのアップグレードを試行します。
         * アップグレードの種類は以下のにとおりです。1.一定期間経過後の破棄ルート(Ignoreへ遷移)2.正常認識ルート(Contourへ遷移)
         * @param i_new_target
         * @param i_base_raster
         * @return
         * @throws NyARException
         */
        private void upgradeNewTarget(NyARTarget i_new_target, INyARVectorReader i_vecreader)
        {
            Debug.Assert(i_new_target._st_type == NyARTargetStatus.ST_NEW);

            //寿命を超えたらignoreへ遷移
            if (i_new_target._status_life <= 0)
            {
                this.changeStatusToIgnore(i_new_target, LIFE_OF_IGNORE_FROM_NEW);
                return;
            }
            NyARNewTargetStatus st = (NyARNewTargetStatus)i_new_target._ref_status;

            //このターゲットをアップグレードできるか確認
            if (st.current_sampleout == null)
            {
                //直近のsampleoutが無い。->なにもできない。
                return;
            }
            //coordステータスを生成
            NyARContourTargetStatus c = this.contourst_pool.newObject();

            if (c == null)
            {
                //ターゲットがいっぱい。(失敗して何もしない)
//			    System.out.println("upgradeNewTarget:status pool full");
                return;
            }
            //ステータスの値をセット
            if (!c.setValue(i_vecreader, st.current_sampleout))
            {
                //値のセットに失敗したので、Ignoreへ遷移(この対象は輪郭認識できない)
                this.changeStatusToIgnore(i_new_target, LIFE_OF_IGNORE_FROM_NEW);
                //System.out.println("drop:new->ignore[contoure failed.]"+t.serial+":"+t.last_update);
                c.releaseObject();
                return;            //失敗しようが成功しようが終了
            }
            if (this.changeStatusToCntoure(i_new_target, c) == null)
            {
                c.releaseObject();
                return;
            }
            return;
        }
Beispiel #5
0
        /**
         * ContoureTargetのステータスを更新します。
         * @param i_list
         * @param i_vecreader
         * @param i_stpool
         * @param source
         * @param index
         * @throws NyARException
         */
        public static void updateContureStatus(NyARTargetList i_list, INyARVectorReader i_vecreader, NyARContourTargetStatusPool i_stpool, LowResolutionLabelingSamplerOut.Item[] source, int[] index)
        {
            NyARTarget[] crd = i_list.getArray();
            NyARTarget   d_ptr;

            //ターゲットの更新
            for (int i = i_list.getLength() - 1; i >= 0; i--)
            {
                d_ptr = crd[i];
                int sample_index = index[i];
                //年齢を加算
                d_ptr._status_life--;
                if (sample_index < 0)
                {
                    //このターゲットに合致するアイテムは無い。
                    d_ptr._delay_tick++;
                    continue;
                }
                LowResolutionLabelingSamplerOut.Item s = source[sample_index];
                //失敗の可能性を考慮して、Statusを先に生成しておく
                NyARContourTargetStatus st = i_stpool.newObject();
                if (st == null)
                {
                    //失敗(作れなかった?)
                    d_ptr._delay_tick++;
                    continue;
                }
                if (!st.setValue(i_vecreader, s))
                {
                    //新しいステータスのセットに失敗?
                    st.releaseObject();
                    d_ptr._delay_tick++;
                    continue;
                }
                d_ptr.setSampleArea(s);
                d_ptr._delay_tick = 0;
                //ref_statusの切り替え
                d_ptr._ref_status.releaseObject();
                d_ptr._ref_status = st;
            }
        }
Beispiel #6
0
        public static void updateRectStatus(NyARTargetList i_list, INyARVectorReader i_vecreader, NyARRectTargetStatusPool i_stpool, LowResolutionLabelingSamplerOut.Item[] source, int[] index)
        {
            NyARTarget[] rct = i_list.getArray();
            NyARTarget   d_ptr;

            //ターゲットの更新
            for (int i = i_list.getLength() - 1; i >= 0; i--)
            {
                d_ptr = rct[i];
                //年齢を加算
                d_ptr._status_life--;
                //新しいステータスの作成
                NyARRectTargetStatus st = i_stpool.newObject();
                if (st == null)
                {
                    //失敗(作れなかった?)
                    d_ptr._delay_tick++;
                    continue;
                }
                int sample_index = index[i];
                LowResolutionLabelingSamplerOut.Item s = sample_index < 0?null:source[sample_index];
                if (!st.setValueByAutoSelect(i_vecreader, s, (NyARRectTargetStatus)d_ptr._ref_status))
                {
                    st.releaseObject();
                    d_ptr._delay_tick++;
                    continue;
                }
                else
                {
                    if (s != null)
                    {
                        d_ptr.setSampleArea(s);
                    }
                }
                d_ptr._ref_status.releaseObject();
                d_ptr._ref_status = st;
                d_ptr._delay_tick = 0;
            }
        }
Beispiel #7
0
        /**
         * 値をセットします。この関数は、処理の成功失敗に関わらず、内容変更を行います。
         * @param i_sampler_in
         * @param i_source
         * @param i_prev_status
         * @return
         * @throws NyARException
         */
        public bool setValueWithDeilyCheck(INyARVectorReader i_vec_reader, LowResolutionLabelingSamplerOut.Item i_source, NyARRectTargetStatus i_prev_status)
        {
            VecLinearCoordinates vecpos = this._ref_my_pool._vecpos;

            //輪郭線を取る
            if (!i_vec_reader.traceConture(i_source.lebeling_th, i_source.entry_pos, vecpos))
            {
                return(false);
            }
            //3,4象限方向のベクトルは1,2象限のベクトルに変換する。
            vecpos.limitQuadrantTo12();
            //ベクトルのマージ
            this._ref_my_pool._vecpos_op.margeResembleCoords(vecpos);
            if (vecpos.length < 4)
            {
                return(false);
            }
            //キーベクトルを取得
            vecpos.getKeyCoord(this._ref_my_pool._indexbuf);
            //点に変換
            NyARDoublePoint2d[] this_vx = this.vertex;
            if (!this._ref_my_pool._line_detect.line2SquareVertex(this._ref_my_pool._indexbuf, this_vx))
            {
                return(false);
            }
            //頂点並び順の調整
            rotateVertexL(this.vertex, checkVertexShiftValue(i_prev_status.vertex, this.vertex));

            //パラメタチェック
            if (!checkDeilyRectCondition(i_prev_status))
            {
                return(false);
            }
            //次回の予測
            setEstimateParam(i_prev_status);
            return(true);
        }
	    /**
	     * @param i_vecreader
	     * @param i_sample
	     * @return
	     * @throws NyARException
	     */
        public bool setValue(INyARVectorReader i_vecreader, LowResolutionLabelingSamplerOut.Item i_sample)
	    {
		    return i_vecreader.traceConture(i_sample.lebeling_th, i_sample.entry_pos, this.vecpos);
	    }	
Beispiel #9
0
        /**
         * Trackerの状態を更新します。
         * @param i_source
         * @throws NyARException
         */
        public void progress(NyARTrackerSource i_s)
        {
            //SampleOutを回収
            LowResolutionLabelingSamplerOut sample_out = i_s.makeSampleOut();

            NyARTargetList[] targets = this._temp_targets;
            NyARTargetList   newtr   = targets[NyARTargetStatus.ST_NEW];
            NyARTargetList   igtr    = targets[NyARTargetStatus.ST_IGNORE];
            NyARTargetList   cotr    = targets[NyARTargetStatus.ST_CONTURE];
            NyARTargetList   retw    = targets[NyARTargetStatus.ST_RECT];

            INyARVectorReader vecreader = i_s.getBaseVectorReader();

            //ターゲットリストの振り分け
            NyARTarget[] target_array = this._targets.getArray();
            newtr.clear();
            igtr.clear();
            cotr.clear();
            retw.clear();
            for (int i = this._targets.getLength() - 1; i >= 0; i--)
            {
                targets[target_array[i]._st_type].pushAssert(target_array[i]);
            }
            int[] index = this._index;
            //サンプルをターゲット毎に振り分け
            sampleMapper(sample_out, newtr, igtr, cotr, retw, this._newsource, this._igsource, this._coordsource, this._rectsource);

            //ターゲットの更新
            this._map.makePairIndexes(this._igsource, igtr, index);
            updateIgnoreStatus(igtr, this._igsource.getArray(), index);

            this._map.makePairIndexes(this._newsource, newtr, index);
            updateNewStatus(newtr, this.newst_pool, this._newsource.getArray(), index);

            this._map.makePairIndexes(this._rectsource, retw, index);
            updateRectStatus(retw, vecreader, this.rect_pool, this._rectsource.getArray(), index);

            this._map.makePairIndexes(this._coordsource, cotr, index);
            updateContureStatus(cotr, vecreader, this.contourst_pool, this._coordsource.getArray(), index);

            //ターゲットのアップグレード
            for (int i = this._targets.getLength() - 1; i >= 0; i--)
            {
                switch (target_array[i]._st_type)
                {
                case NyARTargetStatus.ST_IGNORE:
                    upgradeIgnoreTarget(i);
                    continue;

                case NyARTargetStatus.ST_NEW:
                    upgradeNewTarget(target_array[i], vecreader);
                    continue;

                case NyARTargetStatus.ST_RECT:
                    upgradeRectTarget(target_array[i]);
                    continue;

                case NyARTargetStatus.ST_CONTURE:
                    upgradeContourTarget(target_array[i]);
                    continue;
                }
            }
            return;
        }
	    /**
	     * 予想位置を基準に四角形をトレースして、一定の基準をクリアするかを評価します。
	     * @param i_reader
	     * @param i_edge_size
	     * @param i_prevsq
	     * @return
	     * @throws NyARException
	     */
        private bool traceSquareLine(INyARVectorReader i_reader, int i_edge_size, NyARRectTargetStatus i_prevsq, NyARLinear[] o_line)
	    {
		    NyARDoublePoint2d p1,p2;
		    VecLinearCoordinates vecpos=this._ref_my_pool._vecpos;
		    //NyARIntRect i_rect
		    p1=i_prevsq.estimate_vertex[0];
		    int dist_limit=i_edge_size*i_edge_size;
		    //強度敷居値(セルサイズ-1)
    //		int min_th=i_edge_size*2+1;
    //		min_th=(min_th*min_th);
		    for(int i=0;i<4;i++)
		    {
			    p2=i_prevsq.estimate_vertex[(i+1)%4];
    			
			    //クリップ付きで予想位置周辺の直線のトレース
			    i_reader.traceLineWithClip(p1,p2,i_edge_size,vecpos);

			    //クラスタリングして、傾きの近いベクトルを探す。(限界は10度)
			    this._ref_my_pool._vecpos_op.margeResembleCoords(vecpos);
			    //基本的には1番でかいベクトルだよね。だって、直線状に取るんだもの。

			    int vid=vecpos.getMaxCoordIndex();
			    //データ品質規制(強度が多少強くないと。)
    //			if(vecpos.items[vid].sq_dist<(min_th)){
    //				return false;
    //			}
    //@todo:パラメタ調整
			    //角度規制(元の線分との角度を確認)
			    if(vecpos.items[vid].getAbsVecCos(i_prevsq.vertex[i],i_prevsq.vertex[(i+1)%4])<NyARMath.COS_DEG_5){
				    //System.out.println("CODE1");
				    return false;
			    }
    //@todo:パラメタ調整
			    //予想点からさほど外れていない点であるか。(検出点の移動距離を計算する。)
			    double dist;
			    dist=vecpos.items[vid].sqDistBySegmentLineEdge(i_prevsq.vertex[i],i_prevsq.vertex[i]);
			    if(dist<dist_limit){
				    o_line[i].setVectorWithNormalize(vecpos.items[vid]);
			    }else{
				    //System.out.println("CODE2:"+dist+","+dist_limit);
				    return false;
			    }
			    //頂点ポインタの移動
			    p1=p2;
		    }
		    return true;
	    }
	    /**
	     * 状況に応じて矩形選択手法を切り替えます。
	     * @param i_vec_reader
	     * サンプリングデータの基本画像にリンクしたVectorReader
	     * @param i_source
	     * サンプリングデータ
	     * @param i_prev_status
	     * 前回の状態を格納したオブジェクト
	     * @return
	     * @throws NyARException
	     */
        public bool setValueByAutoSelect(INyARVectorReader i_vec_reader, LowResolutionLabelingSamplerOut.Item i_source, NyARRectTargetStatus i_prev_status)
	    {
		    int current_detect_type=DT_SQDAILY;
		    //移動速度による手段の切り替え
		    int sq_v_ave_limit=i_prev_status.estimate_sum_sq_vertex_velocity_ave/4;
		    //速度が小さい時か、前回LineLogが成功したときはDT_LIDAILY
		    if(((sq_v_ave_limit<10) && (i_prev_status.detect_type==DT_SQDAILY)) || (i_prev_status.detect_type==DT_LIDAILY)){
			    current_detect_type=DT_LIDAILY;
		    }
    		
		    //前回の動作ログによる手段の切り替え
		    switch(current_detect_type)
		    {
		    case DT_LIDAILY:
			    //LineLog->
			    if(setValueByLineLog(i_vec_reader,i_prev_status))
			    {
				    //うまくいった。
				    this.detect_type=DT_LIDAILY;
				    return true;
			    }
			    if(i_source!=null){
				    if(setValueWithDeilyCheck(i_vec_reader,i_source,i_prev_status))
				    {
					    //うまくいった
					    this.detect_type=DT_SQDAILY;
					    return true;
				    }
			    }
			    break;
		    case DT_SQDAILY:
			    if(i_source!=null){
				    if(setValueWithDeilyCheck(i_vec_reader,i_source,i_prev_status))
				    {
					    this.detect_type=DT_SQDAILY;
					    return true;
				    }
			    }
			    break;
		    default:
			    break;
		    }
		    //前回の動作ログを書き換え
		    i_prev_status.detect_type=DT_FAILED;
		    return false;
	    }
	    /**
	     * 輪郭からの単独検出
	     * @param i_raster
	     * @param i_prev_status
	     * @return
	     * @throws NyARException
	     */
        public bool setValueByLineLog(INyARVectorReader i_vec_reader, NyARRectTargetStatus i_prev_status)
	    {
		    //検出範囲からカーネルサイズの2乗値を計算。検出領域の二乗距離の1/(40*40) (元距離の1/40)
		    int d=((int)i_prev_status.estimate_rect.getDiagonalSqDist()/(NyARMath.SQ_40));
		    //二乗移動速度からカーネルサイズを計算。
		    int v_ave_limit=i_prev_status.estimate_sum_sq_vertex_velocity_ave;
		    //
		    if(v_ave_limit>d){
			    //移動カーネルサイズより、検出範囲カーネルのほうが大きかったらエラー(動きすぎ)
			    return false;
		    }
		    d=(int)Math.Sqrt(d);
		    //最低でも2だよね。
		    if(d<2){
			    d=2;
		    }
		    //最大カーネルサイズ(5)を超える場合は5にする。
		    if(d>5){
			    d=5;
		    }
    		
		    //ライントレースの試行

		    NyARLinear[] sh_l=this._ref_my_pool._line;
		    if(!traceSquareLine(i_vec_reader,d,i_prev_status,sh_l)){
			    return false;
		    }else{
		    }
		    //4点抽出
		    for(int i=3;i>=0;i--){
			    if(!sh_l[i].crossPos(sh_l[(i + 3) % 4],this.vertex[i])){
				    //四角が作れない。
				    return false;
			    }
		    }		

		    //頂点並び順の調整
		    rotateVertexL(this.vertex,checkVertexShiftValue(i_prev_status.vertex,this.vertex));	
		    //差分パラメータのセット
		    setEstimateParam(i_prev_status);
		    return true;
	    }
	    /**
	     * 値をセットします。この関数は、処理の成功失敗に関わらず、内容変更を行います。
	     * @param i_sampler_in
	     * @param i_source
	     * @param i_prev_status
	     * @return
	     * @throws NyARException
	     */
        public bool setValueWithDeilyCheck(INyARVectorReader i_vec_reader, LowResolutionLabelingSamplerOut.Item i_source, NyARRectTargetStatus i_prev_status)
	    {
		    VecLinearCoordinates vecpos=this._ref_my_pool._vecpos;
		    //輪郭線を取る
		    if(!i_vec_reader.traceConture(i_source.lebeling_th,i_source.entry_pos,vecpos)){
			    return false;
		    }
		    //3,4象限方向のベクトルは1,2象限のベクトルに変換する。
		    vecpos.limitQuadrantTo12();
		    //ベクトルのマージ
		    this._ref_my_pool._vecpos_op.margeResembleCoords(vecpos);
		    if(vecpos.length<4){
			    return false;
		    }
		    //キーベクトルを取得
		    vecpos.getKeyCoord(this._ref_my_pool._indexbuf);
		    //点に変換
		    NyARDoublePoint2d[] this_vx=this.vertex;
		    if(!this._ref_my_pool._line_detect.line2SquareVertex(this._ref_my_pool._indexbuf,this_vx)){
			    return false;
		    }
		    //頂点並び順の調整
		    rotateVertexL(this.vertex,checkVertexShiftValue(i_prev_status.vertex,this.vertex));	

		    //パラメタチェック
		    if(!checkDeilyRectCondition(i_prev_status)){
			    return false;
		    }
		    //次回の予測
		    setEstimateParam(i_prev_status);
		    return true;
	    }
 /**
  * @param i_vecreader
  * @param i_sample
  * @return
  * @throws NyARException
  */
 public bool setValue(INyARVectorReader i_vecreader, LowResolutionLabelingSamplerOut.Item i_sample)
 {
     return(i_vecreader.traceConture(i_sample.lebeling_th, i_sample.entry_pos, this.vecpos));
 }