示例#1
0
        static TandTi GetNormalizedMatrix(PointFloat[] pts)
        {
            var xmean = getMean(pts, p => p.X);
            var ymean = getMean(pts, p => p.Y);
            var xvar  = getVariance(pts, p => p.X);
            var yvar  = getVariance(pts, p => p.Y);

            var xs = Math.Sqrt(2 / xvar);
            var ys = Math.Sqrt(2 / yvar);

            var m = new GMatrix(new double[, ]
            {
                { xs, 0, -xs * xmean },
                { 0, ys, -ys * ymean },
                { 0, 0, 1 }
            });
            var mi = new GMatrix(new double[, ] {
                { 1 / xs, 0, xmean },
                { 0, 1 / ys, ymean },
                { 0, 0, 1 }
            });

            return(new TandTi
            {
                t = m,
                ti = mi,
            });
        }
示例#2
0
            public Ert GetRT(GMatrix m)
            {
                var svd = JacobSvd.JacobiSVD(m);
                var W   = new GMatrix(new double[, ]
                {
                    { 0, -1, 0 },
                    { 1, 0, 0 },
                    { 0, 0, 1 }
                });

                var Wt = new GMatrix(new double[, ]
                {
                    { 0, 1, 0 },
                    { -1, 0, 0 },
                    { 0, 0, 1 }
                });

                svd.W[2] = 0;
                var t = svd.U.dot(W).dot(svd.getWMat()).dot(svd.U.tranpose());
                var r = svd.U.dot(Wt).dot(svd.Vt);

                return(new Ert
                {
                    R = r,
                    T = t,
                });
            }
示例#3
0
        public static GMatrix CalcFundm(PointFloat[] points1, PointFloat[] points2)
        {
            var m1 = new GMatrix(points1.Length, 9);

            for (var i = 0; i < points1.Length; i++)
            {
                var pp1 = points1[i];
                var pp2 = points2[i];
                var y1  = pp1.X;
                var y2  = pp1.Y;
                var p1  = pp2.X;
                var p2  = pp2.Y;
                var cur = m1.storage[i];
                cur[0] = y1 * p1;
                cur[1] = p1 * y2;
                cur[2] = p1;
                cur[3] = p2 * y1;
                cur[4] = p2 * y2;
                cur[5] = p2;
                cur[6] = y1;
                cur[7] = y2;
                cur[8] = 1;
            }

            var Fhat = SolveSvd3x3(m1);

            var FhatSvd = JacobSvd.JacobiSVD(Fhat);
            var d       = FhatSvd.getWMat();

            d.storage[2][2] = 0;

            var res = FhatSvd.U.dot(d).dot(FhatSvd.Vt);

            return(res);
        }
示例#4
0
        public GMatrix dot(GMatrix m)
        {
            var r  = rows;
            var mc = m.cols;

            //if (r != mc) throw new InvalidOperationException($"Cross: row {r} and col {mc} must equal");
            if (cols != m.rows)
            {
                throw new InvalidOperationException($"Cross: col {cols} and row {m.rows} must equal");
            }
            var newStorage = new double[r, mc];
            var c          = cols;

            for (var i = 0; i < r; i++)
            {
                for (var j = 0; j < mc; j++)
                {
                    double total = 0;
                    for (var k = 0; k < c; k++)
                    {
                        total += storage[i][k] * m.storage[k][j];
                    }
                    newStorage[i, j] = total;
                }
            }
            return(new GMatrix(newStorage));
        }
示例#5
0
        private static JacobSvd.SvdRes SolveSvd(GMatrix m1)
        {
            //double max = 1;
            //double min = -1;
            //for (var i = 0; i < m1.rows; i++)
            //{
            //    for (var j = 0; j < m1.cols; j++)
            //    {
            //        var v = m1.storage[i][j];
            //        if (v > max) max = v;
            //        if (v < min) min = v;
            //    }
            //}
            //var scal = Math.Max(Math.Abs(min), max);
            //for (var i = 0; i < m1.rows; i++)
            //{
            //    for (var j = 0; j < m1.cols; j++)
            //    {
            //        var v = m1.storage[i][j];
            //        m1.storage[i][j] = v / scal;
            //    }
            //}
            var svdA = JacobSvd.JacobiSVD(m1);

            return(svdA);
        }
