Example #1
0
        /**
         * @param i_width
         * @param i_height
         */
        public NyARColorPatt_PseudoAffine(int i_width, int i_height)
        {
            this._size        = new NyARIntSize(i_width, i_height);
            this._patdata     = new int[i_height * i_width];
            this._pixelreader = new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata, this._size);
            //疑似アフィン変換のパラメタマトリクスを計算します。
            //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。
            NyARDoubleMatrix44 mat = this._invmat;

            mat.m00 = 0;
            mat.m01 = 0;
            mat.m02 = 0;
            mat.m03 = 1.0;
            mat.m10 = 0;
            mat.m11 = i_width - 1;
            mat.m12 = 0;
            mat.m13 = 1.0;
            mat.m20 = (i_width - 1) * (i_height - 1);
            mat.m21 = i_width - 1;
            mat.m22 = i_height - 1;
            mat.m23 = 1.0;
            mat.m30 = 0;
            mat.m31 = 0;
            mat.m32 = i_height - 1;
            mat.m33 = 1.0;
            mat.inverse(mat);
            return;
        }
        /**
         * {@link #icpGetInitXw2XcSub}関数のmat_dを計算します。
         */
        private static NyARDoubleMatrix33 makeMatD(NyARDoubleMatrix44 i_cp, NyARDoublePoint2d[] pos2d, int i_num, NyARDoubleMatrix33 o_mat)
        {
            double m02 = 0;
            double m12 = 0;
            double m20 = 0;
            double m21 = 0;
            double m22 = 0;

            for (int i = 0; i < i_num; i++)
            {
                double cx = i_cp.m02 - pos2d[i].x;
                double cy = i_cp.m12 - pos2d[i].y;
                m02 += (cx) * i_cp.m00;
                m12 += (cx) * i_cp.m01 + (cy) * i_cp.m11;
                m20 += i_cp.m00 * (cx);
                m21 += i_cp.m01 * (cx) + i_cp.m11 * (cy);
                m22 += (cx) * (cx) + (cy) * (cy);
            }
            o_mat.m00 = (i_cp.m00 * i_cp.m00) * i_num;
            o_mat.m01 = (i_cp.m00 * i_cp.m01) * i_num;
            o_mat.m02 = m02;
            o_mat.m10 = (i_cp.m01 * i_cp.m00) * i_num;
            o_mat.m11 = (i_cp.m01 * i_cp.m01 + i_cp.m11 * i_cp.m11) * i_num;
            o_mat.m12 = m12;
            o_mat.m20 = m20;
            o_mat.m21 = m21;
            o_mat.m22 = m22;
            o_mat.inverse(o_mat);
            return(o_mat);
        }
Example #3
0
        public Form1()
        {
            InitializeComponent();
            //ARの設定
            //AR用カメラパラメタファイルをロード
            NyARParam ap = NyARParam.createFromARParamFile(new StreamReader(AR_CAMERA_FILE));
            ap.changeScreenSize(320, 240);

            //AR用のパターンコードを読み出し
            NyARCode code = NyARCode.createFromARPattFile(new StreamReader(AR_CODE_FILE),16, 16);

            NyARDoubleMatrix44 result_mat = new NyARDoubleMatrix44();
            //計算モードの設定
            //キャプチャを作る
            /**************************************************
            このコードは、0番目(一番初めに見つかったキャプチャデバイス)
            を使用するようにされています。
            複数のキャプチャデバイスを持つシステムの場合、うまく動作しないかもしれません。
            n番目のデバイスを使いたいときには、CaptureDevice cap=cl[0];←ここの0を変えてください。
            手動で選択させる方法は、SimpleLiteDirect3Dを参考にしてください。
            **************************************************/
            CaptureDeviceList cl=new CaptureDeviceList();
            CaptureDevice cap=cl[0];
            cap.SetCaptureListener(this);
            cap.PrepareCapture(320, 240,30);
            this.m_cap = cap;
            //ラスタを作る。
            this.m_raster = new DsRgbRaster(cap.video_width, cap.video_height,NyARBufferType.OBJECT_CS_Bitmap);
            //1パターンのみを追跡するクラスを作成
            this.m_ar = NyARSingleDetectMarker.createInstance(ap, code, 80.0);
            this.m_ar.setContinueMode(false);
        }
Example #4
0
        /**
         * x,yのうち小さい方の解像度を返す。
         * @param i_pos
         * 理想系座標
         * @return
         * 推定したdpi
         */
        public double ar2GetMinResolution(NyARNftFsetFile.NyAR2FeatureCoord i_pos)
        {
            NyARDoubleMatrix44 t = this.ctrans;
            //基点
            double mx0 = i_pos.mx;
            double my0 = i_pos.my;
            double h0  = t.m20 * mx0 + t.m21 * my0 + t.m23;
            double hx0 = t.m00 * mx0 + t.m01 * my0 + t.m03;
            double hy0 = t.m10 * mx0 + t.m11 * my0 + t.m13;
            double x0  = hx0 / h0;
            double y0  = hy0 / h0;

            double h, sx, sy;

            //+X
            h  = h0 + t.m20 * DPI_BOX;
            sx = ((hx0 + DPI_BOX * t.m00) / h) - x0;
            sy = ((hy0 + DPI_BOX * t.m10) / h) - y0;
            //dpi -x
            double dx = Math.Sqrt(sx * sx + sy * sy) * 2.54;

            //+Y
            h  = h0 + t.m21 * DPI_BOX;
            sx = ((hx0 + DPI_BOX * t.m01) / h) - x0;
            sy = ((hy0 + DPI_BOX * t.m11) / h) - y0;

            //dpi -y
            double dy = Math.Sqrt(sx * sx + sy * sy) * 2.54;

            return(dx < dy ? dx : dy);
        }
        /**
         * {@link #icpGetInitXw2XcSub}関数のmat_eを計算します。
         */
        private static double[] makeMatE(NyARDoubleMatrix44 i_cp, NyARDoubleMatrix44 rot, NyARDoublePoint2d[] pos2d, NyARDoublePoint3d[] pos3d, NyARDoublePoint3d offset, int i_num, double[] o_val)
        {
            double v0 = 0;
            double v1 = 0;
            double v2 = 0;

            for (int j = 0; j < i_num; j++)
            {
                double p3x = pos3d[j].x + offset.x;
                double p3y = pos3d[j].y + offset.y;
                double p3z = pos3d[j].z + offset.z;
                double wx  = rot.m00 * p3x + rot.m01 * p3y + rot.m02 * p3z;
                double wy  = rot.m10 * p3x + rot.m11 * p3y + rot.m12 * p3z;
                double wz  = rot.m20 * p3x + rot.m21 * p3y + rot.m22 * p3z;
                double c1  = wz * pos2d[j].x - i_cp.m00 * wx - i_cp.m01 * wy - i_cp.m02 * wz;
                double c2  = wz * pos2d[j].y - i_cp.m11 * wy - i_cp.m12 * wz;
                v0 += i_cp.m00 * c1;
                v1 += i_cp.m01 * c1 + i_cp.m11 * c2;
                v2 += (i_cp.m02 - pos2d[j].x) * c1 + (i_cp.m12 - pos2d[j].y) * c2;
            }
            o_val[0] = v0;
            o_val[1] = v1;
            o_val[2] = v2;
            return(o_val);
        }
        /**
         * コンストラクタです。
         * @param i_width
         * このラスタの幅
         * @param i_height
         * このラスタの高さ
         * @
         */
        public NyARColorPatt_PseudoAffine(int i_width, int i_height)
            : base(i_width, i_height, true)
        {
            //疑似アフィン変換のパラメタマトリクスを計算します。
            //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。
            NyARDoubleMatrix44 mat = this._invmat;

            mat.m00 = 0;
            mat.m01 = 0;
            mat.m02 = 0;
            mat.m03 = 1.0;
            mat.m10 = 0;
            mat.m11 = i_width - 1;
            mat.m12 = 0;
            mat.m13 = 1.0;
            mat.m20 = (i_width - 1) * (i_height - 1);
            mat.m21 = i_width - 1;
            mat.m22 = i_height - 1;
            mat.m23 = 1.0;
            mat.m30 = 0;
            mat.m31 = 0;
            mat.m32 = i_height - 1;
            mat.m33 = 1.0;
            mat.inverse(mat);
            return;
        }
Example #7
0
        /**
         * 基準点のdpiを推定する。
         * @param i_cptrans
         * 射影変換行列. [cparam]*[trans]
         * @param trans
         * @param pos
         * [2]
         * @param o_dpi
         * x,y方向それぞれの推定dpi
         * @return
         */
        public void ar2GetResolution2d(NyARNftFsetFile.NyAR2FeatureCoord i_pos, NyARDoublePoint2d o_dpi)
        {
            NyARDoubleMatrix44 t = this.ctrans;
            //基点
            double mx0 = i_pos.mx;
            double my0 = i_pos.my;
            double h0  = t.m20 * mx0 + t.m21 * my0 + t.m23;
            double hx0 = t.m00 * mx0 + t.m01 * my0 + t.m03;
            double hy0 = t.m10 * mx0 + t.m11 * my0 + t.m13;
            double x0  = hx0 / h0;
            double y0  = hy0 / h0;

            double h, sx, sy;

            //+X
            h  = h0 + t.m20 * DPI_BOX;
            sx = ((hx0 + DPI_BOX * t.m00) / h) - x0;
            sy = ((hy0 + DPI_BOX * t.m10) / h) - y0;
            //dpi -x
            o_dpi.x = Math.Sqrt(sx * sx + sy * sy) * 2.54;

            //+Y
            h  = h0 + t.m21 * DPI_BOX;
            sx = ((hx0 + DPI_BOX * t.m01) / h) - x0;
            sy = ((hy0 + DPI_BOX * t.m11) / h) - y0;

            //dpi -y
            o_dpi.y = Math.Sqrt(sx * sx + sy * sy) * 2.54;
            return;
        }
