先用红点标出旋转中心的位置,用绿点标出转换前的位置
变换之后,红圈圈出新的坐标
改变旋转中心,角度,放大系数:
结果:
源码:
public void Run()
{
Mat mat = new Mat(800, 800, MatType.CV_8UC3);
//网络线
for (int i = 0; i <= 10; i++)
{
Cv2.Line(mat, new Point(i * 100 + 50, 0), new Point(i * 100 + 50, 800), new Scalar(60,60,60));
Cv2.Line(mat, new Point(0, i * 100 + 50), new Point(800, i * 100 + 50), new Scalar(60, 60, 60));
Cv2.Line(mat, new Point(i * 100, 0), new Point(i * 100, 800), Scalar.Gray );
Cv2.Line(mat, new Point(0, i * 100), new Point(800, i * 100), Scalar.Gray );
}
//旋转中心
Point center = new Point(300, 400);
Cv2.Circle(mat, center, 5, Scalar.Red, -1);
Cv2.ArrowedLine(mat, center, center+new Point(100,0), Scalar.Green);
Cv2.ArrowedLine(mat, center, center + new Point(0, 100), Scalar.Red);
//测试点
Point p = new Point(250, 450);
Cv2.Circle(mat, p, 5, Scalar.Lime, -1);
Cv2.ImShow("T", mat);
Mat mat1 = MatRotate(mat, center, -65, p);
Cv2.ImShow("T1", mat1);
Cv2.WaitKey();
}
private Mat MatRotate(Mat src, Point center, float angle, Point point)
{
Mat dst = new Mat();
Mat rot = Cv2.GetRotationMatrix2D(center, angle, 1.5);
Console.WriteLine(Cv2.Format(rot, FormatType.Python));
Cv2.WarpAffine(src, dst, rot, src.Size());
var x = point.X * rot.At<double>(0, 0) + point.Y * rot.At<double>(0, 1) + rot.At<double>(0, 2);
var y = point.X * rot.At<double>(1, 0) + point.Y * rot.At<double>(1, 1) + rot.At<double>(1, 2);
x = Math.Round(x, 0);
y = Math.Round(y, 0);
Point p = new Point(x, y);
Cv2.Circle(dst, p, 10, Scalar.Red, 1);
return dst;
}