总结图像旋转,突然发现矩阵运算(二维概念)很重要,我们应该有一个基础矩阵运算类,我们把先学会的平移,旋转,翻转引入到类中(简单就好,以后需要的功能,可再增加,一次要设计好,脑瓜疼!),你会发现,坐标系中的每一个点(x,y)需要这样的运算,图像中的每一点(i,j)也需要有这样的运算,运算前先要找到操作点,坐标系很方便,直接上(x,y),而图像,你现在知道,他就是buffer【】,是一个二维的概念,即buffer[j][i]=buffer[j*w+i],其实我们的图像处理,机器视觉都是处理的这个buffer中的每一个像素点,其实你也发现了,电脑显示,也是这个buffer的问题,我们强调的是处理这个buffer,而不是显示这个buffer,这是需要区分的,显示,就交给微软了,我见过他的魔法,但我仍相信他。(我们需要站在巨人肩上,没有谁说,巨人是不犯错的人!而谁又能说,自己不犯错呢?既然对自己的错误视而不见,怎么能去挑别人的错呢?先搞定自己的错误,这或许,就是程序员的bug精神所在吧!)
扯远了,废话一堆,能回归主题,行走弯路自是不少,还是看代码矩阵运算类设计,c++还得去翻陈年旧账,先看c#直线类:
public class mg_line
{
public PointF pt_start;
public PointF pt_end;
public mg_line()
{
pt_end = new PointF();
pt_start = new PointF();
}
public mg_line(PointF pstart, PointF pend)
{
pt_start = pstart;
pt_end = pend;
}
public void 直线平移(PointF 指定点)
{
......
}
public void 直线旋转(PointF 指定点, double 弧度)
{
......
}
}
好,我们来实现函数public void 直线平移(PointF 指定点):
首先,(pt_start.x,pt_start.y,1)*,程序怎么整?
public double[,] 单位矩阵 = new double[3, 3];//单位矩阵
其次, int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
if (i == j) 单位矩阵[i, j] = 1;
else 单位矩阵[i, j] = 0;
}
单位矩阵[2, 0] = -指定点.x;
单位矩阵[2, 1] = -指定点.y;
再次, double x, y;PointF sp=pt_start;
x = this.单位矩阵[0, 0] * sp.X + this.单位矩阵[1, 0] * sp.Y + this.单位矩阵[2, 0];
y = this.单位矩阵[0, 1] * sp.X + this.单位矩阵[1, 1] * sp.Y + this.单位矩阵[2, 1];
pt_start.X = (float)x;
pt_start.Y = (float)y;
搞定pt_start平移,那么pt_end照猫画虎:
double x, y;PointF sp=pt_end;
x = this.单位矩阵[0, 0] * sp.X + this.单位矩阵[1, 0] * sp.Y + this.单位矩阵[2, 0];
y = this.单位矩阵[0, 1] * sp.X + this.单位矩阵[1, 1] * sp.Y + this.单位矩阵[2, 1];
pt_end.X = (float)x;
pt_end.Y = (float)y;
下来,针对原点旋转,(pt_start,pt_start,1)*,程序怎么整?
好,先整一个类: public class 矩阵变换
{
public double[,] 单位矩阵 = new double[3, 3];//单位矩阵
public 矩阵变换()
{
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
if (i == j) 单位矩阵[i, j] = 1;
else 单位矩阵[i, j] = 0;
}
}
}
第一,矩阵变换 M = new 矩阵变换();
M.单位矩阵[0, 0] = M.单位矩阵[1, 1] = Math.Cos(弧度);//Math.Cos
M.单位矩阵[0, 1] = Math.Sin(弧度);//Math.Sin
M.单位矩阵[1, 0] = -M.单位矩阵[0, 1];
第二, double x, y;PointF sp=pt_start;
x = M.单位矩阵[0, 0] * sp.X + M.单位矩阵[1, 0] * sp.Y + M.单位矩阵[2, 0];
y = M.单位矩阵[0, 1] * sp.X + M.单位矩阵[1, 1] * sp.Y + M.单位矩阵[2, 1];
pt_start.X = (float)x;
pt_start.Y = (float)y;
一点旋转搞定,另外点照抄.我们此处重点是要整一个矩阵变换的类,他可以完成直线的平移旋转,好,继续补充完整这个类:
public class 矩阵变换
{
......
public void 点平移(PointF 指定点 ,ref PointF sp)
{
矩阵变换 M = new 矩阵变换();
M. 单位矩阵[2, 0] = -指定点.X;
M. 单位矩阵[2, 1] = -指定点.Y;
double x, y;
x = M.单位矩阵[0, 0] * sp.X + M.单位矩阵[1, 0] * sp.Y + M.单位矩阵[2, 0];
y = M.单位矩阵[0, 1] * sp.X + M.单位矩阵[1, 1] * sp.Y + M.单位矩阵[2, 1];
sp.X = (float)x;
sp.Y = (float)y;
}
public void 原点旋转(double 弧度 ,ref PointF sp)
{ 矩阵变换 M = new 矩阵变换();
M.单位矩阵[0, 0] = M.单位矩阵[1, 1] = Math.Cos(弧度);//Math.Cos
M.单位矩阵[0, 1] = Math.Sin(弧度);//Math.Sin
M.单位矩阵[1, 0] = -M.单位矩阵[0, 1];
double x, y;
x = M.单位矩阵[0, 0] * sp.X + M.单位矩阵[1, 0] * sp.Y + M.单位矩阵[2, 0];
y = M.单位矩阵[0, 1] * sp.X + M.单位矩阵[1, 1] * sp.Y + M.单位矩阵[2, 1];
sp.X = (float)x;
sp.Y = (float)y;
}
}
下面就可以实现直线平移了:
public void 直线平移(PointF 指定点)
{
矩阵变换 temp=new 矩阵变换();
temp.点平移( 指定点 ,ref pt_start);
temp.点平移( 指定点 ,ref pt_end);
}
那么直线旋转呢?
public void 直线旋转(PointF 指定点, double 弧度)//针对指定点旋转
{
矩阵变换 temp=new 矩阵变换();
PointF tempPt=new PointF(-指定点.X,-指定点.Y);
直线平移(指定点);
temp.原点旋转(弧度 ,ref pt_start);
temp.原点旋转(弧度 ,ref pt_end);
直线平移(tempPt);
}
好,出战告捷报,完成两个类。