OpenCVSharp返回仿射变换后的完整图形

本文探讨了如何通过计算仿射变换后图形的边界来确保在原图框内完整显示,介绍了如何确定新图大小和原点对齐的方法,提供了MatMatRotate函数的实现细节和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

仿射变换后的图形如果还在原图框中显示,会有一部分显示不出来,

 

这个函数的思路是计算原图的4个角转换后的位置,然后求最小外接矩,就得到了新图的大小,

 

然后再看原点偏移在4个像限时的对齐方法,这里只是抛砖引玉一下,应该还有更好的方法。

 

        /// <summary>
        /// 仿射变换       
        /// </summary>
        /// <param name="src">输入</param>
        /// <param name="center">中心</param>
        /// <param name="angle">角度</param>
        /// <returns> 返回仿射变换后的完整图形 </returns>
        private static Mat MatRotate(Mat src, Point center, float angle)
        {



            while (angle < 0) angle += 360;
            if (angle > 360) angle %= 360;
            Mat dst = new Mat();

            //变换矩阵
            Mat rot = Cv2.GetRotationMatrix2D(center, angle, 1);
            Console.WriteLine(Cv2.Format(rot, FormatType.Python));

            //X==0 Y==0
            var w1 = rot.At<double>(0, 2);
            var h1 = rot.At<double>(1, 2);


            //Y==0
            var w2 = src.Width * rot.At<double>(0, 0) + rot.At<double>(0, 2);
            var h2 = src.Width * rot.At<double>(1, 0) + rot.At<double>(1, 2);

            //x==0
            var w3 = src.Height * rot.At<double>(0, 1) + rot.At<double>(0, 2);
            var h3 = src.Height * rot.At<double>(1, 1) + rot.At<double>(1, 2);

            var w4 = src.Width * rot.At<double>(0, 0) + src.Height * rot.At<double>(0, 1) + rot.At<double>(0, 2);
            var h4 = src.Width * rot.At<double>(1, 0) + src.Height * rot.At<double>(1, 1) + rot.At<double>(1, 2);

            Point[] points = { new(w1, h1), new(w2, h2), new(w3, h3), new(w4, h4) };

     //       foreach (var p in points)
        //        Console.WriteLine(p);
            Rect rRect = Cv2.BoundingRect(points);
            switch (angle)
            {
                case >= 0 and <= 90:
                    rot.Set<double>(0, 2, 0);
                    rot.Set<double>(1, 2, h1 - h2);
                    break;
                case > 90 and <= 180:
                    rot.Set<double>(0, 2, -w2 + w1);
                    rot.Set<double>(1, 2, rRect.Height);
                    break;
                case > 180 and <= 270:
                    rot.Set<double>(0, 2, rRect.Width);
                    rot.Set<double>(1, 2, h1-h3);
                    break;
                case > 270:
                    rot.Set<double>(0, 2, w1 - w3);
                    rot.Set<double>(1, 2, 0);
                    break;

            }
           // Console.WriteLine(Cv2.Format(rot, FormatType.Python));

            Cv2.WarpAffine(src, dst, rot, rRect.Size);
            return dst;
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值