C# OpenCvSharp 透视变换(图像摆正)Demo

您所在的位置:网站首页 手机拍照透视变形 C# OpenCvSharp 透视变换(图像摆正)Demo

C# OpenCvSharp 透视变换(图像摆正)Demo

2024-07-08 23:10| 来源: 网络整理| 查看: 265

目录

效果

代码

下载

效果

代码

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using OpenCvSharp; using OpenCvSharp.Extensions; using System.Reflection; using System.Drawing.Imaging;

namespace OpenCvSharp_透视变换_图像摆正_ {     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }

        Bitmap bmp;         string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";         string img = "";         private void button2_Click(object sender, EventArgs e)         {             index = 0;             OpenFileDialog ofd = new OpenFileDialog();             ofd.Filter = fileFilter;             if (ofd.ShowDialog() != DialogResult.OK) return;             img = ofd.FileName;             var imagebyte = File.ReadAllBytes(img);             bmp = new Bitmap(img);             pictureBox1.Image = new Bitmap(img);         }

        private void button1_Click(object sender, EventArgs e)         {             Graphics gSave = Graphics.FromImage(bmp);             System.Drawing.Point imagePoint = new System.Drawing.Point();

            GetImagePix(pt[0], out imagePoint);             DrawFlag(gSave, imagePoint, 1);             ptDst[0].X = imagePoint.X;             ptDst[0].Y = imagePoint.Y;

            GetImagePix(pt[1], out imagePoint);             DrawFlag(gSave, imagePoint, 2);             ptDst[1].X = imagePoint.X;             ptDst[1].Y = imagePoint.Y;

            GetImagePix(pt[2], out imagePoint);             DrawFlag(gSave, imagePoint, 3);             ptDst[2].X = imagePoint.X;             ptDst[2].Y = imagePoint.Y;

            GetImagePix(pt[3], out imagePoint);             DrawFlag(gSave, imagePoint, 4);             ptDst[3].X = imagePoint.X;             ptDst[3].Y = imagePoint.Y;

            gSave.DrawLine(pen, ptDst[0].X, ptDst[0].Y, ptDst[1].X, ptDst[1].Y);             gSave.DrawLine(pen, ptDst[1].X, ptDst[1].Y, ptDst[2].X, ptDst[2].Y);             gSave.DrawLine(pen, ptDst[2].X, ptDst[2].Y, ptDst[3].X, ptDst[3].Y);             gSave.DrawLine(pen, ptDst[3].X, ptDst[3].Y, ptDst[0].X, ptDst[0].Y);

            bmp.Save("temp.jpg", ImageFormat.Jpeg);

            gSave.Dispose();

            System.Diagnostics.Process.Start(Application.StartupPath);         }

        Pen pen = new Pen(Color.Red, 3);         Pen pen1 = new Pen(Color.Green, 3);         Font font = new Font("宋体", 12);         SolidBrush solidBrush = new SolidBrush(Color.Red);         int index = 0;         public System.Drawing.Point[] pt = new System.Drawing.Point[4];         public System.Drawing.Point[] ptDst = new System.Drawing.Point[4];

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)         {             Graphics g = pictureBox1.CreateGraphics();             if (index > 3)             {                 //点排序

                //连线                 g.DrawLine(pen, pt[0].X, pt[0].Y, pt[1].X, pt[1].Y);                 g.DrawLine(pen, pt[1].X, pt[1].Y, pt[2].X, pt[2].Y);                 g.DrawLine(pen, pt[2].X, pt[2].Y, pt[3].X, pt[3].Y);                 g.DrawLine(pen, pt[3].X, pt[3].Y, pt[0].X, pt[0].Y);                 return;             }

            pt[index].X = e.X;             pt[index].Y = e.Y;

            g.DrawLine(pen, e.X - 5, e.Y, e.X + 6, e.Y);             g.DrawLine(pen, e.X, e.Y - 5, e.X, e.Y + 6);

            ++index;

            //string str = (++index).ToString() + string.Format("({0},{1})", e.X, e.Y);             //g.DrawString(str, font, solidBrush, e.X, e.Y);

            if (index > 3)             {                 //点排序

                //连线                 g.DrawLine(pen, pt[0].X, pt[0].Y, pt[1].X, pt[1].Y);                 g.DrawLine(pen, pt[1].X, pt[1].Y, pt[2].X, pt[2].Y);                 g.DrawLine(pen, pt[2].X, pt[2].Y, pt[3].X, pt[3].Y);                 g.DrawLine(pen, pt[3].X, pt[3].Y, pt[0].X, pt[0].Y);             }

            g.Dispose();         }

        private void GetImagePixLocation(System.Drawing.Size pictureBoxSize, System.Drawing.Size imageSize, System.Drawing.Point pictureBoxPoint, out System.Drawing.Point imagePoint)         {

            imagePoint = new System.Drawing.Point(0, 0);

            double scale;

            int detalInHeight = 0;

            int detalInWidth = 0;

            if (Convert.ToDouble(pictureBoxSize.Width) / pictureBoxSize.Height > Convert.ToDouble(imageSize.Width) / imageSize.Height)             {                 scale = 1.0 * imageSize.Height / pictureBoxSize.Height;                 detalInWidth = Convert.ToInt32((pictureBoxSize.Width * scale - imageSize.Width) / 2.0);             }

            else             {                 scale = 1.0 * imageSize.Width / pictureBoxSize.Width;                 detalInHeight = Convert.ToInt32((pictureBoxSize.Height * scale - imageSize.Height) / 2.0);             }

            imagePoint.X = Convert.ToInt32(pictureBoxPoint.X * scale - detalInWidth);

            imagePoint.Y = Convert.ToInt32(pictureBoxPoint.Y * scale - detalInHeight);

        }

        private void GetImagePix(System.Drawing.Point pictureBoxPoint, out System.Drawing.Point imagePoint)         {             GetImagePixLocation(pictureBox1.Size, pictureBox1.Image.Size, pictureBoxPoint, out imagePoint);         }         void DrawFlag(Graphics g, System.Drawing.Point e, int index)         {             g.DrawLine(pen, e.X - 5, e.Y, e.X + 6, e.Y);             g.DrawLine(pen, e.X, e.Y - 5, e.X, e.Y + 6);             string str = string.Format("{0}({1},{2})", index, e.X, e.Y);             g.DrawString(str, font, solidBrush, e.X, e.Y);         }

        private void button3_Click(object sender, EventArgs e)         {             if (index == 0)             {                 MessageBox.Show("请先使用鼠标左键在图片上选择四个角的点");                 return;             }             else             {                 index = 0;             }

            Mat src = new Mat(img, ImreadModes.Color);

            Point2f[] srcPt = new Point2f[4];             Point2f[] dstPt = new Point2f[4];

            //左上 右上 右下 左下             System.Drawing.Point imagePoint = new System.Drawing.Point();             GetImagePix(pt[0], out imagePoint);             srcPt[0].X = imagePoint.X;             srcPt[0].Y = imagePoint.Y;

            GetImagePix(pt[1], out imagePoint);             srcPt[1].X = imagePoint.X;             srcPt[1].Y = imagePoint.Y;

            GetImagePix(pt[2], out imagePoint);             srcPt[2].X = imagePoint.X;             srcPt[2].Y = imagePoint.Y;

            GetImagePix(pt[3], out imagePoint);             srcPt[3].X = imagePoint.X;             srcPt[3].Y = imagePoint.Y;

            dstPt[0] = new Point2f(0, 0);             dstPt[1] = new Point2f(bmp.Width, 0);             dstPt[2] = new Point2f(bmp.Width, bmp.Height);             dstPt[3] = new Point2f(0, bmp.Height);

            Mat final = new Mat();             Mat warpmatrix = Cv2.GetPerspectiveTransform(srcPt, dstPt);//获得变换矩阵             Cv2.WarpPerspective(src, final, warpmatrix, src.Size());//投射变换,将结果赋给final

            if (pictureBox1.Image != null)             {                 pictureBox1.Image.Dispose();             }             pictureBox1.Image = BitmapConverter.ToBitmap(final);         }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)         {             if (pictureBox1.Image == null)             {                 return;             }

            int originalWidth = this.pictureBox1.Image.Width;             int originalHeight = this.pictureBox1.Image.Height;

            PropertyInfo rectangleProperty = this.pictureBox1.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);             Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.pictureBox1, null);

            int currentWidth = rectangle.Width;             int currentHeight = rectangle.Height;

            double rate = (double)currentHeight / (double)originalHeight;

            int black_left_width = (currentWidth == this.pictureBox1.Width) ? 0 : (this.pictureBox1.Width - currentWidth) / 2;             int black_top_height = (currentHeight == this.pictureBox1.Height) ? 0 : (this.pictureBox1.Height - currentHeight) / 2;

            int zoom_x = e.X - black_left_width;             int zoom_y = e.Y - black_top_height;

            double original_x = (double)zoom_x * rate;             double original_y = (double)zoom_y * rate;

            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("原始尺寸:({0},{1})(宽/高)\r\n\r\n", originalWidth, originalHeight);             sb.AppendFormat("缩放状态图片尺寸:({0},{1})(宽,高)\r\n\r\n", currentWidth, currentHeight);             sb.AppendFormat("缩放比率:{0}\r\n\r\n", rate);             sb.AppendFormat("左留白宽度:{0}\r\n\r\n", black_left_width);             sb.AppendFormat("上留白高度:{0}\r\n\r\n", black_top_height);             sb.AppendFormat("当前鼠标坐标:({0},{1})(X,Y)\r\n\r\n", e.X, e.Y);

            textBox1.Text = sb.ToString();         }     } }

下载

源码下载 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3