Example #8
0
        /**
         * この関数は、行列同士の掛け算をして、インスタンスに格納します。
         * i_mat_lとi_mat_rには、thisを指定しないでください。
         * @param i_mat_l
         * 左成分の行列
         * @param i_mat_r
         * 右成分の行列
         */
        public void mul(NyARDoubleMatrix44 i_mat_l, NyARDoubleMatrix44 i_mat_r)
        {
            Debug.Assert(this != i_mat_l);
            Debug.Assert(this != i_mat_r);
            this.m00 = i_mat_l.m00 * i_mat_r.m00 + i_mat_l.m01 * i_mat_r.m10 + i_mat_l.m02 * i_mat_r.m20 + i_mat_l.m03 * i_mat_r.m30;
            this.m01 = i_mat_l.m00 * i_mat_r.m01 + i_mat_l.m01 * i_mat_r.m11 + i_mat_l.m02 * i_mat_r.m21 + i_mat_l.m03 * i_mat_r.m31;
            this.m02 = i_mat_l.m00 * i_mat_r.m02 + i_mat_l.m01 * i_mat_r.m12 + i_mat_l.m02 * i_mat_r.m22 + i_mat_l.m03 * i_mat_r.m32;
            this.m03 = i_mat_l.m00 * i_mat_r.m03 + i_mat_l.m01 * i_mat_r.m13 + i_mat_l.m02 * i_mat_r.m23 + i_mat_l.m03 * i_mat_r.m33;

            this.m10 = i_mat_l.m10 * i_mat_r.m00 + i_mat_l.m11 * i_mat_r.m10 + i_mat_l.m12 * i_mat_r.m20 + i_mat_l.m13 * i_mat_r.m30;
            this.m11 = i_mat_l.m10 * i_mat_r.m01 + i_mat_l.m11 * i_mat_r.m11 + i_mat_l.m12 * i_mat_r.m21 + i_mat_l.m13 * i_mat_r.m31;
            this.m12 = i_mat_l.m10 * i_mat_r.m02 + i_mat_l.m11 * i_mat_r.m12 + i_mat_l.m12 * i_mat_r.m22 + i_mat_l.m13 * i_mat_r.m32;
            this.m13 = i_mat_l.m10 * i_mat_r.m03 + i_mat_l.m11 * i_mat_r.m13 + i_mat_l.m12 * i_mat_r.m23 + i_mat_l.m13 * i_mat_r.m33;

            this.m20 = i_mat_l.m20 * i_mat_r.m00 + i_mat_l.m21 * i_mat_r.m10 + i_mat_l.m22 * i_mat_r.m20 + i_mat_l.m23 * i_mat_r.m30;
            this.m21 = i_mat_l.m20 * i_mat_r.m01 + i_mat_l.m21 * i_mat_r.m11 + i_mat_l.m22 * i_mat_r.m21 + i_mat_l.m23 * i_mat_r.m31;
            this.m22 = i_mat_l.m20 * i_mat_r.m02 + i_mat_l.m21 * i_mat_r.m12 + i_mat_l.m22 * i_mat_r.m22 + i_mat_l.m23 * i_mat_r.m32;
            this.m23 = i_mat_l.m20 * i_mat_r.m03 + i_mat_l.m21 * i_mat_r.m13 + i_mat_l.m22 * i_mat_r.m23 + i_mat_l.m23 * i_mat_r.m33;

            this.m30 = i_mat_l.m30 * i_mat_r.m00 + i_mat_l.m31 * i_mat_r.m10 + i_mat_l.m32 * i_mat_r.m20 + i_mat_l.m33 * i_mat_r.m30;
            this.m31 = i_mat_l.m30 * i_mat_r.m01 + i_mat_l.m31 * i_mat_r.m11 + i_mat_l.m32 * i_mat_r.m21 + i_mat_l.m33 * i_mat_r.m31;
            this.m32 = i_mat_l.m30 * i_mat_r.m02 + i_mat_l.m31 * i_mat_r.m12 + i_mat_l.m32 * i_mat_r.m22 + i_mat_l.m33 * i_mat_r.m32;
            this.m33 = i_mat_l.m30 * i_mat_r.m03 + i_mat_l.m31 * i_mat_r.m13 + i_mat_l.m32 * i_mat_r.m23 + i_mat_l.m33 * i_mat_r.m33;
            return;
        }
Example #9
0
        /**
         * 変換行列と頂点座標から、パラメータを計算
         * o_paramの[0..3]にはXのパラメタ、[4..7]にはYのパラメタを格納する。
         * @param i_vertex
         * @param pa
         * @param pb
         */
        private void calcPara(NyARIntPoint2d[] i_vertex, double[] o_cparam)
        {
            NyARDoubleMatrix44 invmat = this._invmat;
            double             v1, v2, v4;

            //変換行列とベクトルの積から、変換パラメタを計算する。
            v1 = i_vertex[0].x;
            v2 = i_vertex[1].x;
            v4 = i_vertex[3].x;

            o_cparam[0] = invmat.m00 * v1 + invmat.m01 * v2 + invmat.m02 * i_vertex[2].x + invmat.m03 * v4;
            o_cparam[1] = invmat.m10 * v1 + invmat.m11 * v2; //m12,m13は0;
            o_cparam[2] = invmat.m20 * v1 + invmat.m23 * v4; //m21,m22は0;
            o_cparam[3] = v1;                                //m30は1.0で、m31,m32,m33は0

            v1 = i_vertex[0].y;
            v2 = i_vertex[1].y;
            v4 = i_vertex[3].y;

            o_cparam[4] = invmat.m00 * v1 + invmat.m01 * v2 + invmat.m02 * i_vertex[2].y + invmat.m03 * v4;
            o_cparam[5] = invmat.m10 * v1 + invmat.m11 * v2; //m12,m13は0;
            o_cparam[6] = invmat.m20 * v1 + invmat.m23 * v4; //m21,m22は0;
            o_cparam[7] = v1;                                //m30は1.0で、m31,m32,m33は0
            return;
        }
 /**
  * この関数は、オブジェクトの配列を生成して返します。
  * @param i_number
  * 配列の長さ
  * @return
  * 新しいオブジェクト配列
  */
 public static NyARDoubleMatrix44[] createArray(int i_number)
 {
     NyARDoubleMatrix44[] ret = new NyARDoubleMatrix44[i_number];
     for (int i = 0; i < i_number; i++)
     {
         ret[i] = new NyARDoubleMatrix44();
     }
     return ret;
 }
Example #11
0
 /**
  * この関数は、オブジェクトの配列を生成して返します。
  * @param i_number
  * 配列の長さ
  * @return
  * 新しいオブジェクト配列
  */
 public static NyARDoubleMatrix44[] createArray(int i_number)
 {
     NyARDoubleMatrix44[] ret = new NyARDoubleMatrix44[i_number];
     for (int i = 0; i < i_number; i++)
     {
         ret[i] = new NyARDoubleMatrix44();
     }
     return(ret);
 }
Example #12
0
        /**
         * なんだろうこれ。Z位置?
         * @param mx
         * @param my
         * @return
         */
        public double calculateVd(double mx, double my)
        {
            NyARDoubleMatrix44 t   = this.trans;
            double             vd0 = t.m00 * mx + t.m01 * my + t.m03;
            double             vd1 = t.m10 * mx + t.m11 * my + t.m13;
            double             vd2 = t.m20 * mx + t.m21 * my + t.m23;

            return((vd0 * t.m02 + vd1 * t.m12 + vd2 * t.m22) / Math.Sqrt(vd0 * vd0 + vd1 * vd1 + vd2 * vd2));
        }
Example #13
0
        /**
         * 現在の特徴点セットから、
         * @param i_keymap
         * @param i_result
         * @return
         */
        public bool kpmMatching(KeyframeMap i_keymap, NyARDoubleMatrix44 i_transmat)
        {
            FeaturePairStack result = new FeaturePairStack(kMaxNumFeatures);

            if (!this.query(this.mQueryKeyframe, i_keymap, result))
            {
                return(false);
            }
            return(kpmUtilGetPose_binary(this._ref_cparam, result, i_transmat, this._result_param));
        }
Example #14
0
        /**
         * 理想点を計算する。
         * @param i_coord
         * 変換元の座標(理想点)
         */
        public void calculate2dPos(double i_x, double i_y, NyARDoublePoint2d o_idepos)
        {
            NyARDoubleMatrix44 t  = this.ctrans;
            double             h  = (t.m20 * i_x + t.m21 * i_y + t.m23);
            double             hx = (t.m00 * i_x + t.m01 * i_y + t.m03) / h;
            double             hy = (t.m10 * i_x + t.m11 * i_y + t.m13) / h;

            o_idepos.x = hx;
            o_idepos.y = hy;
        }
Example #15
0
        public PerspectiveParam getPerspectiveParam(PerspectiveParam o_value)
        {
            NyARDoubleMatrix44 mat = this._frustum_rh;

            o_value.far    = mat.m23 / (mat.m22 + 1);
            o_value.near   = mat.m23 / (mat.m22 - 1);
            o_value.aspect = mat.m11 / mat.m00;
            o_value.fovy   = 2 * Math.Atan(1 / (mat.m00 * o_value.aspect));
            return(o_value);
        }
Example #16
0
        /**
         * カメラ座標系の点を、スクリーン座標の点へ変換します。
         * @param i_x
         * カメラ座標系の点
         * @param i_y
         * カメラ座標系の点
         * @param i_z
         * カメラ座標系の点
         * @param o_pos2d
         * 結果を受け取るオブジェクトです。
         */
        public void project(double i_x, double i_y, double i_z, NyARDoublePoint2d o_pos2d)
        {
            NyARDoubleMatrix44 m    = this._frustum_rh;
            double             v3_1 = 1 / i_z * m.m32;
            double             w    = this._screen_size.w;
            double             h    = this._screen_size.h;

            o_pos2d.x = w - (1 + (i_x * m.m00 + i_z * m.m02) * v3_1) * w / 2;
            o_pos2d.y = h - (1 + (i_y * m.m11 + i_z * m.m12) * v3_1) * h / 2;
            return;
        }
