Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        public bool traceConture(int i_th,
                                 NyARIntPoint2d i_entry, VecLinearCoordinates o_coord)
        {
            NyARIntCoordinates coord = this._coord_buf;

            // Robertsラスタから輪郭抽出
            if (!this._cpickup.getContour(this._ref_rob_raster, i_th, i_entry.x, i_entry.y,
                                          coord))
            {
                // 輪郭線MAXならなにもできないね。
                return(false);
            }
            // 輪郭線のベクトル化
            return(traceConture(coord, this._rob_resolution,
                                this._rob_resolution * 2, o_coord));
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        /**
         * クリッピング付きのライントレーサです。
         *
         * @param i_pos1
         * @param i_pos2
         * @param i_edge
         * @param o_coord
         * @return
         * @throws NyARException
         */
        public bool traceLineWithClip(NyARDoublePoint2d i_pos1,
                                      NyARDoublePoint2d i_pos2, int i_edge, VecLinearCoordinates o_coord)
        {
            NyARIntSize s = this._ref_base_raster.getSize();
            bool        is_p1_inside_area, is_p2_inside_area;

            NyARIntPoint2d[] pt = this.__pt;
            // 線分が範囲内にあるかを確認
            is_p1_inside_area = s.isInnerPoint(i_pos1);
            is_p2_inside_area = s.isInnerPoint(i_pos2);
            // 個数で分岐
            if (is_p1_inside_area && is_p2_inside_area)
            {
                // 2ならクリッピング必要なし。
                if (!this.traceLine(i_pos1, i_pos2, i_edge, o_coord))
                {
                    return(false);
                }
                return(true);
            }
            // 1,0個の場合は、線分を再定義
            if (!this.__temp_l.makeLinearWithNormalize(i_pos1, i_pos2))
            {
                return(false);
            }
            if (!this.__temp_l.makeSegmentLine(s.w, s.h, pt))
            {
                return(false);
            }
            if (is_p1_inside_area != is_p2_inside_area)
            {
                // 1ならクリッピング後に、外に出ていた点に近い輪郭交点を得る。

                if (is_p1_inside_area)
                {
                    // p2が範囲外
                    pt[(i_pos2.sqDist(pt[0]) < i_pos2.sqDist(pt[1])) ? 1 : 0].setValue(i_pos1);
                }
                else
                {
                    // p1が範囲外
                    pt[(i_pos1.sqDist(pt[0]) < i_pos2.sqDist(pt[1])) ? 1 : 0].setValue(i_pos2);
                }
            }
            else
            {
                // 0ならクリッピングして得られた2点を使う。
                if (!this.__temp_l.makeLinearWithNormalize(i_pos1, i_pos2))
                {
                    return(false);
                }
                if (!this.__temp_l.makeSegmentLine(s.w, s.h, pt))
                {
                    return(false);
                }
            }
            if (!this.traceLine(pt[0], pt[1], i_edge, o_coord))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 5
0
        /**
         * 輪郭線を取得します。
         * 取得アルゴリズムは、以下の通りです。
         * 1.輪郭座標(n)の画素周辺の画素ベクトルを取得。
         * 2.輪郭座標(n+1)周辺の画素ベクトルと比較。
         * 3.差分が一定以下なら、座標と強度を保存
         * 4.3点以上の集合になったら、最小二乗法で直線を計算。
         * 5.直線の加重値を個々の画素ベクトルの和として返却。
         */
        public bool traceConture(NyARIntCoordinates i_coord, int i_pos_mag, int i_cell_size, VecLinearCoordinates o_coord)
        {
            VecLinearCoordinates.VecLinearCoordinatePoint[] pos = this._tmp_coord_pos;
            // ベクトル化
            int MAX_COORD  = o_coord.items.Length;
            int i_coordlen = i_coord.length;

            NyARIntPoint2d[] coord = i_coord.items;
            VecLinearCoordinates.VecLinearCoordinatePoint pos_ptr;

            //0個目のライン探索
            int  number_of_data = 0;
            int  sq;
            long sq_sum = 0;

            //0番目のピクセル
            pos[0].scalar = sq = this.getAreaVector33(coord[0].x * i_pos_mag, coord[0].y * i_pos_mag, i_cell_size, i_cell_size, pos[0]);
            sq_sum       += (int)sq;
            //[2]に0を保管

            //1点目だけは前方と後方、両方に探索をかける。
            //前方探索の終点
            int coord_last_edge = i_coordlen;
            //後方探索
            int    sum    = 1;
            double ave_dx = pos[0].dx;
            double ave_dy = pos[0].dy;

            for (int i = i_coordlen - 1; i > 0; i--)
            {
                // ベクトル取得
                pos_ptr        = pos[sum];
                pos_ptr.scalar = sq = this.getAreaVector33(coord[i].x * i_pos_mag, coord[i].y * i_pos_mag, i_cell_size, i_cell_size, pos_ptr);
                sq_sum        += (int)sq;
                // 類似度判定
                if (checkVecCos(pos[sum], pos[sum - 1], ave_dx, ave_dy))
                {
                    //相関なし->前方探索へ。
                    ave_dx          = pos_ptr.dx;
                    ave_dy          = pos_ptr.dy;
                    coord_last_edge = i;
                    break;
                }
                else
                {
                    //相関あり- 点の蓄積
                    ave_dx += pos_ptr.dx;
                    ave_dy += pos_ptr.dy;
                    sum++;
                }
            }
            //前方探索
            for (int i = 1; i < coord_last_edge; i++)
            {
                // ベクトル取得
                pos_ptr        = pos[sum];
                pos_ptr.scalar = sq = this.getAreaVector33(coord[i].x * i_pos_mag, coord[i].y * i_pos_mag, i_cell_size, i_cell_size, pos_ptr);
                sq_sum        += (int)sq;
                if (sq == 0)
                {
                    continue;
                }
                //if (pos_ptr.getAbsVecCos(pos[sum-1]) < NyARMath.COS_DEG_5 && pos_ptr.getAbsVecCos(ave_dx,ave_dy)<NyARMath.COS_DEG_20) {
                if (checkVecCos(pos[sum], pos[sum - 1], ave_dx, ave_dy))
                {
                    //相関なし->新しい要素を作る。
                    if (this.leastSquaresWithNormalize(pos, sum, o_coord.items[number_of_data], sq_sum / (sum * 5)))
                    {
                        number_of_data++;
                    }
                    ave_dx = pos_ptr.dx;
                    ave_dy = pos_ptr.dy;
                    //獲得した値を0へ移動
                    pos[0].setValue(pos[sum]);
                    sq_sum = 0;
                    sum    = 1;
                }
                else
                {
                    //相関あり- 点の蓄積
                    ave_dx += pos_ptr.dx;
                    ave_dy += pos_ptr.dy;
                    sum++;
                }
                // 輪郭中心を出すための計算
                if (number_of_data == MAX_COORD)
                {
                    // 輪郭ベクトルバッファの最大を超えたら失敗
                    return(false);
                }
            }
            if (this.leastSquaresWithNormalize(pos, sum, o_coord.items[number_of_data], sq_sum / (sum * 5)))
            {
                number_of_data++;
            }
            // ベクトル化2:最後尾と先頭の要素が似ていれば連結する。
            // sq_distの合計を計算
            o_coord.length = number_of_data;

            return(true);
        }
Ejemplo n.º 6
0
        public bool traceLine(NyARDoublePoint2d i_pos1, NyARDoublePoint2d i_pos2, int i_edge, VecLinearCoordinates o_coord)
        {
            NyARIntCoordinates coord  = this._coord_buf;
            NyARIntSize        base_s = this._ref_base_raster.getSize();
            // (i_area*2)の矩形が範囲内に収まるように線を引く
            // 移動量

            // 点間距離を計算
            int dist = (int)Math.Sqrt(i_pos1.sqDist(i_pos2));

            // 最低AREA*2以上の大きさが無いなら、ラインのトレースは不可能。
            if (dist < 4)
            {
                return(false);
            }
            // dist最大数の決定
            if (dist > 12)
            {
                dist = 12;
            }
            // サンプリングサイズを決定(移動速度とサイズから)
            int s  = i_edge * 2 + 1;
            int dx = (int)(i_pos2.x - i_pos1.x);
            int dy = (int)(i_pos2.y - i_pos1.y);
            int r  = base_s.w - s;
            int b  = base_s.h - s;

            // 最大24点を定義して、そのうち両端の2個を除いた点を使用する。
            for (int i = 1; i < dist - 1; i++)
            {
                int x = (int)(i * dx / dist + i_pos1.x - i_edge);
                int y = (int)(i * dy / dist + i_pos1.y - i_edge);
                // limit
                coord.items[i - 1].x = x < 0 ? 0 : (x >= r ? r : x);
                coord.items[i - 1].y = y < 0 ? 0 : (y >= b ? b : y);
            }

            coord.length = dist - 2;
            // 点数は10点程度を得る。
            return(traceConture(coord, 1, s, o_coord));
        }