Beispiel #1
0
        /**
         * この関数は、頂点同士の距離から、頂点のシフト量(回転量)を返します。
         * よく似た2つの矩形の頂点同士の、頂点の対応を取るために使用します。
         * @param i_square
         * 比較対象の矩形
         * @return
         * シフト量を数値で返します。
         * シフト量はthis-i_squareです。1の場合、this.sqvertex[0]とi_square.sqvertex[1]が対応点になる(shift量1)であることを示します。
         */
        public int checkVertexShiftValue(NyARSquare i_square)
        {
            NyARDoublePoint2d[] a = this.sqvertex;
            NyARDoublePoint2d[] b = i_square.sqvertex;

            //3-0番目
            int min_dist = int.MaxValue;
            int min_index = 0;
            int xd, yd;
            for (int i = 3; i >= 0; i--)
            {
                int d = 0;
                for (int i2 = 3; i2 >= 0; i2--)
                {
                    xd = (int)(a[i2].x - b[(i2 + i) % 4].x);
                    yd = (int)(a[i2].y - b[(i2 + i) % 4].y);
                    d += xd * xd + yd * yd;
                }
                if (min_dist > d)
                {
                    min_dist = d;
                    min_index = i;
                }
            }
            return min_index;
        }
Beispiel #2
0
        /**
         * この関数は、頂点同士の距離から、頂点のシフト量(回転量)を返します。
         * よく似た2つの矩形の頂点同士の、頂点の対応を取るために使用します。
         * @param i_square
         * 比較対象の矩形
         * @return
         * シフト量を数値で返します。
         * シフト量はthis-i_squareです。1の場合、this.sqvertex[0]とi_square.sqvertex[1]が対応点になる(shift量1)であることを示します。
         */
        public int checkVertexShiftValue(NyARSquare i_square)
        {
            NyARDoublePoint2d[] a = this.sqvertex;
            NyARDoublePoint2d[] b = i_square.sqvertex;

            //3-0番目
            int min_dist = int.MaxValue;
            int min_index = 0;
            int xd, yd;
            for (int i = 3; i >= 0; i--)
            {
                int d = 0;
                for (int i2 = 3; i2 >= 0; i2--)
                {
                    xd = (int)(a[i2].x - b[(i2 + i) % 4].x);
                    yd = (int)(a[i2].y - b[(i2 + i) % 4].y);
                    d += xd * xd + yd * yd;
                }
                if (min_dist > d)
                {
                    min_dist = d;
                    min_index = i;
                }
            }
            return min_index;
        }
Beispiel #3
0
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * ARToolKitのarGetTransMatに該当します。
         * @see INyARTransMat#transMatContinue
         */
        public bool transMat(NyARSquare i_square, NyARRectOffset i_offset, NyARDoubleMatrix44 o_result, NyARTransMatResultParam o_param)
        {
            NyARDoublePoint3d trans         = this.__transMat_trans;
            double            err_threshold = makeErrThreshold(i_square.sqvertex);

            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                //歪み復元必要
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                //歪み復元は不要
                vertex_2d = i_square.sqvertex;
            }
            //平行移動量計算機に、2D座標系をセット
            this._transsolver.set2dVertex(vertex_2d, 4);

            //回転行列を計算
            if (!this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex))
            {
                return(false);
            }

            //回転後の3D座標系から、平行移動量を計算
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            double err = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d, err_threshold, o_result);

            //必要なら計算パラメータを返却
            if (o_param != null)
            {
                o_param.last_error = err;
            }
            return(true);
        }
Beispiel #4
0
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * 計算に過去の履歴を使う点が、{@link #transMat}と異なります。
         * @see INyARTransMat#transMatContinue
         */
        public bool transMatContinue(NyARSquare i_square, NyARRectOffset i_offset, NyARDoubleMatrix44 i_prev_result, double i_prev_err, NyARDoubleMatrix44 o_result, NyARTransMatResultParam o_param)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            //最適化計算の閾値を決定
            double err_threshold = makeErrThreshold(i_square.sqvertex);


            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                vertex_2d = i_square.sqvertex;
            }
            this._transsolver.set2dVertex(vertex_2d, 4);

            //回転行列を計算
            NyARRotMatrix rot = this._rotmatrix;

            rot.initRotByPrevResult(i_prev_result);

            //回転後の3D座標系から、平行移動量を計算
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            rot.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //現在のエラーレートを計算
            double min_err = errRate(rot, trans, i_offset.vertex, vertex_2d, 4, vertex_3d);

            //エラーレートの判定
            if (min_err < i_prev_err + err_threshold)
            {
                //save initial result
                o_result.setValue(rot, trans);
                //			System.out.println("TR:ok");
                //最適化してみる。
                for (int i = 0; i < 5; i++)
                {
                    //変換行列の最適化
                    this._mat_optimize.modifyMatrix(rot, trans, i_offset.vertex, vertex_2d, 4);
                    double err = errRate(rot, trans, i_offset.vertex, vertex_2d, 4, vertex_3d);
                    //System.out.println("E:"+err);
                    if (min_err - err < err_threshold / 2)
                    {
                        //System.out.println("BREAK");
                        break;
                    }
                    this._transsolver.solveTransportVector(vertex_3d, trans);
                    o_result.setValue(rot, trans);
                    min_err = err;
                }
                //継続計算成功
                if (o_param != null)
                {
                    o_param.last_error = min_err;
                }
                return(true);
            }
            //継続計算失敗
            return(false);
        }