Example #17
0
        /**
         * 元ar2GenTemplate関数。
         * 与えられた座標を中心に、テンプレート画像を生成する。
         * 座標は観察座標点。
         * @param i_x
         * @param i_y
         * @param i_scale
         * @param o_template
         * @return
         * @throws NyARException
         */
        public void makeFromReferenceImage(double i_x, double i_y, NyARDoubleMatrix44 i_ref_ctrans, INyARCameraDistortionFactor i_ref_dist_factor, NyARNftIsetFile.ReferenceImage i_source)
        {
            int[]             img      = this.img;
            int               img1_ptr = 0;
            int               k        = 0;
            int               sum2     = 0;
            int               sum      = 0;
            NyARDoublePoint2d ideal    = this.__in;

            for (int j = -(this.yts); j <= this.yts; j++)
            {
                for (int i = -(this.xts); i <= this.xts; i++)
                {
                    i_ref_dist_factor.observ2Ideal(i_x + i * AR2_TEMP_SCALE, i_y + j * AR2_TEMP_SCALE, ideal);
                    double ideal_x = ideal.x;
                    double ideal_y = ideal.y;
                    //ar2ScreenCoord2MarkerCoord(in.x,in.y,i_ref_ctrans,in);の展開
                    double c11 = i_ref_ctrans.m20 * ideal_x - i_ref_ctrans.m00;
                    double c12 = i_ref_ctrans.m21 * ideal_x - i_ref_ctrans.m01;
                    double c21 = i_ref_ctrans.m20 * ideal_y - i_ref_ctrans.m10;
                    double c22 = i_ref_ctrans.m21 * ideal_y - i_ref_ctrans.m11;
                    double b1  = i_ref_ctrans.m03 - i_ref_ctrans.m23 * ideal_x;
                    double b2  = i_ref_ctrans.m13 - i_ref_ctrans.m23 * ideal_y;
                    double m   = c11 * c22 - c12 * c21;
                    //public int ar2GetImageValue(double sx, double sy) throws NyARExceptionの展開
                    {
                        int ix = (int)((((c22 * b1 - c12 * b2) / m) * i_source.dpi / 25.4f) + 0.5);
                        int iy = (int)((i_source.height - (((c11 * b2 - c21 * b1) / m) * i_source.dpi) / 25.4f) + 0.5);

                        //座標計算と値取得は分けよう。
                        if (ix < 0 || ix >= i_source.width || iy < 0 || iy >= i_source.height)
                        {
                            img[img1_ptr] = AR2_TEMPLATE_NULL_PIXEL;
                        }
                        else
                        {
                            int ret = img[img1_ptr] = i_source.img[iy * i_source.width + ix];
                            sum2 += ret * ret;
                            sum  += ret;
                            k++;
                        }
                        //byte値はint化
                    }
                    img1_ptr++;
                }
            }
            int vlen = sum2 - sum * sum / k;

            this.vlen         = (int)Math.Sqrt((double)(vlen));
            this.sum_of_img   = sum;
            this.valid_pixels = k;
            return;
        }
Example #18
0
        /**
         * 透視変換パラメータを行列から復元します。
         * @param o_value
         * @return
         * 値をセットしたo_valueを返します。
         */
        public FrustumParam getFrustumParam(FrustumParam o_value)
        {
            double             near;
            NyARDoubleMatrix44 mat = this._frustum_rh;

            o_value.far    = mat.m23 / (mat.m22 + 1);
            o_value.near   = near = mat.m23 / (mat.m22 - 1);
            o_value.left   = (mat.m02 - 1) * near / mat.m00;
            o_value.right  = (mat.m02 + 1) * near / mat.m00;
            o_value.bottom = (mat.m12 - 1) * near / mat.m11;
            o_value.top    = (mat.m12 + 1) * near / mat.m11;
            return(o_value);
        }
        /**
         * インスタンスの値とi_matの値が同一かを返します。
         */
        override public bool Equals(Object i_mat)
        {
            NyARDoubleMatrix44 m = (NyARDoubleMatrix44)i_mat;

            if (m.m00 == this.m00 && m.m01 == this.m01 && m.m02 == this.m02 && m.m03 == this.m03 &&
                m.m10 == this.m10 && m.m11 == this.m11 && m.m12 == this.m12 && m.m13 == this.m13 &&
                m.m20 == this.m20 && m.m21 == this.m21 && m.m22 == this.m22 && m.m23 == this.m23 &&
                m.m30 == this.m30 && m.m31 == this.m31 && m.m32 == this.m32 && m.m33 == this.m33)
            {
                return(true);
            }
            return(false);
        }
            /**
             * icpGetU_from_X_by_MatX2U関数
             * @param matX2U
             * @param coord3d
             * @return
             */
            public bool setXbyMatX2U(NyARDoubleMatrix44 matX2U, NyARDoublePoint3d coord3d)
            {
                double hx = matX2U.m00 * coord3d.x + matX2U.m01 * coord3d.y + matX2U.m02 * coord3d.z + matX2U.m03;
                double hy = matX2U.m10 * coord3d.x + matX2U.m11 * coord3d.y + matX2U.m12 * coord3d.z + matX2U.m13;
                double h  = matX2U.m20 * coord3d.x + matX2U.m21 * coord3d.y + matX2U.m22 * coord3d.z + matX2U.m23;

                if (h == 0.0)
                {
                    return(false);
                }
                this.x = hx / h;
                this.y = hy / h;
                return(true);
            }
Example #21
0
        /**
         * この関数は、スクリーン座標を撮像点座標に変換します。
         * 撮像点の座標系は、カメラ座標系になります。
         * <p>公式 -
         * この関数は、gluUnprojectのビューポートとモデルビュー行列を固定したものです。
         * 公式は、以下の物使用しました。
         * http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml
         * ARToolKitの座標系に合せて計算するため、OpenGLのunProjectとはix,iyの与え方が違います。画面上の座標をそのまま与えてください。
         * </p>
         * @param ix
         * スクリーン上の座標
         * @param iy
         * 画像上の座標
         * @param o_point_on_screen
         * 撮像点座標
         */
        public void unProject(double ix, double iy, NyARDoublePoint3d o_point_on_screen)
        {
            double             n   = (this._frustum_rh.m23 / (this._frustum_rh.m22 - 1));
            NyARDoubleMatrix44 m44 = this._inv_frustum_rh;
            double             v1  = (this._screen_size.w - ix - 1) * 2 / this._screen_size.w - 1.0;//ARToolKitのFrustramに合せてる。
            double             v2  = (this._screen_size.h - iy - 1) * 2 / this._screen_size.h - 1.0;
            double             v3  = 2 * n - 1.0;
            double             b   = 1 / (m44.m30 * v1 + m44.m31 * v2 + m44.m32 * v3 + m44.m33);

            o_point_on_screen.x = (m44.m00 * v1 + m44.m01 * v2 + m44.m02 * v3 + m44.m03) * b;
            o_point_on_screen.y = (m44.m10 * v1 + m44.m11 * v2 + m44.m12 * v3 + m44.m13) * b;
            o_point_on_screen.z = (m44.m20 * v1 + m44.m21 * v2 + m44.m22 * v3 + m44.m23) * b;
            return;
        }
Example #22
0
        /**
         * 画面上の点と原点を結ぶ直線と任意姿勢の平面の交差点を、平面の座標系で取得します。
         * ARToolKitの本P175周辺の実装と同じです。
         * <p>
         * このAPIは繰り返し使用には最適化されていません。同一なi_matに繰り返しアクセスするときは、展開してください。
         * </p>
         * @param ix
         * スクリーン上の座標
         * @param iy
         * スクリーン上の座標
         * @param i_mat
         * 平面の姿勢行列です。
         * @param o_pos
         * 結果を受け取るオブジェクトです。
         * @return
         * 計算に成功すると、trueを返します。
         */
        public bool unProjectOnMatrix(double ix, double iy, NyARDoubleMatrix44 i_mat, NyARDoublePoint3d o_pos)
        {
            //交点をカメラ座標系で計算
            unProjectOnCamera(ix, iy, i_mat, o_pos);
            //座標系の変換
            NyARDoubleMatrix44 m = new NyARDoubleMatrix44();

            if (!m.inverse(i_mat))
            {
                return(false);
            }
            m.transform3d(o_pos, o_pos);
            return(true);
        }
        /**
         * この関数は、{@link NyARTransMatResult}の内容を、回転行列にセットします。
         * @param i_prev_result
         * セットする姿勢変換行列。
         */
        public virtual void initRotByPrevResult(NyARDoubleMatrix44 i_prev_result)
        {
            this.m00 = i_prev_result.m00;
            this.m01 = i_prev_result.m01;
            this.m02 = i_prev_result.m02;

            this.m10 = i_prev_result.m10;
            this.m11 = i_prev_result.m11;
            this.m12 = i_prev_result.m12;

            this.m20 = i_prev_result.m20;
            this.m21 = i_prev_result.m21;
            this.m22 = i_prev_result.m22;
            return;
        }
        /**
         * この関数は、{@link NyARTransMatResult}の内容を、回転行列にセットします。
         * @param i_prev_result
         * セットする姿勢変換行列。
         */
        public virtual void initRotByPrevResult(NyARDoubleMatrix44 i_prev_result)
        {

            this.m00 = i_prev_result.m00;
            this.m01 = i_prev_result.m01;
            this.m02 = i_prev_result.m02;

            this.m10 = i_prev_result.m10;
            this.m11 = i_prev_result.m11;
            this.m12 = i_prev_result.m12;

            this.m20 = i_prev_result.m20;
            this.m21 = i_prev_result.m21;
            this.m22 = i_prev_result.m22;
            return;
        }
        public void setFromMatrix(NyARDoubleMatrix44 i_mat)
        {
            // 最大成分を検索
            double elem0 = i_mat.m00 - i_mat.m11 - i_mat.m22 + 1.0;
            double elem1 = -i_mat.m00 + i_mat.m11 - i_mat.m22 + 1.0;
            double elem2 = -i_mat.m00 - i_mat.m11 + i_mat.m22 + 1.0;
            double elem3 = i_mat.m00 + i_mat.m11 + i_mat.m22 + 1.0;

            if (elem0 > elem1 && elem0 > elem2 && elem0 > elem3)
            {
                double v    = Math.Sqrt(elem0) * 0.5;
                double mult = 0.25 / v;
                this.x = v;
                this.y = ((i_mat.m10 + i_mat.m01) * mult);
                this.z = ((i_mat.m02 + i_mat.m20) * mult);
                this.w = ((i_mat.m21 - i_mat.m12) * mult);
            }
            else if (elem1 > elem2 && elem1 > elem3)
            {
                double v    = Math.Sqrt(elem1) * 0.5;
                double mult = 0.25 / v;
                this.x = ((i_mat.m10 + i_mat.m01) * mult);
                this.y = (v);
                this.z = ((i_mat.m21 + i_mat.m12) * mult);
                this.w = ((i_mat.m02 - i_mat.m20) * mult);
            }
            else if (elem2 > elem3)
            {
                double v    = Math.Sqrt(elem2) * 0.5;
                double mult = 0.25 / v;
                this.x = ((i_mat.m02 + i_mat.m20) * mult);
                this.y = ((i_mat.m21 + i_mat.m12) * mult);
                this.z = (v);
                this.w = ((i_mat.m10 - i_mat.m01) * mult);
            }
            else
            {
                double v    = Math.Sqrt(elem3) * 0.5;
                double mult = 0.25 / v;
                this.x = ((i_mat.m21 - i_mat.m12) * mult);
                this.y = ((i_mat.m02 - i_mat.m20) * mult);
                this.z = ((i_mat.m10 - i_mat.m01) * mult);
                this.w = v;
            }
            return;
        }