示例#6
0
        public static GMatrix GetH2(PointFloat e, PointFloat imgSize)
        {
            var     w2 = -imgSize.X / 2;
            var     h2 = -imgSize.Y / 2;
            GMatrix T  = new GMatrix(new double[, ] {
                { 1, 0, w2 },
                { 0, 1, h2 },
                { 0, 0, 1 }
            });
            var     e1   = e.X + w2;
            var     e2   = e.Y + h2;
            var     l    = Math.Sqrt((e1 * e1) + (e2 * e2));
            var     alph = e1 >= 0 ? 1 : -1;
            GMatrix R    = new GMatrix(new double[, ] {
                { alph *e1 / l, alph *e2 / l, 0 },
                { -1 * alph * e2 / l, alph * e1 / l, 0 },
                { 0, 0, 1 }
            });
            GMatrix G = new GMatrix(new double[, ]
            {
                { 1, 0, 0 },
                { 0, 1, 0 },
                { -1 / e1, 0, 1 }
            });

            return(GMatrix.Inverse3x3(T).dot(G.dot(R.dot(T))));
        }
示例#7
0
        public static PointFloat FindEpipole(PointFloat[] pts, PointSide side, GMatrix f)
        {
            if (side == PointSide.Right)
            {
                f = f.tranpose();
            }

            GMatrix lines   = new GMatrix(pts.Length, 3);
            var     storage = lines.storage;

            for (int i = 0; i < pts.Length; i++)
            {
                var cur = storage[i];
                var pt  = pts[i];
                var gm  = f.dot(new GMatrix(new double[3, 1] {
                    { pt.X }, { pt.Y }, { 1 }
                }));
                var ms = gm.storage;
                for (int j = 0; j < 3; j++)
                {
                    cur[j] = ms[j][0];
                }
            }

            var svdA = JacobSvd.JacobiSVD(lines);
            var res  = svdA.Vt.storage[2];

            //Console.WriteLine($"{res[0].ToString("0.00")},{res[1].ToString("0.00")},{res[2].ToString("0.0000000")}");
            //Console.WriteLine($"{(res[0]/res[2]).ToString("0.00")},{(res[1]/res[2]).ToString("0.00")}");
            return(new PointFloat((float)(res[0] / res[2]), (float)(res[1] / res[2])));
        }
示例#8
0
        static void MaxApply(GMatrix m, int pos)
        {
            double max = 0;

            for (var i = 0; i < m.rows; i++)
            {
                var v = Math.Abs(m.storage[i][pos]);
                if (v > max)
                {
                    max = v;
                }
            }
            for (var i = 0; i < m.rows; i++)
            {
                var v = m.storage[i][pos];
                if (v == 0)
                {
                    continue;
                }
                var scal = max / v;
                for (var j = pos; j < m.cols; j++)
                {
                    m.storage[i][j] *= scal;
                }
            }
        }
示例#9
0
        public static double[] SVBkSb(GMatrix u, double[] w, GMatrix v, double[] b)
        {
            int m = u.rows, n = u.cols;

            double[] x    = new double[n];
            double[] temp = new double[n];
            for (int j = 0; j < n; j++)
            {
                double s = 0;
                if (w[j] != 0)
                {
                    for (var i = 0; i < m; i++)
                    {
                        s += u.storage[i][j] * b[i];
                    }
                    s /= w[j];
                }
                temp[j] = s;
            }
            for (var j = 0; j < n; j++)
            {
                double s = 0.0;
                for (var jj = 0; jj < n; jj++)
                {
                    s += v.storage[j][jj] * temp[jj];
                }
                x[j] = s;
            }
            return(x);
        }
示例#10
0
            public GMatrix getWMat()
            {
                var mat = new GMatrix(U.rows, Vt.cols);
                int at  = 0;

                for (var i = 0; i < Vt.cols; i++)
                {
                    mat.storage[i][i] = W[at++];
                }
                return(mat);
            }
示例#11
0
        static PointFloat[] perspectiveTransform(PointFloat[] pts, GMatrix mat)
        {
            List <PointFloat> res = new List <PointFloat>();

            foreach (var pt in pts)
            {
                var npt = mat.dot(pt.ToVect());
                var w   = npt.storage[2][0];
                res.Add(new PointFloat(npt.storage[0][0] / w, npt.storage[1][0] / w));
            }
            return(res.ToArray());
        }