Beispiel #5
0
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * 計算に過去の履歴を使う点が、{@link #transMat}と異なります。
         * @see INyARTransMat#transMatContinue
         */
        public bool transMatContinue(NyARSquare i_square,NyARRectOffset i_offset, NyARDoubleMatrix44 i_prev_result,double i_prev_err,NyARDoubleMatrix44 o_result,NyARTransMatResultParam o_param)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;

            //最適化計算の閾値を決定
            double err_threshold = makeErrThreshold(i_square.sqvertex);

            //平行移動量計算機に、2D座標系をセット
            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                vertex_2d = i_square.sqvertex;
            }
            this._transsolver.set2dVertex(vertex_2d, 4);

            //回転行列を計算
            NyARRotMatrix rot = this._rotmatrix;
            rot.initRotByPrevResult(i_prev_result);

            //回転後の3D座標系から、平行移動量を計算
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            rot.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //現在のエラーレートを計算
            double min_err = errRate(rot, trans, i_offset.vertex, vertex_2d, 4, vertex_3d);

            //エラーレートの判定
            if(min_err<i_prev_err+err_threshold){
                //save initial result
                o_result.setValue(rot,trans);
                //			System.out.println("TR:ok");
                //最適化してみる。
                for (int i = 0; i < 5; i++)
                {
                    //変換行列の最適化
                    this._mat_optimize.modifyMatrix(rot, trans, i_offset.vertex, vertex_2d, 4);
                    double err = errRate(rot, trans, i_offset.vertex, vertex_2d, 4, vertex_3d);
                    //System.out.println("E:"+err);
                    if (min_err - err < err_threshold / 2)
                    {
                        //System.out.println("BREAK");
                        break;
                    }
                    this._transsolver.solveTransportVector(vertex_3d, trans);
                    o_result.setValue(rot, trans);
                    min_err = err;
                }
                //継続計算成功
                if (o_param != null)
                {
                    o_param.last_error = min_err;
                }
                return true;
            }
            //継続計算失敗
            return false;
        }