Example #26
0
        public void Test()
        {
            //AR用カメラパラメタファイルをロード
            NyARParam ap = NyARParam.createFromARParamFile(new StreamReader(camera_file));
            ap.changeScreenSize(320, 240);

            //AR用のパターンコードを読み出し	
            NyARCode code = NyARCode.createFromARPattFile(new StreamReader(code_file), 16, 16);

            //試験イメージの読み出し(320x240 BGRAのRAWデータ)
            StreamReader sr = new StreamReader(data_file);
            BinaryReader bs = new BinaryReader(sr.BaseStream);
            byte[] raw = bs.ReadBytes(320 * 240 * 4);
            
//            NyARBitmapRaster ra = new NyARBitmapRaster(320, 240);
//            Graphics g = Graphics.FromImage(ra.getBitmap());
//            g.DrawImage(new Bitmap("../../../../../data/320x240ABGR.png"), 0, 0);
            

            NyARRgbRaster ra = new NyARRgbRaster(320, 240,NyARBufferType.BYTE1D_B8G8R8X8_32,false);
            ra.wrapBuffer(raw);

            //1パターンのみを追跡するクラスを作成
            NyARSingleDetectMarker ar = NyARSingleDetectMarker.createInstance(ap, code, 80.0,NyARSingleDetectMarker.PF_NYARTOOLKIT);
            NyARDoubleMatrix44 result_mat = new NyARDoubleMatrix44();
            ar.setContinueMode(false);
            ar.detectMarkerLite(ra, 100);
            ar.getTransmationMatrix(result_mat);

            //マーカーを検出
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 1000; i++)
            {
                //変換行列を取得
                ar.detectMarkerLite(ra, 100);
                ar.getTransmationMatrix(result_mat);
            }
            Console.WriteLine(result_mat.m00 + "," + result_mat.m01 + ","+result_mat.m02+","+result_mat.m03);
            Console.WriteLine(result_mat.m10 + "," + result_mat.m11 + ","+result_mat.m12+","+result_mat.m13);
            Console.WriteLine(result_mat.m20 + "," + result_mat.m21 + ","+result_mat.m22+","+result_mat.m23);
            Console.WriteLine(result_mat.m30 + "," + result_mat.m31 + ","+result_mat.m32+","+result_mat.m33);
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds + "[ms]");
            return;
        }
Example #27
0
        /**
         * この関数は、スクリーン上の点と原点を結ぶ直線と、任意姿勢の平面の交差点を、カメラの座標系で取得します。
         * この座標は、カメラ座標系です。
         * @param ix
         * スクリーン上の座標
         * @param iy
         * スクリーン上の座標
         * @param i_mat
         * 平面の姿勢行列です。
         * @param o_pos
         * 結果を受け取るオブジェクトです。
         */
        public void unProjectOnCamera(double ix, double iy, NyARDoubleMatrix44 i_mat, NyARDoublePoint3d o_pos)
        {
            //画面→撮像点
            this.unProject(ix, iy, o_pos);
            //撮像点→カメラ座標系
            double nx = i_mat.m02;
            double ny = i_mat.m12;
            double nz = i_mat.m22;
            double mx = i_mat.m03;
            double my = i_mat.m13;
            double mz = i_mat.m23;
            double t  = (nx * mx + ny * my + nz * mz) / (nx * o_pos.x + ny * o_pos.y + nz * o_pos.z);

            o_pos.x = t * o_pos.x;
            o_pos.y = t * o_pos.y;
            o_pos.z = t * o_pos.z;
        }
 public void setFromMatrix(NyARDoubleMatrix44 i_mat)
 {
     // 最大成分を検索
     double elem0 = i_mat.m00 - i_mat.m11 - i_mat.m22 + 1.0;
     double elem1 = -i_mat.m00 + i_mat.m11 - i_mat.m22 + 1.0;
     double elem2 = -i_mat.m00 - i_mat.m11 + i_mat.m22 + 1.0;
     double elem3 = i_mat.m00 + i_mat.m11 + i_mat.m22 + 1.0;
     if (elem0 > elem1 && elem0 > elem2 && elem0 > elem3)
     {
         double v = Math.Sqrt(elem0) * 0.5;
         double mult = 0.25 / v;
         this.x = v;
         this.y = ((i_mat.m10 + i_mat.m01) * mult);
         this.z = ((i_mat.m02 + i_mat.m20) * mult);
         this.w = ((i_mat.m21 - i_mat.m12) * mult);
     }
     else if (elem1 > elem2 && elem1 > elem3)
     {
         double v = Math.Sqrt(elem1) * 0.5;
         double mult = 0.25 / v;
         this.x = ((i_mat.m10 + i_mat.m01) * mult);
         this.y = (v);
         this.z = ((i_mat.m21 + i_mat.m12) * mult);
         this.w = ((i_mat.m02 - i_mat.m20) * mult);
     }
     else if (elem2 > elem3)
     {
         double v = Math.Sqrt(elem2) * 0.5;
         double mult = 0.25 / v;
         this.x = ((i_mat.m02 + i_mat.m20) * mult);
         this.y = ((i_mat.m21 + i_mat.m12) * mult);
         this.z = (v);
         this.w = ((i_mat.m10 - i_mat.m01) * mult);
     }
     else
     {
         double v = Math.Sqrt(elem3) * 0.5;
         double mult = 0.25 / v;
         this.x = ((i_mat.m21 - i_mat.m12) * mult);
         this.y = ((i_mat.m02 - i_mat.m20) * mult);
         this.z = ((i_mat.m10 - i_mat.m01) * mult);
         this.w = v;
     }
     return;
 }
            /**
             * icpUpdateMat関数です。matXw2Xcへ値を出力します。
             * @param matXw2Xc
             * @param dS
             * double[6]
             * @return
             */
            public void makeMat(NyARDoubleMatrix44 matXw2Xc)
            {
                IcpMat44 mat = this.__mat;

                mat.setDeltaS(this);

                double w0, w1, w2, w3;

                w0 = matXw2Xc.m00;
                w1 = matXw2Xc.m01;
                w2 = matXw2Xc.m02;
                w3 = matXw2Xc.m03;

                //ji
                matXw2Xc.m00 = w0 * mat.m00 + w1 * mat.m10 + w2 * mat.m20;
                matXw2Xc.m01 = w0 * mat.m01 + w1 * mat.m11 + w2 * mat.m21;
                matXw2Xc.m02 = w0 * mat.m02 + w1 * mat.m12 + w2 * mat.m22;
                matXw2Xc.m03 = w0 * mat.m03 + w1 * mat.m13 + w2 * mat.m23 + w3;


                w0           = matXw2Xc.m10;
                w1           = matXw2Xc.m11;
                w2           = matXw2Xc.m12;
                w3           = matXw2Xc.m13;
                matXw2Xc.m10 = w0 * mat.m00 + w1 * mat.m10 + w2 * mat.m20;
                matXw2Xc.m11 = w0 * mat.m01 + w1 * mat.m11 + w2 * mat.m21;
                matXw2Xc.m12 = w0 * mat.m02 + w1 * mat.m12 + w2 * mat.m22;
                matXw2Xc.m13 = w0 * mat.m03 + w1 * mat.m13 + w2 * mat.m23 + w3;

                w0           = matXw2Xc.m20;
                w1           = matXw2Xc.m21;
                w2           = matXw2Xc.m22;
                w3           = matXw2Xc.m23;
                matXw2Xc.m20 = w0 * mat.m00 + w1 * mat.m10 + w2 * mat.m20;
                matXw2Xc.m21 = w0 * mat.m01 + w1 * mat.m11 + w2 * mat.m21;
                matXw2Xc.m22 = w0 * mat.m02 + w1 * mat.m12 + w2 * mat.m22;
                matXw2Xc.m23 = w0 * mat.m03 + w1 * mat.m13 + w2 * mat.m23 + w3;

                matXw2Xc.m30 = 0;
                matXw2Xc.m31 = 0;
                matXw2Xc.m32 = 0;
                matXw2Xc.m33 = 1;
                return;
            }
Example #30
0
        private static bool kpmUtilGetPose_binary(NyARParam i_cparam, FeaturePairStack matchData, NyARDoubleMatrix44 i_transmat, NyARTransMatResultParam i_resultparam)
        {
            NyARDoubleMatrix44 initMatXw2Xc = new NyARDoubleMatrix44();
            // ARdouble err;
            int i;

            if (matchData.getLength() < 4)
            {
                return(false);
            }
            NyARDoublePoint2d[] sCoord = NyARDoublePoint2d.createArray(matchData.getLength());
            NyARDoublePoint3d[] wCoord = NyARDoublePoint3d.createArray(matchData.getLength());
            for (i = 0; i < matchData.getLength(); i++)
            {
                sCoord[i].x = matchData.getItem(i).query.x;
                sCoord[i].y = matchData.getItem(i).query.y;

                wCoord[i].x = matchData.getItem(i).ref_.pos3d.x;
                wCoord[i].y = matchData.getItem(i).ref_.pos3d.y;
                wCoord[i].z = 0.0;
            }


            NyARIcpPlane icp_planer = new NyARIcpPlane(i_cparam.getPerspectiveProjectionMatrix());

            if (!icp_planer.icpGetInitXw2Xc_from_PlanarData(sCoord, wCoord, matchData.getLength(), initMatXw2Xc))
            {
                return(false);
            }

            /*
             * printf("--- Init pose ---\n"); for( int j = 0; j < 3; j++ ) { for( i = 0; i < 4; i++ ) printf(" %8.3f",
             * initMatXw2Xc[j][i]); printf("\n"); }
             */
            NyARIcpPoint icp_point = new NyARIcpPoint(i_cparam.getPerspectiveProjectionMatrix());

            icp_point.icpPoint(sCoord, wCoord, matchData.getLength(), initMatXw2Xc, i_transmat, i_resultparam);
            if (i_resultparam.last_error > 10.0f)
            {
                return(false);
            }
            return(true);
        }