示例#12
0
        public static GMatrix GetH1(PointFloat e, PointFloat imgSize, GMatrix F, GMatrix H2,
                                    PointFloat[] leftPts, PointFloat[] rightPts)
        {
            var ex = new GMatrix(new double[, ]
            {
                { 0, -1, e.Y },
                { 1, 0, -e.X },
                { -e.Y, e.X, 0 }
            });
            var e_111 = new GMatrix(new double[, ]
            {
                { e.X, e.X, e.X },
                { e.Y, e.Y, e.Y },
                { 1, 1, 1 },
            });
            var m = ex.dot(F).add(e_111);

            var h0h = H2.dot(m);

            var m1   = perspectiveTransform(leftPts, h0h);
            var m2   = perspectiveTransform(rightPts, H2);
            var abuf = new double[leftPts.Length, 3];

            for (var i = 0; i < leftPts.Length; i++)
            {
                var pt = leftPts[i];
                abuf[i, 0] = pt.X;
                abuf[i, 1] = pt.Y;
                abuf[i, 2] = 1;
            }
            var A    = new GMatrix(abuf);
            var svcr = JacobSvd.JacobiSVD(A);

            double[] B = new double[rightPts.Length];
            for (var i = 0; i < rightPts.Length; i++)
            {
                B[i] = m2[i].X;
            }
            var x = Util.SVBkSb(svcr.U, svcr.W, svcr.Vt, B);

            var Ha = new GMatrix(new double[, ]
            {
                { x[0], x[1], x[2] },
                { 0, 1, 0 },
                { 0, 0, 1 }
            });

            var res = Ha.dot(h0h);

            return(res);
        }
示例#13
0
        public GMatrix add(GMatrix m)
        {
            var r          = rows;
            var c          = cols;
            var newStorage = new GMatrix(r, c);

            for (var i = 0; i < r; i++)
            {
                for (var j = 0; j < c; j++)
                {
                    newStorage.storage[i][j] = storage[i][j] + m.storage[i][j];
                }
            }
            return(newStorage);
        }
示例#14
0
        public GMatrix div(double v)
        {
            var r          = rows;
            var c          = cols;
            var newStorage = new GMatrix(r, c);

            for (var i = 0; i < r; i++)
            {
                for (var j = 0; j < c; j++)
                {
                    newStorage.storage[i][j] = storage[i][j] / v;
                }
            }
            return(newStorage);
        }
示例#15
0
        public GMatrix tranpose()
        {
            var r          = rows;
            var c          = cols;
            var newStorage = new GMatrix(c, r);

            for (var i = 0; i < r; i++)
            {
                for (var j = 0; j < c; j++)
                {
                    newStorage.storage[j][i] = storage[i][j];
                }
            }
            return(newStorage);
        }
示例#16
0
        public static GMatrix SolveSvd3x3(GMatrix m1)
        {
            JacobSvd.SvdRes svdA = SolveSvd(m1);
            var             Fhat = new GMatrix(3, 3);
            int             at   = 0;
            var             ms   = svdA.Vt.storage[8];

            for (var i = 0; i < 3; i++)
            {
                for (var j = 0; j < 3; j++)
                {
                    Fhat.storage[i][j] = ms[at++];
                }
            }
            return(Fhat);
        }
示例#17
0
        public static GMatrix EstimateHomography(PointFloat[] points, PointFloat[] checkBoardLoc)
        {
            var nu = GetNormalizedMatrix(points);
            var nx = GetNormalizedMatrix(checkBoardLoc);
            var m1 = new GMatrix(points.Length * 2, 9);

            for (var i = 0; i < points.Length; i++)
            {
                var pts = nu.t.dot(points[i].ToVect()).noramByLast();
                var obj = nx.t.dot(checkBoardLoc[i].ToVect()).noramByLast();
                var ii  = i * 2;
                //var xy = points[i];
                var x   = pts.storage[0][0];
                var y   = pts.storage[1][0];
                var X   = obj.storage[0][0];
                var Y   = obj.storage[1][0];
                var cur = m1.storage[ii];
                cur[0] = -X;
                cur[1] = -Y;
                cur[2] = -1;
                cur[3] = 0;
                cur[4] = 0;
                cur[5] = 0;
                cur[6] = x * X;
                cur[7] = x * Y;
                cur[8] = x;

                cur    = m1.storage[ii + 1];
                cur[0] = 0;
                cur[1] = 0;
                cur[2] = 0;
                cur[3] = -X;
                cur[4] = -Y;
                cur[5] = -1;
                cur[6] = y * X;
                cur[7] = y * Y;
                cur[8] = y;
            }

            var res = SolveSvd3x3(m1);

            var denormed = nu.ti.dot(res).dot(nx.t).noramByLast();

            return(denormed);
        }
