Converting Matrix / Coordinate in C #

I have an array of coordinates that reflects known positions in the image. Let me call this template image. It has a unique barcode and orientation markers (which are also in the coordinate array).

The image is printed, scanned and returned back to my application for detection. During printing and scanning, the image can be converted in three ways; translation, rotation and scale.

Assuming I can find orientation markers on a distorted image, how can I use matrix transformation to get the relative positions of the remaining coordinates?

I posted this question on SO before , but made it too complicated to understand what I wanted.

EDIT

namespace MatrixTest
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.Generic;

public static class Program
{
public static void Main ()
{
Template template = new Template(); // Original template image.
Document document = new Document(); // Printed and scanned distorted image.

template.CreateTemplateImage();

// The template image is printed and scanned. This method generates an example scan or this question.
document.CreateDistortedImageFromTemplateImage();
// Stuck here.
document.Transform();
// Draw transformed points on the image to verify that transformation is successful.
document.DrawPoints();

System.Diagnostics.Process.Start(new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).Directory.FullName);
}
}

public class Page
{
public Bitmap Image { get; set; }
public Point[] Markers = new Point[3]; // Orientation markers: 1=TopLeft, 2=TopRight, 3=BottomRight.
public Point[] Points = new Point[100]; // Coordinates to transform in the TemplateScanned derived class!
}

// This class represents the originalk template image.
public class Template: Page
{
public Template ()
{
this.Image = new Bitmap(300, 400);

// Known dimentions for marker rectangles.
this.Markers[0] = new Point(10, 10);
this.Markers[1] = new Point(this.Image.Width - 20 - 10, 10);
this.Markers[2] = new Point(this.Image.Width - 20 - 10, this.Image.Height - 20 - 10);

// Known points of interest. Consider them hardcoded.
int index = 0;
for (int y = 0; y < 10; y++)
for (int x = 0; x < 10; x++)
this.Points[index++] = new Point((this.Image.Width / 10) + (x * 20), (this.Image.Height / 10) + (y * 20));
}

public void CreateTemplateImage ()
{
using (Graphics graphics = Graphics.FromImage(this.Image))
{
graphics.Clear(Color.White);

for (int i = 0; i < this.Markers.Length; i++)
graphics.FillRectangle(Brushes.Black, this.Markers[i].X, this.Markers[i].Y, 20, 20);

for (int i = 0; i < this.Points.Length; i++)
graphics.DrawRectangle(Pens.Red, this.Points[i].X, this.Points[i].Y, 5, 5);
}

this.Image.Save("Document Original.png");
}
}

// This class represents the scanned image.
public class Document: Page
{
public struct StructTransformation
{
public float AngleOfRotation;
public SizeF ScaleRatio;
public SizeF TranslationOffset;
}

private Template Template = new Template();
private StructTransformation Transformation = new StructTransformation();

public Document ()
{
this.Template = new Template();
this.Transformation = new StructTransformation { AngleOfRotation = 5f, ScaleRatio = new SizeF(.8f, .7f), TranslationOffset = new SizeF(100f, 30f) };

this.Template.CreateTemplateImage();

// Copy points from template.
for (int i = 0; i < this.Template.Markers.Length; i++)
this.Markers[i] = this.Template.Markers[i];

for (int i = 0; i < this.Points.Length; i++)
this.Points[i] = this.Template.Points[i];
}

// Just distorts the original template image as if it had been read from a scanner.
public void CreateDistortedImageFromTemplateImage ()
{
// Distort coordinates.
Matrix matrix = new Matrix();
matrix.Rotate(this.Transformation.AngleOfRotation);
matrix.Scale(this.Transformation.ScaleRatio.Width, this.Transformation.ScaleRatio.Height);
matrix.Translate(this.Transformation.TranslationOffset.Width, this.Transformation.TranslationOffset.Height);
matrix.TransformPoints(this.Markers);
matrix.TransformPoints(this.Points);

// Distort and save image for visual reference.
this.Image = new Bitmap(this.Template.Image.Width, this.Template.Image.Height);
using (Graphics graphics = Graphics.FromImage(this.Image))
{
graphics.Clear(Color.White);
graphics.RotateTransform(this.Transformation.AngleOfRotation);
graphics.ScaleTransform(this.Transformation.ScaleRatio.Width, this.Transformation.ScaleRatio.Height);
graphics.TranslateTransform(this.Transformation.TranslationOffset.Width, this.Transformation.TranslationOffset.Height);
graphics.DrawImage(this.Template.Image, 0, 0);
}
this.Image.Save("Document Scanned.png");
}

public void Transform ()
{
// The rectangles of the ScannedDcoument are not known at this time. They would obviously be relative to the three orientation markers.
//    I can't figure out how to use the following code properly i.e. using Matrix to apply all three transformations.
Matrix matrix = new Matrix();
matrix.Rotate(-this.Transformation.AngleOfRotation);
matrix.Scale(1f/this.Transformation.ScaleRatio.Width, 1f/this.Transformation.ScaleRatio.Height);
matrix.Translate(-this.Transformation.TranslationOffset.Width, -this.Transformation.TranslationOffset.Height);
matrix.TransformPoints(this.Markers);
matrix.TransformPoints(this.Points);
}

public void DrawPoints ()
{
using (Graphics graphics = Graphics.FromImage(this.Image))
{
graphics.Clear(Color.White);

for (int i = 0; i < this.Markers.Length; i++)
graphics.FillRectangle(Brushes.Blue, this.Markers[i].X, this.Markers[i].Y, 20, 20);

for (int i = 0; i < this.Points.Length; i++)
graphics.DrawRectangle(Pens.Purple, this.Points[i].X, this.Points[i].Y, 5, 5);
}
this.Image.Save("Document Fixed.png");
}
}
}
+2
1

, ((0, 0) - (1.0, 1.0)) , - , x (1,0, 0), - y (0, 1.0).

:

  • (Ox, Oy)
  • X (X1, Y2)
  • Y (X2, Y2)
  • X- (X1-Ox, Y1-Oy) (RX1, RY1)
  • Y- (X2-ox, Y2-Oy) (RX2, RY2)

(0,0) ,

(1   0   -Ox)
(0   1   -Oy)
(0   0    1) 

:

(RX1   RX2   0)
(RY1   RY2   0)
( 0    0     1)

, , : (RX1 * RY2-RX2 * RY1) D

(RY2/D   -RX2/D   0)
(-RY1/D   RX1/D   0)
(  0       0      1)

, .

+5

All Articles