Example #31
0
 /**
  * アプリケーションフレームワークのハンドラ(マーカ出現)
  */
 protected override void onEnterHandler(INyIdMarkerData i_code)
 {
     NyIdMarkerData_RawBit code = (NyIdMarkerData_RawBit)i_code;
     if (code.length > 4)
     {
         //4バイト以上の時はint変換しない。
         this.current_id = -1;//undefined_id
     }
     else
     {
         this.current_id = 0;
         //最大4バイト繋げて1個のint値に変換
         for (int i = 0; i < code.length; i++)
         {
             this.current_id = (this.current_id << 8) | code.packet[i];
         }
     }
     this.transmat = null;
 }
Example #32
0
        /**
         * この関数は、ARToolKitのcheck_dir関数に相当します。
         * 詳細は不明です。(ベクトルの開始/終了座標を指定して、ベクトルの方向を調整?)
         * @param i_start_vertex
         * 開始位置?
         * @param i_end_vertex
         * 終了位置?
         * @throws NyARException
         */
        public bool checkVectorByVertex(NyARDoublePoint2d i_start_vertex, NyARDoublePoint2d i_end_vertex)
        {
            double             h;
            NyARDoubleMatrix44 inv_cpara = this._inv_cpara;
            //final double[] world = __checkVectorByVertex_world;// [2][3];
            double world0 = inv_cpara.m00 * i_start_vertex.x * 10.0 + inv_cpara.m01 * i_start_vertex.y * 10.0 + inv_cpara.m02 * 10.0; // mat_a->m[0]*st[0]*10.0+
            double world1 = inv_cpara.m10 * i_start_vertex.x * 10.0 + inv_cpara.m11 * i_start_vertex.y * 10.0 + inv_cpara.m12 * 10.0; // mat_a->m[3]*st[0]*10.0+
            double world2 = inv_cpara.m20 * i_start_vertex.x * 10.0 + inv_cpara.m21 * i_start_vertex.y * 10.0 + inv_cpara.m22 * 10.0; // mat_a->m[6]*st[0]*10.0+
            double world3 = world0 + this.v1;
            double world4 = world1 + this.v2;
            double world5 = world2 + this.v3;
            // </Optimize>

            NyARPerspectiveProjectionMatrix cmat = this._projection_mat_ref;

            h = cmat.m20 * world0 + cmat.m21 * world1 + cmat.m22 * world2;
            if (h == 0.0)
            {
                return(false);
            }
            double camera0 = (cmat.m00 * world0 + cmat.m01 * world1 + cmat.m02 * world2) / h;
            double camera1 = (cmat.m10 * world0 + cmat.m11 * world1 + cmat.m12 * world2) / h;

            //h = cpara[2 * 4 + 0] * world3 + cpara[2 * 4 + 1] * world4 + cpara[2 * 4 + 2] * world5;
            h = cmat.m20 * world3 + cmat.m21 * world4 + cmat.m22 * world5;
            if (h == 0.0)
            {
                return(false);
            }
            double camera2 = (cmat.m00 * world3 + cmat.m01 * world4 + cmat.m02 * world5) / h;
            double camera3 = (cmat.m10 * world3 + cmat.m11 * world4 + cmat.m12 * world5) / h;

            double v = (i_end_vertex.x - i_start_vertex.x) * (camera2 - camera0) + (i_end_vertex.y - i_start_vertex.y) * (camera3 - camera1);

            if (v < 0)
            {
                this.v1 = -this.v1;
                this.v2 = -this.v2;
                this.v3 = -this.v3;
            }
            return(true);
        }
Example #33
0
 /**
  * この関数は、オブジェクトの内容をインスタンスにコピーします。
  * @param i_value
  * コピー元のオブジェクト
  */
 public void setValue(NyARDoubleMatrix44 i_value)
 {
     this.m00 = i_value.m00;
     this.m01 = i_value.m01;
     this.m02 = i_value.m02;
     this.m03 = i_value.m03;
     this.m10 = i_value.m10;
     this.m11 = i_value.m11;
     this.m12 = i_value.m12;
     this.m13 = i_value.m13;
     this.m20 = i_value.m20;
     this.m21 = i_value.m21;
     this.m22 = i_value.m22;
     this.m23 = i_value.m23;
     this.m30 = i_value.m30;
     this.m31 = i_value.m31;
     this.m32 = i_value.m32;
     this.m33 = i_value.m33;
     return;
 }
        public void icpGetInitXw2XcSub(NyARDoubleMatrix44 rot,
                                       NyARDoublePoint2d[] pos2d, NyARDoublePoint3d[] ppos3d, int num,
                                       NyARDoubleMatrix44 conv)
        {
            NyARDoublePoint3d  off  = makeOffset(ppos3d, num, this.__off);
            NyARDoubleMatrix33 matd = makeMatD(this._cparam, pos2d, num, this.__matd);

            double[] mate = makeMatE(this._cparam, rot, pos2d, ppos3d, off, num, this.__mate);

            conv.setValue(rot);
            conv.m03 = matd.m00 * mate[0] + matd.m01 * mate[1] + matd.m02 * mate[2];
            conv.m13 = matd.m10 * mate[0] + matd.m11 * mate[1] + matd.m12 * mate[2];
            conv.m23 = matd.m20 * mate[0] + matd.m21 * mate[1] + matd.m22 * mate[2];

            conv.m03 = conv.m00 * off.x + conv.m01 * off.y + conv.m02 * off.z + conv.m03;
            conv.m13 = conv.m10 * off.x + conv.m11 * off.y + conv.m12 * off.z + conv.m13;
            conv.m23 = conv.m20 * off.x + conv.m21 * off.y + conv.m22 * off.z + conv.m23;

            return;
        }
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * 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);
        }
Example #36
0
		/**
		 * この関数は、ARToolKitスタイルのProjectionMatrixから、 CameraFrustamを計算します。
		 * @param i_promat
		 * @param i_size
		 * スクリーンサイズを指定します。
		 * @param i_scale
		 * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。
		 * @param i_near
		 * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。
		 * @param i_far
		 * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。
		 * @param o_gl_projection
		 * {@link #toCameraFrustumRH(NyARParam i_arparam,double i_scale,double i_near,double i_far,double[] o_gl_projection)}を参照。
		 */
		public static void toCameraFrustumRH(NyARPerspectiveProjectionMatrix i_promat,NyARIntSize i_size,double i_scale,double i_near,double i_far,ref Matrix4x4 o_mat)
		{
			NyARDoubleMatrix44 m=new NyARDoubleMatrix44();
			i_promat.makeCameraFrustumRH(i_size.w,i_size.h,i_near*i_scale,i_far*i_scale,m);
			o_mat.m00=(float)m.m00;
			o_mat.m01=(float)m.m01;
			o_mat.m02=(float)m.m02;
			o_mat.m03=(float)m.m03;
			o_mat.m10=(float)m.m10;
			o_mat.m11=(float)m.m11;
			o_mat.m12=(float)m.m12;
			o_mat.m13=(float)m.m13;
			o_mat.m20=(float)m.m20;
			o_mat.m21=(float)m.m21;
			o_mat.m22=(float)m.m22;
			o_mat.m23=(float)m.m23;
			o_mat.m30=(float)m.m30;
			o_mat.m31=(float)m.m31;
			o_mat.m32=(float)m.m32;
			o_mat.m33=(float)m.m33;
			return;
		}
            /**
             * icpGetJ_U_Xc
             * @param J_U_Xc
             * @param matXc2U
             * @param cameraCoord
             * @return
             */
            public bool setXc2UXc(NyARDoubleMatrix44 matXc2U, double Xcx, double Xcy, double Xcz)
            {
                double w1, w2, w3, w3_w3;

                w1 = matXc2U.m00 * Xcx + matXc2U.m01 * Xcy + matXc2U.m02 * Xcz + matXc2U.m03;
                w2 = matXc2U.m10 * Xcx + matXc2U.m11 * Xcy + matXc2U.m12 * Xcz + matXc2U.m13;
                w3 = matXc2U.m20 * Xcx + matXc2U.m21 * Xcy + matXc2U.m22 * Xcz + matXc2U.m23;

                if (w3 == 0.0)
                {
                    return(false);
                }

                w3_w3    = w3 * w3;
                this.m00 = (matXc2U.m00 * w3 - matXc2U.m20 * w1) / w3_w3;
                this.m01 = (matXc2U.m01 * w3 - matXc2U.m21 * w1) / w3_w3;
                this.m02 = (matXc2U.m02 * w3 - matXc2U.m22 * w1) / w3_w3;
                this.m10 = (matXc2U.m10 * w3 - matXc2U.m20 * w2) / w3_w3;
                this.m11 = (matXc2U.m11 * w3 - matXc2U.m21 * w2) / w3_w3;
                this.m12 = (matXc2U.m12 * w3 - matXc2U.m22 * w2) / w3_w3;
                return(true);
            }
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * 計算に過去の履歴を使う点が、{@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;
        }
