- 自带的函数
采用自带的例如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();