问题
I am working on a logic of correcting width, height and angle of page(image). Point r1,r2,r3 are on correct image and Point d1,d2,d3 are corresponding points on current image.
I have tried multiple approach and have landed on this.
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:
I am not answering your question directly: But a common technique to align a scanned image is to use an affine transformation. It is a 3x3 matrix equation based on a,b,c,a',b',c'. With a simple matrix multiplication you can then calculate every coordinate within the one ot the other image system or make complete transformation of all pixels.
Sorry to have no working example for you. See https://www.graphicsmill.com/docs/gm/affine-and-projective-transformations.htm and https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.matrixtransform?view=netframework-4.8 is used in WPF RenderTransform.
回答2:
Finally found the answer.
1st : As explained by JA72 here TransformationMatrix = BaseImageMatrix * (ScanedImageMatrix)^-1
2nd : Also here to use TransformationMatrix to calculate Translate, Scale and Rotation.
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 rotation = Math.Cos(H[0, 0]) * Math.Cos(H[1, 0]) - Math.Sin(H[1, 0]) * Math.Sin(H[0, 1]);
transform.Children.Add(new TranslateTransform(H[2, 0], H[2, 1]));
transform.Children.Add(new ScaleTransform(H[0, 0], H[1, 1]));
transform.Children.Add(new RotateTransform(rotation));
transform.Children.Add(new TranslateTransform(-H[2, 0], -H[2, 1]));
来源:https://stackoverflow.com/questions/59467047/is-it-possible-to-correct-page-dimensions-by-getting-three-points-on-it