コード例 #1
0
        public static Bitmap DrawTwoImages(Bitmap img1, Bitmap img2, List <ValueTuple <Descriptor, Descriptor> > match)
        {
            var offset = 20;
            var width  = img1.Width + img2.Width + offset;
            var height = Math.Max(img1.Height, img2.Height) + offset;

            var result = new Bitmap(width + 2 * offset, height + 2 * offset);

            using (var g = Graphics.FromImage(result))
            {
                g.DrawImage(img1,
                            offset,
                            offset,
                            img1.Width,
                            img1.Height);

                g.DrawImage(img2,
                            2 * offset + img1.Width,
                            2 * offset,
                            img2.Width,
                            img2.Height);
            }

            foreach (var(d1, d2) in match)
            {
                InterestingPoint
                    from = d1.Point,
                    to   = d2.Point;

                DrawLine(result,
                         offset + from.getX(),
                         offset + from.getY(),
                         (int)from.Radius,
                         2 * offset + to.getX() + img1.Width,
                         2 * offset + to.getY(),
                         (int)to.Radius
                         );
            }

            return(result);
        }
コード例 #2
0
        private static List <int> GetInliers(List <ValueTuple <Descriptor, Descriptor> > matches, List <double> homography)
        {
            var inliers = new List <int>();

            for (var i = 0; i < matches.Count; i++)
            {
                var match = matches[i];
                InterestingPoint
                    a = match.Item1.Point,
                    b = match.Item2.Point;

                var point    = Transform(homography, a.getX(), a.getY());
                var distance = MathHelper.SqrtOfSqrSum(point.Item1 - b.getX(), point.Item2 - b.getY());

                if (distance < Threshold)
                {
                    inliers.Add(i);
                }
            }

            return(inliers);
        }
コード例 #3
0
        private static List <double> FindCurrentHomography(List <ValueTuple <Descriptor, Descriptor> > matches,
                                                           List <int> choices, bool reverse)
        {
            double[,] Homography = new double[2 * choices.Count, MatrixWidth];

            var index = 0;

            foreach (var value in choices)
            {
                var match = matches[value];
                InterestingPoint a = match.Item1.Point, b = match.Item2.Point;

                if (reverse)
                {
                    (a, b) = (b, a);
                }

                int i1 = 2 * index, i2 = 2 * index + 1;

                Homography[i1, 0] = a.getX();
                Homography[i1, 1] = a.getY();
                Homography[i1, 2] = 1;
                Homography[i1, 3] = 0;
                Homography[i1, 4] = 0;
                Homography[i1, 5] = 0;
                Homography[i1, 6] = -b.getX() * a.getX();
                Homography[i1, 7] = -b.getX() * a.getY();
                Homography[i1, 8] = -b.getX();

                Homography[i2, 0] = 0;
                Homography[i2, 1] = 0;
                Homography[i2, 2] = 0;
                Homography[i2, 3] = a.getX();
                Homography[i2, 4] = a.getY();
                Homography[i2, 5] = 1;
                Homography[i2, 6] = -b.getY() * a.getX();
                Homography[i2, 7] = -b.getY() * a.getY();
                Homography[i2, 8] = -b.getY();

                index++;
            }

            var m   = Homography.GetLength(1);
            var n   = Homography.GetLength(1);
            var k   = Homography.GetLength(0);
            var mat = new double[m, n];

            alglib.rmatrixgemm(m, n, k, 1,
                               Homography, 0, 0, 1,
                               Homography, 0, 0, 0,
                               0,
                               ref mat, 0, 0
                               );

            // SV decomposition. A = U * S * V^T
            m = mat.GetLength(0);
            n = mat.GetLength(1);
            alglib.rmatrixsvd(mat, m, n, 2, 0, 2, out var w, out var u, out _);

            var minIndex = Array.IndexOf(w, w.Min());

            var scale  = 1 / u[MatrixWidth - 1, minIndex];
            var result = new List <double>();

            for (var i = 0; i < MatrixWidth; i++)
            {
                result.Add(scale * u[i, minIndex]);
            }

            return(result);
        }
コード例 #4
0
        private static Vector CalculateForPointWithRotation(Mat gradient, Mat dx, Mat dy, double expScale,
                                                            int gridSize, double radius, int binsCount, InterestingPoint center, double alpha, bool affine)
        {
            var centerX = center.getX() / (1 << center.Octave);
            var centerY = center.getY() / (1 << center.Octave);

            var size      = (int)(radius * 2 + 1);
            var blockSize = size / gridSize;
            var step      = 2 * Math.PI / binsCount;

            double cos = Math.Cos(-alpha),
                   sin = Math.Sin(-alpha);

            var bins = new Dictionary <ValueTuple <int, int>, List <double> >();

            for (var u = -radius; u < radius; u++)
            {
                for (var v = -radius; v < radius; v++)
                {
                    int x = (int)(centerX + u),
                        y = (int)(centerY + v);

                    var magnitude = gradient.GetPixel(x, y, BorderWrapType.Wrap);
                    var theta     = Math.Atan2(dy.GetPixel(x, y, BorderWrapType.Wrap), dx.GetPixel(x, y, BorderWrapType.Wrap));
                    if (theta < 0)
                    {
                        theta += Math.PI * 2;
                    }

                    var rotatedU = u * cos + v * sin;
                    var rotatedV = v * cos - u * sin;

                    var row    = (rotatedV + size / 2D) / blockSize;
                    var column = (rotatedU + size / 2D) / blockSize;

                    if (column < 0 || column >= gridSize || row < 0 || row >= gridSize)
                    {
                        continue;
                    }

                    magnitude *= Math.Exp(expScale * (rotatedU * rotatedU + rotatedV * rotatedV));

                    var rotatedTheta = theta + alpha;
                    if (rotatedTheta > Math.PI * 2)
                    {
                        rotatedTheta -= Math.PI * 2;
                    }

                    var ratio    = rotatedTheta % step / step;
                    var leftBin  = Math.Min((int)Math.Floor(rotatedTheta / step), binsCount - 1);
                    var rightBin = (leftBin + 1) % binsCount;

                    if (!bins.ContainsKey(((int)row, (int)column)))
                    {
                        bins.Add(((int)row, (int)column), Enumerable.Repeat(0D, binsCount).ToList());
                    }

                    if (!affine)
                    {
                        PutToBins(bins, (int)row, (int)column, 1, leftBin, rightBin, ratio, magnitude);
                    }
                    else
                    {
                        var i = (int)row;
                        if (row - i <= 0.5)
                        {
                            i--;
                        }

                        var j = (int)column;
                        if (column - j <= 0.5)
                        {
                            j--;
                        }

                        var ki = 1 - Math.Abs(column - (j + 0.5));
                        var kj = 1 - Math.Abs(row - (i + 0.5));

                        PutToBins(bins, i, j, ki * kj, leftBin, rightBin, ratio, magnitude);
                        PutToBins(bins, i, j + 1, (1 - ki) * kj, leftBin, rightBin, ratio, magnitude);
                        PutToBins(bins, i + 1, j, ki * (1 - kj), leftBin, rightBin, ratio, magnitude);
                        PutToBins(bins, i + 1, j + 1, (1 - ki) * (1 - kj), leftBin, rightBin, ratio, magnitude);
                    }
                }
            }

            var result = new Vector(gridSize * gridSize * binsCount);

            for (var i = 0; i < gridSize; i++)
            {
                for (var j = 0; j < gridSize; j++)
                {
                    for (var k = 0; k < binsCount; k++)
                    {
                        double value = 0;
                        if (bins.ContainsKey((i, j)))
                        {
                            value = bins[(i, j)][k];