Example #39
0
 /**
  * この関数は、スクリーン上の点と原点を結ぶ直線と、任意姿勢の平面の交差点を、カメラの座標系で取得します。
  * この座標は、カメラ座標系です。
  * @param ix
  * スクリーン上の座標
  * @param iy
  * スクリーン上の座標
  * @param i_mat
  * 平面の姿勢行列です。
  * @param o_pos
  * 結果を受け取るオブジェクトです。
  */
 public void unProjectOnCamera(double ix, double iy, NyARDoubleMatrix44 i_mat, NyARDoublePoint3d o_pos)
 {
     //画面→撮像点
     this.unProject(ix, iy, o_pos);
     //撮像点→カメラ座標系
     double nx = i_mat.m02;
     double ny = i_mat.m12;
     double nz = i_mat.m22;
     double mx = i_mat.m03;
     double my = i_mat.m13;
     double mz = i_mat.m23;
     double t = (nx * mx + ny * my + nz * mz) / (nx * o_pos.x + ny * o_pos.y + nz * o_pos.z);
     o_pos.x = t * o_pos.x;
     o_pos.y = t * o_pos.y;
     o_pos.z = t * o_pos.z;
 }
 /**
  * 自己コールバック関数です。
  * 継承したクラスで、マーカ更新時の処理を実装してください。
  * 引数の値の有効期間は、関数が終了するまでです。
  * @param i_square
  * 現在のマーカ検出位置です。
  * @param o_result
  * 現在の姿勢変換行列です。
  */
 protected abstract void onUpdateHandler(NyARSquare i_square, NyARDoubleMatrix44 o_result);
        public override bool icpPoint(NyARDoublePoint2d[] screenCoord,
            NyARDoublePoint3d[] worldCoord, int num,
            NyARDoubleMatrix44 initMatXw2Xc, NyARDoubleMatrix44 o_matxw2xc, NyARTransMatResultParam o_result_param)
        {
            Debug.Assert(num >= 4);
            double err0 = 0, err1;

            NyARIcpUtils.U u = this.__u;
            NyARIcpUtils.DeltaS dS = this.__dS;
            //ワークオブジェクトのリセット		
            if (this.__jus.getArraySize() < num)
            {
                this.__jus = new NyARIcpUtils.JusStack(num);
                this.__E = new double[num];
                this.__E2 = new double[num];
                this.__du = NyARDoublePoint2d.createArray(num);
            }
            NyARIcpUtils.JusStack jus = this.__jus;
            double[] E = this.__E;
            double[] E2 = this.__E2;
            NyARDoublePoint2d[] du = this.__du;
            NyARDoubleMatrix44 matXw2U = this.__matXw2U;

            int inlierNum = (int)(num * this.getInlierProbability()) - 1;
            if (inlierNum < 3)
            {
                inlierNum = 3;
            }

		    o_matxw2xc.setValue(initMatXw2Xc);
		    for (int i = 0;; i++) {
    			matXw2U.mul(this._ref_matXc2U, o_matxw2xc);
                for (int j = 0; j < num; j++)
                {
                    if (!u.setXbyMatX2U(matXw2U, worldCoord[j]))
                    {
                        return false;
                    }
                    double dx = screenCoord[j].x - u.x;
                    double dy = screenCoord[j].y - u.y;
                    du[j].x = dx;
                    du[j].y = dy;
                    E[j] = E2[j] = dx * dx + dy * dy;
                }
                Array.Sort(E2, 0, num);// qsort(E2, data->num, sizeof(ARdouble), compE);
                double K2 = E2[inlierNum] * K2_FACTOR;
                if (K2 < 16.0)
                {
                    K2 = 16.0;
                }
                err1 = 0.0;
                for (int j = 0; j < num; j++)
                {
                    if (E2[j] > K2)
                    {
                        err1 += K2 / 6.0;
                    }
                    else
                    {
                        err1 += K2 / 6.0 * (1.0 - (1.0 - E2[j] / K2) * (1.0 - E2[j] / K2) * (1.0 - E2[j] / K2));
                    }
                }
                err1 /= num;

                if (err1 < this.breakLoopErrorThresh)
                {
                    break;
                }
                if (i > 0 && err1 < this.breakLoopErrorThresh2 && err1 / err0 > this.breakLoopErrorRatioThresh)
                {
                    break;
                }
                if (i == this._maxLoop)
                {
                    break;
                }
                err0 = err1;
                jus.clear();
                for (int j = 0; j < num; j++)
                {
                    if (E[j] <= K2)
                    {
                        double W = (1.0 - E[j] / K2) * (1.0 - E[j] / K2);
	    				if(!jus.push(this._ref_matXc2U,o_matxw2xc, worldCoord[j],du[j],W))
                        {
                            return false;
                        }
                    }
                }
                if (jus.getLength() < 3)
                {
                    return false;
                }
                if (!dS.setJusArray(jus))
                {
                    return false;
                }
			    dS.makeMat(o_matxw2xc);
		    }
		    if(o_result_param!=null){
			    o_result_param.last_error=err1;
		    }
            return true;
        }
Example #42
0
 /**
  * この関数は、カメラパラメータから右手系の視錐台を作ります。
  * <p>注意 -
  * この処理は低速です。繰り返しの使用はできるだけ避けてください。
  * </p>
  * @param i_dist_min
  * 視錐台のnear point(mm指定)
  * @param i_dist_max
  * 視錐台のfar point(mm指定)
  * @param o_frustum
  * 視錐台を受け取る配列。
  * @see NyARPerspectiveProjectionMatrix#makeCameraFrustumRH
  */
 public void makeCameraFrustumRH(double i_dist_min, double i_dist_max, NyARDoubleMatrix44 o_frustum)
 {
     this._projection_matrix.makeCameraFrustumRH(this._screen_size.w, this._screen_size.h, i_dist_min, i_dist_max, o_frustum);
     return;
 }
        /**
         * この関数は、行列同士の掛け算をして、インスタンスに格納します。
         * i_mat_lとi_mat_rには、thisを指定しないでください。
         * @param i_mat_l
         * 左成分の行列
         * @param i_mat_r
         * 右成分の行列
         */
        public void mul(NyARDoubleMatrix44 i_mat_l, NyARDoubleMatrix44 i_mat_r)
        {
            Debug.Assert(this != i_mat_l);
            Debug.Assert(this != i_mat_r);
            this.m00 = i_mat_l.m00 * i_mat_r.m00 + i_mat_l.m01 * i_mat_r.m10 + i_mat_l.m02 * i_mat_r.m20 + i_mat_l.m03 * i_mat_r.m30;
            this.m01 = i_mat_l.m00 * i_mat_r.m01 + i_mat_l.m01 * i_mat_r.m11 + i_mat_l.m02 * i_mat_r.m21 + i_mat_l.m03 * i_mat_r.m31;
            this.m02 = i_mat_l.m00 * i_mat_r.m02 + i_mat_l.m01 * i_mat_r.m12 + i_mat_l.m02 * i_mat_r.m22 + i_mat_l.m03 * i_mat_r.m32;
            this.m03 = i_mat_l.m00 * i_mat_r.m03 + i_mat_l.m01 * i_mat_r.m13 + i_mat_l.m02 * i_mat_r.m23 + i_mat_l.m03 * i_mat_r.m33;

            this.m10 = i_mat_l.m10 * i_mat_r.m00 + i_mat_l.m11 * i_mat_r.m10 + i_mat_l.m12 * i_mat_r.m20 + i_mat_l.m13 * i_mat_r.m30;
            this.m11 = i_mat_l.m10 * i_mat_r.m01 + i_mat_l.m11 * i_mat_r.m11 + i_mat_l.m12 * i_mat_r.m21 + i_mat_l.m13 * i_mat_r.m31;
            this.m12 = i_mat_l.m10 * i_mat_r.m02 + i_mat_l.m11 * i_mat_r.m12 + i_mat_l.m12 * i_mat_r.m22 + i_mat_l.m13 * i_mat_r.m32;
            this.m13 = i_mat_l.m10 * i_mat_r.m03 + i_mat_l.m11 * i_mat_r.m13 + i_mat_l.m12 * i_mat_r.m23 + i_mat_l.m13 * i_mat_r.m33;

            this.m20 = i_mat_l.m20 * i_mat_r.m00 + i_mat_l.m21 * i_mat_r.m10 + i_mat_l.m22 * i_mat_r.m20 + i_mat_l.m23 * i_mat_r.m30;
            this.m21 = i_mat_l.m20 * i_mat_r.m01 + i_mat_l.m21 * i_mat_r.m11 + i_mat_l.m22 * i_mat_r.m21 + i_mat_l.m23 * i_mat_r.m31;
            this.m22 = i_mat_l.m20 * i_mat_r.m02 + i_mat_l.m21 * i_mat_r.m12 + i_mat_l.m22 * i_mat_r.m22 + i_mat_l.m23 * i_mat_r.m32;
            this.m23 = i_mat_l.m20 * i_mat_r.m03 + i_mat_l.m21 * i_mat_r.m13 + i_mat_l.m22 * i_mat_r.m23 + i_mat_l.m23 * i_mat_r.m33;

            this.m30 = i_mat_l.m30 * i_mat_r.m00 + i_mat_l.m31 * i_mat_r.m10 + i_mat_l.m32 * i_mat_r.m20 + i_mat_l.m33 * i_mat_r.m30;
            this.m31 = i_mat_l.m30 * i_mat_r.m01 + i_mat_l.m31 * i_mat_r.m11 + i_mat_l.m32 * i_mat_r.m21 + i_mat_l.m33 * i_mat_r.m31;
            this.m32 = i_mat_l.m30 * i_mat_r.m02 + i_mat_l.m31 * i_mat_r.m12 + i_mat_l.m32 * i_mat_r.m22 + i_mat_l.m33 * i_mat_r.m32;
            this.m33 = i_mat_l.m30 * i_mat_r.m03 + i_mat_l.m31 * i_mat_r.m13 + i_mat_l.m32 * i_mat_r.m23 + i_mat_l.m33 * i_mat_r.m33;
            return;
        }
        /**
         * 
         * @param iw_rotmat
         * @param iw_transvec
         * @param i_solver
         * @param i_offset_3d
         * @param i_2d_vertex
         * @param i_err_threshold
         * @param o_result
         * @return
         * @
         */
	    private double optimize(NyARRotMatrix iw_rotmat,NyARDoublePoint3d iw_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex,double i_err_threshold,NyARDoubleMatrix44 o_result)
        {
            //System.out.println("START");
            NyARDoublePoint3d[] vertex_3d = this.__transMat_vertex_3d;
            //初期のエラー値を計算
            double min_err = errRate(iw_rotmat, iw_transvec, i_offset_3d, i_2d_vertex, 4, vertex_3d);
            o_result.setValue(iw_rotmat, iw_transvec);

            for (int i = 0; i < 5; i++)
            {
                //変換行列の最適化
                this._mat_optimize.modifyMatrix(iw_rotmat, iw_transvec, i_offset_3d, i_2d_vertex, 4);
                double err = errRate(iw_rotmat, iw_transvec, i_offset_3d, i_2d_vertex, 4, vertex_3d);
                //System.out.println("E:"+err);
                if (min_err - err < i_err_threshold)
                {
                    //System.out.println("BREAK");
                    break;
                }
                i_solver.solveTransportVector(vertex_3d, iw_transvec);
                o_result.setValue(iw_rotmat, iw_transvec);
                min_err = err;
            }
            //System.out.println("END");
            return min_err;
        }