Beispiel #6
0
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * ARToolKitのarGetTransMatに該当します。
         * @see INyARTransMat#transMatContinue
         */
        public bool transMat(NyARSquare i_square,NyARRectOffset i_offset, NyARDoubleMatrix44 o_result,NyARTransMatResultParam o_param)
        {
            NyARDoublePoint3d trans = this.__transMat_trans;
            double err_threshold = makeErrThreshold(i_square.sqvertex);

            NyARDoublePoint2d[] vertex_2d;
            if (this._ref_dist_factor != null)
            {
                //歪み復元必要
                vertex_2d = this.__transMat_vertex_2d;
                this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d, 4);
            }
            else
            {
                //歪み復元は不要
                vertex_2d = i_square.sqvertex;
            }
            //平行移動量計算機に、2D座標系をセット
            this._transsolver.set2dVertex(vertex_2d, 4);

            //回転行列を計算
            if (!this._rotmatrix.initRotBySquare(i_square.line, i_square.sqvertex))
            {
                return false;
            }

            //回転後の3D座標系から、平行移動量を計算
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            this._rotmatrix.getPoint3dBatch(i_offset.vertex, vertex_3d, 4);
            this._transsolver.solveTransportVector(vertex_3d, trans);

            //計算結果の最適化(平行移動量と回転行列の最適化)
            double err = this.optimize(this._rotmatrix, trans, this._transsolver, i_offset.vertex, vertex_2d, err_threshold, o_result);
            //必要なら計算パラメータを返却
            if (o_param != null)
            {
                o_param.last_error = err;
            }
            return true;
        }
 /**	オブジェクトのステータスを更新し、必要に応じて自己コールバック関数を駆動します。
  * 	戻り値は、「実際にマーカを発見する事ができたか」を示す真偽値です。クラスの状態とは異なります。
  */
 private bool updateStatus(NyARSquare i_square, int i_code_index)
 {
     if (this._current_arcode_index < 0) {// 未認識中
     if (i_code_index < 0) {// 未認識から未認識の遷移
                        // なにもしないよーん。
       return false;
     }
     else {// 未認識から認識の遷移
       this._current_arcode_index = i_code_index;
       // イベント生成
       // OnEnter
       this.onEnterHandler(i_code_index);
       // 変換行列を作成
       this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param);
       // OnUpdate
       this.onUpdateHandler(i_square, this._transmat_result);
       this._lost_delay_count = 0;
       return true;
     }
       }
       else {// 認識中
     if (i_code_index < 0) {// 認識から未認識の遷移
       this._lost_delay_count++;
       if (this._lost_delay < this._lost_delay_count) {
     // OnLeave
     this._current_arcode_index = -1;
     this.onLeaveHandler();
       }
       return false;
     }
     else if (i_code_index == this._current_arcode_index) {// 同じARCodeの再認識
                                                       // イベント生成
                                                       // 変換行列を作成
       if (!this._transmat.transMatContinue(i_square, this._offset, this._transmat_result, this._last_result_param.last_error, this._transmat_result, this._last_result_param)) {
     this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param);
       }
       // OnUpdate
       this.onUpdateHandler(i_square, this._transmat_result);
       this._lost_delay_count = 0;
       return true;
     }
     else {// 異なるコードの認識→今はサポートしない。
       throw new NyARException();
     }
       }
 }
 /**
  * 自己コールバック関数です。
  * 継承したクラスで、マーカ更新時の処理を実装してください。
  * 引数の値の有効期間は、関数が終了するまでです。
  * @param i_square
  * 現在のマーカ検出位置です。
  * @param o_result
  * 現在の姿勢変換行列です。
  */
 protected abstract void onUpdateHandler(NyARSquare i_square, NyARDoubleMatrix44 o_result);
 /**オブジェクトのステータスを更新し、必要に応じて自己コールバック関数を駆動します。
  */
 private bool UpdateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data)
 {
     bool is_id_found = false;
       if (!this._is_active) {// 未認識中
     if (i_marker_data == null) {// 未認識から未認識の遷移
                             // なにもしないよーん。
       this._is_active = false;
     }
     else {// 未認識から認識の遷移
       this._data_current.copyFrom(i_marker_data);
       // イベント生成
       // OnEnter
       this.OnEnterHandler(this._data_current);
       // 変換行列を作成
       this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param);
       // OnUpdate
       this.OnUpdateHandler(i_square, this._transmat_result);
       this._lost_delay_count = 0;
       this._is_active = true;
       is_id_found = true;
     }
       }
       else {// 認識中
     if (i_marker_data == null) {
       // 認識から未認識の遷移
       this._lost_delay_count++;
       if (this._lost_delay < this._lost_delay_count) {
     // OnLeave
     this.OnLeaveHandler();
     this._is_active = false;
       }
     }
     else if (this._data_current.isEqual(i_marker_data)) {
       //同じidの再認識
       if (!this._transmat.transMatContinue(i_square, this._offset, this._transmat_result, this._last_result_param.last_error, this._transmat_result, this._last_result_param)) {
     this._transmat.transMat(i_square, this._offset, this._transmat_result, this._last_result_param);
       }
       // OnUpdate
       this.OnUpdateHandler(i_square, this._transmat_result);
       this._lost_delay_count = 0;
       is_id_found = true;
     }
     else {// 異なるコードの認識→今はサポートしない。
       throw new NyARException();
     }
       }
       return is_id_found;
 }
Beispiel #10
0
        /**
         * 頂点データをNyARSquareにセットする関数です。
         * 初期位置セットには使わないこと。
         * @param i_vx
         * @param i_s
         */
        private void SetSquare(NyARDoublePoint2d[] i_vx, NyARSquare i_s)
        {
            NyARLinear l = this.__tmp_l;
              //線分を平滑化。(ノイズが多いソースを使う時は線分の平滑化。ほんとは使いたくない。)
              for (int i = 3; i >= 0; i--) {
            i_s.sqvertex[i].setValue(i_vx[i]);
            l.makeLinearWithNormalize(i_vx[i], i_vx[(i + 1) % 4]);
            i_s.line[i].a = i_s.line[i].a * 0.6 + l.a * 0.4;
            i_s.line[i].b = i_s.line[i].b * 0.6 + l.b * 0.4;
            i_s.line[i].c = i_s.line[i].c * 0.6 + l.c * 0.4;
              }

              for (int i = 3; i >= 0; i--) {
            i_s.line[i].crossPos(i_s.line[(i + 3) % 4], i_s.sqvertex[i]);
              }
        }