【问题标题】:Is it possible to correct page dimensions by getting three points on it?是否可以通过获得三个点来纠正页面尺寸?
【发布时间】:2019-12-24 10:02:37
【问题描述】:

我正在研究校正页面(图像)的宽度、高度和角度的逻辑。 点 r1,r2,r3 在正确图像上,点 d1,d2,d3 是当前图像上的对应点。

我尝试了多种方法并最终实现了这一目标。

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;
    }

【问题讨论】:

  • 谁能帮我计算 ScaleTransform 和 RotateTransform 的值?

标签: c# wpf logic


【解决方案1】:

我没有直接回答您的问题:但是对齐扫描图像的常用技术是使用仿射变换。它是一个基于 a,b,c,a',b',c' 的 3x3 矩阵方程。通过简单的矩阵乘法,您可以计算一个或另一个图像系统中的每个坐标或对所有像素进行完全转换。

很抱歉没有适合您的示例。请参阅 https://www.graphicsmill.com/docs/gm/affine-and-projective-transformations.htmhttps://docs.microsoft.com/en-us/dotnet/api/system.windows.media.matrixtransform?view=netframework-4.8 在 WPF RenderTransform 中使用。

【讨论】:

  • 我的项目在 dotnet core 3.1 中,它需要 System.Windows.Media 的 .net 框架。
  • 我已经尝试过您的解决方案,但无法使其正常工作。我已经用新的变化更新了我的问题。
  • 谢谢@r2d2。我用变换矩阵做到了。
  • 也谢谢你! @Pratap Singh Mehra
【解决方案2】:

终于找到答案了。

第 1 次: 正如 JA72 here 所解释的那样 TransformationMatrix = BaseImageMatrix * (ScanedImageMatrix)^-1

第 2 次:here 使用 TransformationMatrix 计算平移、缩放和旋转。

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]));

【讨论】:

    猜你喜欢
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多