emguCV实现仿射变换

来源:互联网 发布:jq遍历json数组 编辑:程序博客网 时间:2024/05/18 00:51
  • 自带的函数
    采用自带的例如CvInvoke.GetRotationMatrix2D函数会生成非齐次的2X3矩阵。通过旋转中心、缩放、平移的参数可得一个Mat类型的值,该值与图像的Mat便可使得图像平移、缩放、旋转。
    Image<Bgr,byte> My_Image = new Image<Bgr, byte>("lena.jpg");                        this.Size = My_Image.Size;            Image<Gray, byte> gray_image = My_Image.Convert<Gray, byte>();        Mat AffineMat = new Mat();          //中心,旋转,比例      CvInvoke.GetRotationMatrix2D(new PointF(gray_image.Cols / 2, gray_image.Rows / 2), 20, 1, AffineMat);        CvInvoke.WarpAffine(gray_image, gray_image, AffineMat,gray_image.Size,Inter.Cubic,Warp.FillOutliers,BorderType.Constant);       pictureBox1.Image = gray_image.ToBitmap();
注意CvInvoke.WarpAffine函数需要指定插值的方法,可以当成因为缩放时像素丢失所必须做的插值运算。采用线性插值时速度最快,但容易产生锯齿。建议使用双线性插值。
  • 自生成矩阵运算
    矩阵的代表的含义可以自行百度链接。

    -cmgucv数组可以直接转换矩阵,以下是对一个点做仿射变换。

//平移     float x = 100;     float y = 0;     float[] PointOri = { x, y ,1};     float offerX = 50,offerY = 0;     float[,] AffineOffer = { { 1.0f,0.0f,offerX},                              { 0.0f,1.0f,offerY},                              { 0.0f,0.0f,1.0f} };     //缩放     float ScaleX = 1, ScaleY = 1;     float[,] AffineScale = { { ScaleX,0.0f,0.0f},                              { 0.0f,ScaleY,0.0f},                              { 0.0f,0.0f,1.0f} };     //绕某点旋转     float a = -(float)Math.PI * (20.0f / 180.0f); //单位换算     float CenterX = gray_image.Cols / 2, CenterY = gray_image.Rows / 2;     float[,] AffineRotate = { { (float)Math.Cos(a),(float)-Math.Sin(a),(float)(CenterX-CenterX*Math.Cos(a)+CenterY*Math.Sin(a))},                              { (float)Math.Sin(a),(float)Math.Cos(a),(float)(CenterY-CenterX*Math.Sin(a)-CenterY*Math.Cos(a))},                              { 0.0f,0.0f,1.0f} };     Matrix<Single> AffineOfferMat = new Matrix<float>(AffineOffer);     Matrix<Single> AffineScaleMat = new Matrix<float>(AffineScale);     Matrix<Single> AffineRotateMat = new Matrix<float>(AffineRotate);     Matrix<Single> PointOriMat = new Matrix<float>(PointOri);     Matrix<Single> PointMat = AffineRotateMat.Mul(AffineOfferMat);  //旋转+平移     PointMat = AffineOfferMat.Mul(AffineScaleMat);  //旋转+平移+缩放     PointMat = PointMat.Mul(PointOriMat);     x = PointMat.Data[0, 0];     y = PointMat.Data[1, 0];     Cross2DF crossTest = new Cross2DF(new PointF(x, y), 30, 30);     CvInvoke.WarpAffine(gray_image, gray_image, AffineMat,gray_image.Size,Inter.Cubic,Warp.FillOutliers,BorderType.Constant);     gray_image.Draw(cross, new Gray(255), 1);     gray_image.Draw(crossTest, new Gray(255), 1);     pictureBox1.Image = gray_image.ToBitmap();