示例#18
0
        protected static GMatrix Cholesky3x3(GMatrix m)
        {
            var     l11 = Math.Sqrt(m.storage[0][0]);
            var     l21 = m.storage[0][1] / l11;
            var     l31 = m.storage[0][2] / l11;
            var     l22 = Math.Sqrt(m.storage[1][1] - (l21 * l21));
            var     l32 = (m.storage[1][2] - (l31 * l21)) / l22;
            var     l33 = Math.Sqrt(m.storage[2][2] - ((l31 * l31) + (l32 * l32)));
            GMatrix rm  = new GMatrix(3, 3);

            rm.storage[0][0] = l11;
            rm.storage[0][1] = l21;
            rm.storage[0][2] = l31;
            rm.storage[1][1] = l22;
            rm.storage[1][2] = l32;
            rm.storage[2][2] = l33;
            return(rm);
        }
示例#19
0
        public static SvdRes JacobiSVD(GMatrix mat)
        {
            //m rows, n cols
            //orig mxn, U mxm, W mxn V nxn

            //W is array of size n, Vt size nxn

            var m   = mat.rows;
            var n   = mat.cols;
            var A   = mat.tranpose().ToArray();
            var res = SVD(A, m, n);

            return(new SvdRes
            {
                U = new GMatrix(A, n, m).tranpose(), //or nxm or mxn?
                W = res.W,
                Vt = new GMatrix(res.Vt, n, n),
            });
        }
示例#20
0
        public static GMatrix Inverse3x3(GMatrix m)
        {
            double det = 0;
            var    mat = m.storage;

            for (var i = 0; i < 3; i++)
            {
                det = det + (mat[0][i] * (mat[1][(i + 1) % 3] * mat[2][(i + 2) % 3] - mat[1][(i + 2) % 3] * mat[2][(i + 1) % 3]));
            }


            var res = new GMatrix(3, 3);

            for (var i = 0; i < 3; ++i)
            {
                for (var j = 0; j < 3; ++j)
                {
                    res.storage[i][j] = ((mat[(j + 1) % 3][(i + 1) % 3] * mat[(j + 2) % 3][(i + 2) % 3]) - (mat[(j + 1) % 3][(i + 2) % 3] * mat[(j + 2) % 3][(i + 1) % 3])) / det;
                }
            }
            return(res);
        }
示例#21
0
        public static RectifyResult Rectify(List <StereoPoints> allPts, PointFloat imgSize, int CalibGridRow = 6, int CalibGridCol = 3)
        {
            var leftPts  = allPts.SelectMany(x => x.Left).ToArray();
            var rightPts = allPts.SelectMany(x => x.Right).ToArray();
            var F        = Calib.CalcFundm(leftPts, rightPts);
            var epol     = CalibRect.FindEpipole(leftPts, PointSide.Left, F);


            var h2 = CalibRect.GetH2(epol, new PointFloat(imgSize.X, imgSize.Y));
            var h1 = CalibRect.GetH1(epol, new PointFloat(imgSize.X, imgSize.Y), F, h2, allPts[0].Left, allPts[0].Right);


            Func <Func <StereoPoints, PointFloat[]>, PointFloat[][]> fetch = f =>
            {
                PointFloat[][] res = new PointFloat[allPts.Count][];
                for (var i = 0; i < allPts.Count; i++)
                {
                    res[i] = f(allPts[i]);
                }
                return(res);
            };

            var li = Calib.EstimateIntranics(fetch(x => x.Left), CalibGridRow, CalibGridCol);
            var ri = Calib.EstimateIntranics(fetch(x => x.Right), CalibGridRow, CalibGridCol);

            var E = GMatrix.Inverse3x3(li).tranpose().dot(F).dot(GMatrix.Inverse3x3(ri));

            return(new RectifyResult
            {
                H1 = h1,
                H2 = h2,
                F = F,
                E = E,
                el = epol,
                LeftIntrinics = li,
                RightIntrinics = ri,
            });
        }