Example #45
0
	    /**
	     * カメラ座標系の4頂点でかこまれる領域から、RGB画像をo_rasterに取得します。
	     * @param i_vertex
	     * @param i_matrix
	     * i_vertexに適応する変換行列。
	     * ターゲットの姿勢行列を指定すると、ターゲット座標系になります。不要ならばnullを設定してください。
	     * @param i_resolution
	     * @param o_raster
	     * @return
	     * @throws NyARException
	     */
        public bool getRgbPatt3d(NyARRealitySource i_src, NyARDoublePoint3d[] i_vertex, NyARDoubleMatrix44 i_matrix, int i_resolution, INyARRgbRaster o_raster)
	    {
		    NyARDoublePoint2d[] vx=NyARDoublePoint2d.createArray(4);
		    if(i_matrix!=null){
			    //姿勢変換してから射影変換
			    NyARDoublePoint3d v3d=new NyARDoublePoint3d();
			    for(int i=3;i>=0;i--){
				    i_matrix.transform3d(i_vertex[i],v3d);
				    this._ref_prjmat.project(v3d,vx[i]);
			    }
		    }else{
			    //射影変換のみ
			    for(int i=3;i>=0;i--){
				    this._ref_prjmat.project(i_vertex[i],vx[i]);
			    }
		    }
		    //パターンの取得
            return i_src.refPerspectiveRasterReader().copyPatt(vx, 0, 0, i_resolution, o_raster);
	    }
        /**
         * この関数は、逆行列を計算して、インスタンスにセットします。
         * @param i_src
         * 逆行列を計算するオブジェクト。thisを指定できます。
         * @return
         * 逆行列を得られると、trueを返します。
         */
        public bool inverse(NyARDoubleMatrix44 i_src)
        {
            double a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41, a42, a43, a44;
            double b11, b12, b13, b14, b21, b22, b23, b24, b31, b32, b33, b34, b41, b42, b43, b44;
            double t1, t2, t3, t4, t5, t6;
            a11 = i_src.m00; a12 = i_src.m01; a13 = i_src.m02; a14 = i_src.m03;
            a21 = i_src.m10; a22 = i_src.m11; a23 = i_src.m12; a24 = i_src.m13;
            a31 = i_src.m20; a32 = i_src.m21; a33 = i_src.m22; a34 = i_src.m23;
            a41 = i_src.m30; a42 = i_src.m31; a43 = i_src.m32; a44 = i_src.m33;

            t1 = a33 * a44 - a34 * a43;
            t2 = a34 * a42 - a32 * a44;
            t3 = a32 * a43 - a33 * a42;
            t4 = a34 * a41 - a31 * a44;
            t5 = a31 * a43 - a33 * a41;
            t6 = a31 * a42 - a32 * a41;

            b11 = a22 * t1 + a23 * t2 + a24 * t3;
            b21 = -(a23 * t4 + a24 * t5 + a21 * t1);
            b31 = a24 * t6 - a21 * t2 + a22 * t4;
            b41 = -(a21 * t3 - a22 * t5 + a23 * t6);

            t1 = a43 * a14 - a44 * a13;
            t2 = a44 * a12 - a42 * a14;
            t3 = a42 * a13 - a43 * a12;
            t4 = a44 * a11 - a41 * a14;
            t5 = a41 * a13 - a43 * a11;
            t6 = a41 * a12 - a42 * a11;

            b12 = -(a32 * t1 + a33 * t2 + a34 * t3);
            b22 = a33 * t4 + a34 * t5 + a31 * t1;
            b32 = -(a34 * t6 - a31 * t2 + a32 * t4);
            b42 = a31 * t3 - a32 * t5 + a33 * t6;

            t1 = a13 * a24 - a14 * a23;
            t2 = a14 * a22 - a12 * a24;
            t3 = a12 * a23 - a13 * a22;
            t4 = a14 * a21 - a11 * a24;
            t5 = a11 * a23 - a13 * a21;
            t6 = a11 * a22 - a12 * a21;

            b13 = a42 * t1 + a43 * t2 + a44 * t3;
            b23 = -(a43 * t4 + a44 * t5 + a41 * t1);
            b33 = a44 * t6 - a41 * t2 + a42 * t4;
            b43 = -(a41 * t3 - a42 * t5 + a43 * t6);

            t1 = a23 * a34 - a24 * a33;
            t2 = a24 * a32 - a22 * a34;
            t3 = a22 * a33 - a23 * a32;
            t4 = a24 * a31 - a21 * a34;
            t5 = a21 * a33 - a23 * a31;
            t6 = a21 * a32 - a22 * a31;

            b14 = -(a12 * t1 + a13 * t2 + a14 * t3);
            b24 = a13 * t4 + a14 * t5 + a11 * t1;
            b34 = -(a14 * t6 - a11 * t2 + a12 * t4);
            b44 = a11 * t3 - a12 * t5 + a13 * t6;

            double det_1 = (a11 * b11 + a21 * b12 + a31 * b13 + a41 * b14);
            if (det_1 == 0)
            {
                return false;
            }
            det_1 = 1 / det_1;

            this.m00 = b11 * det_1;
            this.m01 = b12 * det_1;
            this.m02 = b13 * det_1;
            this.m03 = b14 * det_1;

            this.m10 = b21 * det_1;
            this.m11 = b22 * det_1;
            this.m12 = b23 * det_1;
            this.m13 = b24 * det_1;

            this.m20 = b31 * det_1;
            this.m21 = b32 * det_1;
            this.m22 = b33 * det_1;
            this.m23 = b34 * det_1;

            this.m30 = b41 * det_1;
            this.m31 = b42 * det_1;
            this.m32 = b43 * det_1;
            this.m33 = b44 * det_1;

            return true;
        }
        /**
         * この関数は、検出したマーカーの変換行列を計算して、o_resultへ値を返します。
         * 直前に実行した{@link #detectMarkerLite}が成功していないと使えません。
         * @param o_result
         * 変換行列を受け取るオブジェクト。
         * @
         */
	    public void getTransmat(NyARDoubleMatrix44 o_result)
	    {
		    // 一番一致したマーカーの位置とかその辺を計算
		    if (this._is_continue){
			    //履歴が使えそうか判定
			    if(this._last_input_mat==o_result){
				    if(this._transmat.transMatContinue(this._square,this._offset,o_result, this._last_result_param.last_error,o_result, this._last_result_param)){
					    return;
				    }
			    }
		    }
		    //履歴使えないor継続認識失敗
		    this._transmat.transMat(this._square,this._offset,o_result,this._last_result_param);
		    this._last_input_mat=o_result;
		    return;
	    }
Example #48
0
 /**
  * アプリケーションフレームワークのハンドラ(マーカ消滅)
  */
 protected override void onLeaveHandler()
 {
     this.current_id = -1;
     this.transmat = null;
     return;
 }
Example #49
0
 /* カメラのプロジェクションMatrix(RH)を返します。
  * このMatrixはMicrosoft.DirectX.Direct3d.Device.Transform.Projectionに設定できます。
  */
 public static void toCameraFrustumRH(NyARPerspectiveProjectionMatrix i_promat, NyARIntSize i_size, double i_scale, double i_near, double i_far, ref Matrix o_d3d_projection)
 {
     NyARDoubleMatrix44 m = new NyARDoubleMatrix44();
     i_promat.makeCameraFrustumRH(i_size.w, i_size.h, i_near * i_scale, i_far * i_scale, m);
     NyARD3dUtil.mat44ToD3dMatrixT(m, ref o_d3d_projection);
     return;
 }
Example #50
0
 /**
  * アプリケーションフレームワークのハンドラ(マーカ更新)
  */
 protected override void onUpdateHandler(NyARSquare i_square, NyARDoubleMatrix44 result)
 {
     NyARD3dUtil.toD3dCameraView(result, 1f, ref this.transmat);
 }
Example #51
0
        /**
         * Direct3d形式のカメラビュー行列に変換します。
         */
        public static void toD3dCameraView(NyARDoubleMatrix44 i_ny_result, float i_scale, ref Matrix o_result)
        {
            Matrix m;
            m.M11 = (float)i_ny_result.m00;
            m.M12 = -(float)i_ny_result.m10;
            m.M13 = -(float)i_ny_result.m20;
            m.M14 = 0;
            m.M21 = (float)i_ny_result.m01;
            m.M22 = -(float)i_ny_result.m11;
            m.M23 = -(float)i_ny_result.m21;
            m.M24 = 0;
            m.M31 = (float)i_ny_result.m02;
            m.M32 = -(float)i_ny_result.m12;
            m.M33 = -(float)i_ny_result.m22;
            m.M34 = 0;
            float scale =(1 / i_scale);
            m.M41 = (float)i_ny_result.m03 * scale;
            m.M42 = -(float)i_ny_result.m13 * scale;
            m.M43 = -(float)i_ny_result.m23 * scale;
            m.M44 = 1;

            o_result = m;
            return;
        }
Example #52
0
        public static void mat44ToD3dMatrixT(NyARDoubleMatrix44 i_src, ref Matrix o_dst)
        {
            o_dst.M11 = (float)i_src.m00;
            o_dst.M21 = (float)i_src.m01;
            o_dst.M31 = (float)i_src.m02;
            o_dst.M41 = (float)i_src.m03;

            o_dst.M12 = (float)i_src.m10;
            o_dst.M22 = (float)i_src.m11;
            o_dst.M32 = (float)i_src.m12;
            o_dst.M42 = (float)i_src.m13;

            o_dst.M13 = (float)i_src.m20;
            o_dst.M23 = (float)i_src.m21;
            o_dst.M33 = (float)i_src.m22;
            o_dst.M43 = (float)i_src.m23;

            o_dst.M14 = (float)i_src.m30;
            o_dst.M24 = (float)i_src.m31;
            o_dst.M34 = (float)i_src.m32;
            o_dst.M44 = (float)i_src.m33;
            return;
        }
