Estoy trabajando en una lógica de corrección de ancho, alto y ángulo de página (imagen). Los puntos r1, r2, r3 están en la imagen correcta y los puntos d1, d2, d3 son puntos correspondientes en la imagen actual.

He intentado un enfoque múltiple y he aterrizado en esto.

public System.Drawing.Bitmap CorrectFileDimentionsV2(System.Drawing.Bitmap bitmap, PagePoints pagePoints)
    {
        BitmapHelper bitmapHelper = new BitmapHelper();
        var bitmapImage = bitmapHelper.Bitmap2BitmapImage(bitmap);
        DrawingVisual MyPath = new DrawingVisual();
        using (DrawingContext dc = MyPath.RenderOpen())
        {
            TransformGroup transform = new TransformGroup();

            Point r1 = pagePoints.ADash;
            Point r2 = pagePoints.BDash;
            Point r3 = pagePoints.CDash;

            Point d1 = pagePoints.A;
            Point d2 = pagePoints.B;
            Point d3 = pagePoints.C;

            Vector vr21 = r2 - r1;
            Vector vd21 = d2 - d1;

            Vector vr31 = r3 - r1;
            Vector vd31 = d3 - d1;

            double y1 = Vector.CrossProduct(vr31, vr21) / vr21.Length;
            double y2 = Vector.CrossProduct(vd31, vd21) / vd21.Length;

            transform.Children.Add(new TranslateTransform(-r1.X, -r1.Y));
            transform.Children.Add(new ScaleTransform(vd21.Length / vr21.Length, y2 / y1));
            transform.Children.Add(new RotateTransform(Vector.AngleBetween(vr21, vd21)));
            transform.Children.Add(new TranslateTransform(d1.X, d1.Y));

            dc.PushTransform(transform);
            dc.DrawImage(bitmapImage, new Rect(0, 0, bitmapImage.Width, bitmapImage.Height));
            dc.Pop();
        }
            Image theImage = new Image();
            DrawingImage dImageSource = new DrawingImage(dGroup);
            theImage.Source = dImageSource;

            using (MemoryStream ms = new MemoryStream())
            {
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(ToBitmapSource(dImageSource)));
                encoder.Save(ms);

                using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms))
                {
                    bmpOut = new System.Drawing.Bitmap(bmp);
                }
            }
        return bmpOut;
    }
1
Pratap Singh Mehra 24 dic. 2019 a las 13:02

2 respuestas

La mejor respuesta

Finalmente encontré la respuesta.

1er: Como lo explica JA72 aquí TransformationMatrix = BaseImageMatrix * (ScanedImageMatrix) ^ - 1

2do: También aquí usar TransformationMatrix para calcular Traslación, Escala y Rotación.

var BaseImageBuilder = MathNet.Numerics.LinearAlgebra.Matrix<double>.Build;
double[,] BaseImageCoordinates = { { pagePoints.ADash.X, pagePoints.BDash.X, pagePoints.CDash.X }, { pagePoints.ADash.Y, pagePoints.BDash.Y, pagePoints.CDash.Y }, { 1, 1, 1 } };
var BaseImageMatrix = BaseImageBuilder.DenseOfArray(BaseImageCoordinates);

double[,] ScanedImageCoordinates = { { pagePoints.A.X, pagePoints.B.X, pagePoints.C.X }, { pagePoints.A.Y, pagePoints.B.Y, pagePoints.C.Y }, { 1, 1, 1 } };
var ScanedImageMatrix = BaseImageBuilder.DenseOfArray(ScanedImageCoordinates);
var ScanedInverseMatrix = ScanedImageMatrix.Inverse();

var H = BaseImageMatrix * ScanedInverseMatrix;
var vec1 = new Vector(H[0, 0], H[1, 0]);
var scaleX = vec1.Length;
var vec2 = new Vector(H[0, 1], H[1, 1]);
var scaleY = vec2.Length;
var rotation = Math.Acos(H[0, 0] / scaleX) * 180 / Math.PI;

transform.Children.Add(new TranslateTransform(H[2, 0], H[2, 1]));                     
transform.Children.Add(new ScaleTransform(scaleX, scaleY));
transform.Children.Add(new RotateTransform(rotation));
transform.Children.Add(new TranslateTransform(-H[2, 0], -H[2, 1]));
2
Pratap Singh Mehra 5 mar. 2020 a las 05:10

No estoy respondiendo su pregunta directamente: Pero una técnica común para alinear una imagen escaneada es usar una transformación afín. Es una ecuación matricial de 3x3 basada en a, b, c, a ', b', c '. Con una simple multiplicación de matrices, puede calcular cada coordenada dentro de la otra del otro sistema de imagen o realizar una transformación completa de todos los píxeles.

Lamento no tener un ejemplo de trabajo para ti. Consulte https://www.graphicsmill.com/docs/gm /affine-and-projective-transformations.htm y https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.matrixtransform?view=netframework-4.8 se utiliza en WPF RenderTransform.

2
r2d2 24 dic. 2019 a las 12:37