示例#22
0
 public void Solve(GMatrix m)
 {
     MaxApply(m, 0);
 }
示例#23
0
        public static GMatrix EstimateIntranics(PointFloat[][] allPoints, int w = 6, int h = 3)
        {
            /*
             *   hij
             *            h12  h22  h32
             *
             *   h11      b11  b12  b13
             *   h21      b12  b22  b23
             *   h31      b13  b23  b33
             *
             *
             *   h11 h12 t1
             *   h21 h22 t2
             *   h31 h32 t3
             *
             */
            var allHomos = allPoints.GetLength(0);
            var homopts  = new List <HomoPts>();

            for (var c = 0; c < allHomos; c++)
            {
                var p  = allPoints[c];
                var hm = EstimateHomography(p, w, h);
                Action <int, int, double[], GMatrix> fillV = (i, j, cur, h**o) =>
                {
                    Func <int, int, double> hval = (hrow, hcol) =>
                    {
                        return(h**o.storage[hrow][hcol]);
                    };
                    cur[0] = hval(0, i) * hval(0, j);
                    cur[1] = (hval(0, i) * hval(1, j)) + (hval(1, i) * hval(0, j));
                    cur[2] = hval(1, i) * hval(1, j);
                    cur[3] = (hval(2, i) * hval(0, j)) + (hval(0, i) * hval(2, j));
                    cur[4] = (hval(2, i) * hval(1, j)) + (hval(1, i) * hval(2, j));
                    cur[5] = hval(2, i) * hval(2, j);
                };
                homopts.Add(new HomoPts {
                    h**o = hm, points = p, FillV = fillV
                });
            }


            var     pointsLength = w * h;
            GMatrix m            = new GMatrix(allHomos * 2, 6);
            int     at           = 0;

            for (var c = 0; c < homopts.Count; c++)
            {
                var hp    = homopts[c];
                var FillV = hp.FillV;
                FillV(0, 1, m.storage[at], hp.h**o);
                var v00 = new double[6];
                FillV(0, 0, v00, hp.h**o);
                var v11 = new double[6];
                FillV(1, 1, v11, hp.h**o);
                var r2 = m.storage[at + 1];
                for (var j = 0; j < 6; j++)
                {
                    r2[j] = v00[j] - v11[j];
                }
                at += 2;
            }
            var svdr = SolveSvd(m);

            var a   = new GMatrix(3, 3);
            var vtl = svdr.Vt.storage[5];
            Func <int, double> gb = i => vtl[i];
            var gb0_4             = gb(0) * gb(4);
            var gb0_2             = gb(0) * gb(2);
            var gb1x1             = gb(1) * gb(1);
            var vc    = ((gb(1) * gb(3)) - gb0_4) / (gb0_2 - gb1x1);
            var l     = gb(5) - ((gb(3) * gb(3) + vc * (gb(1) * gb(2) - gb0_4)) / gb(0));
            var alpha = Math.Sqrt(l / gb(0));
            var beta  = Math.Sqrt((l * gb(0)) / (gb0_2 - gb1x1));
            var gamma = -1 * (gb(1) * alpha * alpha) * beta / l;
            var uc    = gamma * vc / beta - (gb(3) * alpha * alpha / l);

            a.storage[0][0] = alpha;
            a.storage[1][1] = beta;
            a.storage[0][1] = gamma;
            a.storage[0][2] = uc;
            a.storage[1][2] = vc;
            a.storage[2][2] = 1;
            //Console.WriteLine(a);
            return(a);
            // var b = new GMatrix(3, 3);
            //b.storage[0][0] = svdr.Vt.storage[0][5];
            //b.storage[0][1] = b.storage[1][0] = svdr.Vt.storage[1][5]; //b12
            //b.storage[0][2] = b.storage[2][0] = svdr.Vt.storage[2][5]; //b13
            //b.storage[1][1] = svdr.Vt.storage[3][5]; //b22
            //b.storage[1][2] = b.storage[2][1] = svdr.Vt.storage[4][5]; //b23
            //b.storage[2][2] = svdr.Vt.storage[5][5]; //b33
            ////b= K-t*K-1
            //Console.WriteLine(b);
            //var A1 = Cholesky3x3(b);
            //Console.WriteLine(Inverse3x3(A1));
        }