Example #53
0
 /**
  * この関数は、視錐台行列をインスタンスにセットします。
  * @param i_projection
  * ARToolKitスタイルの射影変換行列
  * @param i_width
  * スクリーンサイズです。
  * @param i_height
  * スクリーンサイズです。
  */
 public void setValue(NyARDoubleMatrix44 i_projection_mat, int i_width, int i_height)
 {
     this._frustum_rh.setValue(i_projection_mat);
     this._inv_frustum_rh.inverse(this._frustum_rh);
     this._screen_size.setValue(i_width, i_height);
 }
 /**
  * この関数は、オブジェクトの内容をインスタンスにコピーします。
  * @param i_value
  * コピー元のオブジェクト
  */
 public void setValue(NyARDoubleMatrix44 i_value)
 {
     this.m00 = i_value.m00;
     this.m01 = i_value.m01;
     this.m02 = i_value.m02;
     this.m03 = i_value.m03;
     this.m10 = i_value.m10;
     this.m11 = i_value.m11;
     this.m12 = i_value.m12;
     this.m13 = i_value.m13;
     this.m20 = i_value.m20;
     this.m21 = i_value.m21;
     this.m22 = i_value.m22;
     this.m23 = i_value.m23;
     this.m30 = i_value.m30;
     this.m31 = i_value.m31;
     this.m32 = i_value.m32;
     this.m33 = i_value.m33;
     return;
 }
 /**
  * @deprecated
  * {@link #getTransmat}
  */
 public void getTransmationMatrix(NyARDoubleMatrix44 o_result)
 {
     this.getTransmat(o_result);
     return;
 }
	    /**
	     * ターゲット座標系の4頂点でかこまれる領域を射影した平面から、RGB画像をo_rasterに取得します。
	     * @param i_vertex
	     * ターゲットのオフセットを基準値とした、頂点座標。要素数は4であること。(mm単位)
	     * @param i_matrix
	     * i_vertexに適応する変換行列。
	     * ターゲットの姿勢行列を指定すると、ターゲット座標系になります。不要ならばnullを設定してください。
	     * @param i_resolution
	     * 1ピクセルあたりのサンプリング値(n^2表現)
	     * @param o_raster
	     * 出力ラスタ
	     * @return
	     * @throws NyARException
	     * <p>メモ:この関数にはnewが残ってるので注意</p>
	     */
        public bool getRgbPatt3d(NyARRealitySource i_src, NyARDoublePoint3d[] i_vertex, NyARDoubleMatrix44 i_matrix, int i_resolution, INyARRgbRaster o_raster)
	    {
		    Debug.Assert(this._target_type==RT_KNOWN);
		    NyARDoublePoint2d[] da4=this._ref_pool._wk_da2_4;
		    NyARDoublePoint3d v3d=new NyARDoublePoint3d();
		    if(i_matrix!=null){
			    //姿勢変換してから射影変換
			    for(int i=3;i>=0;i--){
				    //姿勢を変更して射影変換
				    i_matrix.transform3d(i_vertex[i],v3d);
				    this._transform_matrix.transform3d(v3d,v3d);
				    this._ref_pool._ref_prj_mat.project(v3d,da4[i]);
			    }
		    }else{
			    //射影変換のみ
			    for(int i=3;i>=0;i--){
				    //姿勢を変更して射影変換
				    this._transform_matrix.transform3d(i_vertex[i],v3d);
				    this._ref_pool._ref_prj_mat.project(v3d,da4[i]);
			    }
		    }
		    //パターンの取得
		    return i_src.refPerspectiveRasterReader().copyPatt(da4,0,0,i_resolution, o_raster);
	    }
Example #57
0
 /**
  * 画面上の点と原点を結ぶ直線と任意姿勢の平面の交差点を、平面の座標系で取得します。
  * ARToolKitの本P175周辺の実装と同じです。
  * <p>
  * このAPIは繰り返し使用には最適化されていません。同一なi_matに繰り返しアクセスするときは、展開してください。
  * </p>
  * @param ix
  * スクリーン上の座標
  * @param iy
  * スクリーン上の座標
  * @param i_mat
  * 平面の姿勢行列です。
  * @param o_pos
  * 結果を受け取るオブジェクトです。
  * @return
  * 計算に成功すると、trueを返します。
  */
 public bool unProjectOnMatrix(double ix, double iy, NyARDoubleMatrix44 i_mat, NyARDoublePoint3d o_pos)
 {
     //交点をカメラ座標系で計算
     unProjectOnCamera(ix, iy, i_mat, o_pos);
     //座標系の変換
     NyARDoubleMatrix44 m = new NyARDoubleMatrix44();
     if (!m.inverse(i_mat))
     {
         return false;
     }
     m.transform3d(o_pos, o_pos);
     return true;
 }
        /**
         * 右手系の視錐台を作ります。
         * この視錐台は、ARToolKitのarglCameraViewRHの作る視錐台と同じです。
         * @param i_screen_width
         * スクリーンサイズを指定します。
         * @param i_screen_height
         * スクリーンサイズを指定します。
         * @param i_dist_min
         * near pointを指定します(mm単位)
         * @param i_dist_max
         * far pointを指定します(mm単位)
         * @param o_frustum
         * 視錐台の格納先オブジェクトを指定します。
         */
        public void makeCameraFrustumRH(double i_screen_width, double i_screen_height, double i_dist_min, double i_dist_max, NyARDoubleMatrix44 o_frustum)
        {
            NyARMat trans_mat = new NyARMat(3, 4);
            NyARMat icpara_mat = new NyARMat(3, 4);
            double[][] p = ArrayUtils.newDouble2dArray(3, 3);
            int i;

            this.decompMat(icpara_mat, trans_mat);

            double[][] icpara = icpara_mat.getArray();
            double[][] trans = trans_mat.getArray();
            for (i = 0; i < 4; i++)
            {
                icpara[1][i] = (i_screen_height - 1) * (icpara[2][i]) - icpara[1][i];
            }
            p[0][0] = icpara[0][0] / icpara[2][2];
            p[0][1] = icpara[0][1] / icpara[2][2];
            p[0][2] = icpara[0][2] / icpara[2][2];

            p[1][0] = icpara[1][0] / icpara[2][2];
            p[1][1] = icpara[1][1] / icpara[2][2];
            p[1][2] = icpara[1][2] / icpara[2][2];

            p[2][0] = icpara[2][0] / icpara[2][2];
            p[2][1] = icpara[2][1] / icpara[2][2];
            p[2][2] = icpara[2][2] / icpara[2][2];

            double q00, q01, q02, q03, q10, q11, q12, q13, q20, q21, q22, q23, q30, q31, q32, q33;

            //視錐台への変換
            q00 = (2.0 * p[0][0] / (i_screen_width - 1));
            q01 = (2.0 * p[0][1] / (i_screen_width - 1));
            q02 = -((2.0 * p[0][2] / (i_screen_width - 1)) - 1.0);
            q03 = 0.0;
            o_frustum.m00 = q00 * trans[0][0] + q01 * trans[1][0] + q02 * trans[2][0];
            o_frustum.m01 = q00 * trans[0][1] + q01 * trans[1][1] + q02 * trans[2][1];
            o_frustum.m02 = q00 * trans[0][2] + q01 * trans[1][2] + q02 * trans[2][2];
            o_frustum.m03 = q00 * trans[0][3] + q01 * trans[1][3] + q02 * trans[2][3] + q03;

            q10 = 0.0;
            q11 = -(2.0 * p[1][1] / (i_screen_height - 1));
            q12 = -((2.0 * p[1][2] / (i_screen_height - 1)) - 1.0);
            q13 = 0.0;
            o_frustum.m10 = q10 * trans[0][0] + q11 * trans[1][0] + q12 * trans[2][0];
            o_frustum.m11 = q10 * trans[0][1] + q11 * trans[1][1] + q12 * trans[2][1];
            o_frustum.m12 = q10 * trans[0][2] + q11 * trans[1][2] + q12 * trans[2][2];
            o_frustum.m13 = q10 * trans[0][3] + q11 * trans[1][3] + q12 * trans[2][3] + q13;

            q20 = 0.0;
            q21 = 0.0;
            q22 = (i_dist_max + i_dist_min) / (i_dist_min - i_dist_max);
            q23 = 2.0 * i_dist_max * i_dist_min / (i_dist_min - i_dist_max);
            o_frustum.m20 = q20 * trans[0][0] + q21 * trans[1][0] + q22 * trans[2][0];
            o_frustum.m21 = q20 * trans[0][1] + q21 * trans[1][1] + q22 * trans[2][1];
            o_frustum.m22 = q20 * trans[0][2] + q21 * trans[1][2] + q22 * trans[2][2];
            o_frustum.m23 = q20 * trans[0][3] + q21 * trans[1][3] + q22 * trans[2][3] + q23;

            q30 = 0.0;
            q31 = 0.0;
            q32 = -1.0;
            q33 = 0.0;
            o_frustum.m30 = q30 * trans[0][0] + q31 * trans[1][0] + q32 * trans[2][0];
            o_frustum.m31 = q30 * trans[0][1] + q31 * trans[1][1] + q32 * trans[2][1];
            o_frustum.m32 = q30 * trans[0][2] + q31 * trans[1][2] + q32 * trans[2][2];
            o_frustum.m33 = q30 * trans[0][3] + q31 * trans[1][3] + q32 * trans[2][3] + q33;
            return;
        }
        /**
         * この関数は、理想座標系の四角系を元に、位置姿勢変換行列を求めます。
         * 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;
        }
Example #60
0
 /**
  * アプリケーションフレームワークのハンドラ(マーカ更新)
  */
 protected override void onUpdateHandler(NyARSquare i_square, NyARDoubleMatrix44 result)
 {
     this.transmat = result;
 }