c 语言坐标矩阵,C中的矩阵/坐标变换#

我有一个反映图像上已知位置的坐标数组。我们称之为模板图像。它有一个独特的条形码和方向标记(也在坐标数组中)。C中的矩阵/坐标变换#

图像被打印,扫描并反馈到我的应用程序中进行检测。在打印和扫描过程中,图像可以通过三种方式进行转换;翻译,旋转和缩放。

假设我可以在扭曲的图像上找到方向标记,我如何使用矩阵变换来获取其余坐标的相对位置?

我在SO before上发布了这个问题,但是太复杂了,无法理解我想要的东西。

编辑

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

}

}

}

+0

[this](http://www.willamette.edu/~gorr/classes/GeneralGraphics/Transforms/transforms2d.htm)可以帮助你。有2点起点和2点终点,你*应该*能够得到正确的变换矩阵。 –

2012-01-11 06:53:15

+0

@Tigran:链接似乎被打破。实际上,该域名似乎至少在我的位置无法访问。你能否提供一个替代方案? –

2012-01-11 15:41:15

+0

@Rageel Khan:我刚打开它。 –

2012-01-11 15:42:13

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
public class CoordTrans7Param { public double[,] values=new double[7,1]; //{{dx},{dy},{dz},{rx},{ry},{rz},{k}}; //public double   两个坐标系转换一般需要平移,旋转,缩放共七参数。 Y=(1+k)*M(x,y,z)*X+dX; public double[,] values=new double[7,1]; //{{dx},{dy},{dz},{rx},{ry},{rz},{k}}; //public double dx,dy,dz,rx,ry,rz,k; public void Set4Param(double dx,double dy,double dz,double k) { this.dx=dx; this.dy=dy; this.dz=dz; this.k=k; this.rx=this.ry=this.rz=0; } public void SetRotationParamRad(double rx,double ry,double rz) { this.rx=rx; this.ry=ry; this.rz=rz; } public void SetRotationParamMM(double rx,double ry,double rz) { SetRotationParamRad(rx*Math.PI/648000,ry*Math.PI/648000,rz*Math.PI/648000); } private double[,] GetMx() { double [,] Mx=new double[,] {{1,0,0}, {0,Math.Cos(rx),Math.Sin(rx)}, {0,-Math.Sin(rx),Math.Cos(rx)}}; return Mx; } private double[,] GetMy() { double [,] My=new double[,] {{Math.Cos(ry),0,-Math.Sin(ry)}, {0,1,0}, {Math.Sin(ry),0,Math.Cos(ry)}}; return My; } private double[,] GetMz() { double [,] Mz=new double[,] {{Math.Cos(rz),Math.Sin(rz),0}, {-Math.Sin(rz),Math.Cos(rz),0}, {0,0,1}}; return Mz; } private double[,] GetM() //M=Mx*My*Mz? or M=Mz*My*Mx? { double [,] M=new double[3,3]; MatrixTool.Multi(GetMz(),GetMy(),ref M); MatrixTool.Multi(M,GetMx(),ref M); return M; } private double[,] GetMdx() { double[,] mt = {{ 0, 0, 0 }, { 0, -Math.Sin(rx), Math.Cos(rx) }, { 0, -Math.Cos(rx), -Math.Sin(rx) }}; double[,] m=new double[3,3]; MatrixTool.Multi(GetMz(),GetMy(),ref m); MatrixTool.Multi(m,mt,ref m); return m; } private double[,] GetMdy() { double[,] mt = {{ -Math.Sin(ry), 0, -Math.Cos(ry) }, { 0, 0, 0 }, { Math.Cos(ry), 0, -Math.Sin(ry) }}; double[,] m=new double[3,3]; MatrixTool.Multi(GetMz(),mt,ref m); MatrixTool.Multi(m,GetMx(),ref m); return m; } private double[,] GetMdz() { double[,] mt = {{ -Math.Sin(rz), Math.Co
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值