机器视觉入门之路(二十,图像旋转之后,c#)

总结图像旋转,突然发现矩阵运算(二维概念)很重要,我们应该有一个基础矩阵运算类,我们把先学会的平移,旋转,翻转引入到类中(简单就好,以后需要的功能,可再增加,一次要设计好,脑瓜疼!),你会发现,坐标系中的每一个点(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)*\begin{bmatrix}1 ,0 ,0\\ 0 ,1 ,0\\-zhidingdian.x,-zhidingdian.y, 1 \end{bmatrix},程序怎么整?

  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)*\begin{bmatrix} cos\Theta ,-sin\Theta ,0\\ sin\Theta ,cos\Theta ,0\\0,0, 1 \end{bmatrix},程序怎么整?

好,先整一个类: 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);
        }

好,出战告捷报,完成两个类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值