本示例是《OpenCV3编程入门》中7.4.5中的示例程序的C# + EMGU 3.4.1版,演示了以WarpAffine和GetRotationMatrix2D函数为核心的对图像进行仿射变换的操作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
namespace warpAffine
{
class Program
{
static void Main(string[] args)
{
//【1】参数准备
//定义两组点,代表两个三角形
PointF[] srcTriangle = new PointF[3];
PointF[] dstTriangle = new PointF[3];
//定义一些Mat变量
Mat warpMat = new Mat(2, 3, DepthType.Cv32F, 1);
Mat rotMat = new Mat(2, 3, DepthType.Cv32F, 1);
Mat srcImage = new Mat(), dstImage_warp = new Mat(), dstImage_warp_rotate = new Mat();
//【2】加载源图像并作一些初始化
srcImage = CvInvoke.Imread("landscape1.jpg"); //首先确保目录中存在该图片
//设置目标类型的大小和类型与源图像一致
dstImage_warp = Mat.Zeros(srcImage.Rows, srcImage.Cols, srcImage.Depth, srcImage.NumberOfChannels);
//【3】设置源图像和目标图像上的三组点以计算用于仿射变换的矩阵
srcTriangle[0] = new PointF(0, 0);
srcTriangle[1] = new PointF(srcImage.Cols - 1, 0);
srcTriangle[2] = new PointF(0, srcImage.Rows - 1);
dstTriangle[0] = new PointF((float)(srcImage.Cols * 0.0), (float)(srcImage.Rows * 0.33));
dstTriangle[1] = new PointF((float)(srcImage.Cols * 0.65), (float)(srcImage.Rows * 0.35));
dstTriangle[2] = new PointF((float)(srcImage.Cols * 0.15), (float)(srcImage.Rows * 0.6));
//【4】求得用于仿射变换的矩阵
warpMat = CvInvoke.GetAffineTransform(srcTriangle, dstTriangle);
//【5】对源图像应用以上求得的仿射变换矩阵
CvInvoke.WarpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.Size);
//【6】对图像进行缩放后再旋转
//计算绕图像中心点顺时针旋转30度,缩放因子为0.6的旋转矩阵
Point center = new Point(dstImage_warp.Cols / 2, dstImage_warp.Rows / 2);
double angle = -30.0;
double scale = 0.6;
//通过以上的旋转细节信息求得旋转矩阵
CvInvoke.GetRotationMatrix2D(center, angle, scale, rotMat);
//调用仿射变换函数,进行图像的旋转和缩放
CvInvoke.WarpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.Size);
//【7】显示结果
CvInvoke.Imshow("Source Image", srcImage);
CvInvoke.Imshow("Warp Image", dstImage_warp);
CvInvoke.Imshow("Warp Rotate Image", dstImage_warp_rotate);
//等待用户按任意键退出程序
CvInvoke.WaitKey(0);
}
}
}
程序运行截图如下: