CrazyIter 4 лет назад
Родитель
Сommit
b4ad26b865

+ 31 - 0
OpenCVDemo.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30413.136
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenCVDemo", "OpenCVDemo\OpenCVDemo.csproj", "{DE3B6D6A-FC3A-4FCB-AE58-1EAFB9838029}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenCVTest", "OpenCVTest\OpenCVTest.csproj", "{76B8C618-B391-444A-806F-22DD6B9C923B}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{DE3B6D6A-FC3A-4FCB-AE58-1EAFB9838029}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DE3B6D6A-FC3A-4FCB-AE58-1EAFB9838029}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DE3B6D6A-FC3A-4FCB-AE58-1EAFB9838029}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DE3B6D6A-FC3A-4FCB-AE58-1EAFB9838029}.Release|Any CPU.Build.0 = Release|Any CPU
+		{76B8C618-B391-444A-806F-22DD6B9C923B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{76B8C618-B391-444A-806F-22DD6B9C923B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{76B8C618-B391-444A-806F-22DD6B9C923B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{76B8C618-B391-444A-806F-22DD6B9C923B}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {24F6B75A-D46A-48B6-8D07-4309E57C1904}
+	EndGlobalSection
+EndGlobal

+ 100 - 0
OpenCVDemo/Form1.Designer.cs

@@ -0,0 +1,100 @@
+namespace OpenCVDemo
+{
+    partial class Form1
+    {
+        /// <summary>
+        ///  Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        ///  Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        ///  Required method for Designer support - do not modify
+        ///  the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.button1 = new System.Windows.Forms.Button();
+            this.pictureBox1 = new System.Windows.Forms.PictureBox();
+            this.listBox1 = new System.Windows.Forms.ListBox();
+            this.listBox2 = new System.Windows.Forms.ListBox();
+            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // button1
+            // 
+            this.button1.Location = new System.Drawing.Point(1, 1);
+            this.button1.Name = "button1";
+            this.button1.Size = new System.Drawing.Size(75, 23);
+            this.button1.TabIndex = 0;
+            this.button1.Text = "button1";
+            this.button1.UseVisualStyleBackColor = true;
+            this.button1.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // pictureBox1
+            // 
+            this.pictureBox1.Location = new System.Drawing.Point(102, 30);
+            this.pictureBox1.Name = "pictureBox1";
+            this.pictureBox1.Size = new System.Drawing.Size(1091, 718);
+            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+            this.pictureBox1.TabIndex = 1;
+            this.pictureBox1.TabStop = false;
+            this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click);
+            // 
+            // listBox1
+            // 
+            this.listBox1.FormattingEnabled = true;
+            this.listBox1.ItemHeight = 17;
+            this.listBox1.Location = new System.Drawing.Point(1, 30);
+            this.listBox1.Name = "listBox1";
+            this.listBox1.Size = new System.Drawing.Size(95, 718);
+            this.listBox1.TabIndex = 2;
+            // 
+            // listBox2
+            // 
+            this.listBox2.FormattingEnabled = true;
+            this.listBox2.ItemHeight = 17;
+            this.listBox2.Location = new System.Drawing.Point(1199, 30);
+            this.listBox2.Name = "listBox2";
+            this.listBox2.Size = new System.Drawing.Size(142, 718);
+            this.listBox2.TabIndex = 3;
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(1341, 757);
+            this.Controls.Add(this.listBox2);
+            this.Controls.Add(this.listBox1);
+            this.Controls.Add(this.pictureBox1);
+            this.Controls.Add(this.button1);
+            this.Name = "Form1";
+            this.Text = "Form1";
+            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.PictureBox pictureBox1;
+        private System.Windows.Forms.ListBox listBox1;
+        private System.Windows.Forms.ListBox listBox2;
+    }
+}
+

+ 551 - 0
OpenCVDemo/Form1.cs

@@ -0,0 +1,551 @@
+using OpenCvSharp;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Point = OpenCvSharp.Point;
+
+namespace OpenCVDemo
+{
+    public partial class Form1 : Form
+    {
+        public Form1()
+        {
+            InitializeComponent();
+        }
+        public string my_imagesource, my_imagesource2;
+        private Mat image1;
+        private Mat image2;
+        public int[,] myOPENCV_runlist = new int[20, 5];//运行步骤列表 与myOPENCV_value不同的是,运行步骤限定为20步,列的第一个元素存放运行函数下标
+        private void button1_Click(object sender, EventArgs e)
+        {
+
+            pictureBox1.Load(@"F:/20191204104138.jpg");
+            Mat image1 = new Mat(@"F:/20191204104138.jpg");
+            image2 = new Mat();
+            //// Mat src = new Mat(@"F:/rmb.png", ImreadModes.Color);
+            // Cv2.ImShow("src", src);
+            // #region
+            // //Mat rotateImage = new Mat(src.Rows, src.Cols, MatType.CV_8UC3);
+            // //rotateImage.SetTo(0);
+            // //Mat M= Cv2.GetRotationMatrix2D(new Point2f(300, 300), 30, 0.5);
+            // //Cv2.WarpAffine(src, rotateImage, M, src.Size(), InterpolationFlags.WarpInverseMap);//flags: 插值算法标识符,有默认值INTER_LINEAR
+            // //Cv2.ImShow("11", rotateImage);
+            // //Cv2.WaitKey();
+            // #endregion
+            // Mat gray = new Mat();
+            // Mat binary = new Mat();
+            // Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
+            // Cv2.Threshold(gray, binary, 50, 255, ThresholdTypes.Binary);//转换为二值图像
+            // Cv2.ImShow("bin", binary);
+            // //Cv2.WaitKey();
+            // //建立轮廓接受数组
+            // Point[][] contours;
+            // HierarchyIndex[] hierarchy;
+            // Cv2.FindContours(binary, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
+            // //最小外接矩形接收数组
+            // RotatedRect[] rotateRect = new RotatedRect[contours.Length];
+            // Point[][] contours_poly = new Point[contours.Length][];
+            // for (int i = 0; i < contours.Length; i++)
+            // {
+            //     contours_poly[i] = Cv2.ApproxPolyDP(contours[i], 30, true);//返回凸包,单线长大于30过滤
+
+            //     rotateRect[i] = Cv2.MinAreaRect(contours_poly[i]);//最小外接矩形集合
+            //                                                       //}
+            //     Console.WriteLine(rotateRect.Length);
+            //     Point2f[] pot = new Point2f[4];//新建点集合接收点集合
+
+            //     //for (int i = 0; i < rotateRect.Length; i++)
+            //     //{
+            //     float angle = rotateRect[i].Angle;//矩形角度
+            //     pot = rotateRect[i].Points();//矩形的4个角
+            //     double line1 = Math.Sqrt((pot[0].X - pot[1].X) * (pot[0].X - pot[1].X) + (pot[0].Y - pot[1].Y) * (pot[0].Y - pot[1].Y));
+            //     double line2 = Math.Sqrt((pot[0].X - pot[3].X) * (pot[0].X - pot[3].X) + (pot[0].Y - pot[3].Y) * (pot[0].Y - pot[3].Y));
+            //     if (line1 * line2 < 1000)//过滤,太小的矩形直接pass
+            //     {
+            //         continue;
+            //     }
+            //     if (line1 > line2)//依据实际情况进行判断
+            //     {
+            //         angle += 90;
+            //     }
+
+            //     Console.WriteLine(line1);
+            //     Console.WriteLine(line2);
+            //     Mat Roi = new Mat(src.Size(), MatType.CV_8UC3);
+            //     Roi.SetTo(0);//全黑
+            //     Cv2.DrawContours(binary, contours, -1, Scalar.White, -1);//在二值图像中圈出轮廓区域并染白
+            //     Cv2.ImShow("bin", binary);
+            //     src.CopyTo(Roi, binary);//将原图通过mask抠图到Roi
+            //     Cv2.ImShow("Roi", Roi);
+            //     Mat afterRotato = new Mat(src.Size(), MatType.CV_8UC3);
+            //     afterRotato.SetTo(0);
+            //     Point2f center = rotateRect[i].Center;
+            //     Mat M = Cv2.GetRotationMatrix2D(center, angle, 1);//计算变换矩阵
+            //     Cv2.WarpAffine(Roi, afterRotato, M, Roi.Size(), InterpolationFlags.Linear, BorderTypes.Constant);//得到变换后的图像,滤除其他信息
+            //     Cv2.ImShow("旋转后", afterRotato);
+            //     Mat bin2 = new Mat();
+            //     Cv2.ImShow("after", afterRotato);
+            //     Cv2.CvtColor(afterRotato, bin2, ColorConversionCodes.BGR2GRAY);
+            //     Cv2.Threshold(bin2, bin2, 20, 255, ThresholdTypes.Binary);
+            //     Point[][] con;
+            //     HierarchyIndex[] temp;//接收矫正后的轮廓信息
+            //     Cv2.FindContours(bin2, out con, out temp, RetrievalModes.External, ContourApproximationModes.ApproxNone);
+            //     for (int j = 0; j < con.Length; j++)
+            //     {
+            //         Rect rect = Cv2.BoundingRect(con[j]);//直接使用矫正矩形,因为矫正后不需要再旋转
+            //         if (rect.Height * rect.Width < 8000)//过滤干扰信息
+            //         {
+            //             continue;
+            //         }
+            //         Mat dstImg = new Mat(afterRotato, rect);
+            //         //string name = "dst" + i;//主要看调试的时候有几个结果
+            //         Cv2.ImShow("dst", dstImg);
+            //     }
+            // }
+            // Cv2.WaitKey();
+        }
+        private Mat myOPENCV_run(Mat image_in, Mat image_out)
+        {
+            image_out = image_in;
+            for (int i = 0; i < listBox2.Items.Count; i++)
+            {
+                switch ((myOPENCV)myOPENCV_runlist[i, 0])
+                {
+                    case myOPENCV.cvt_color:
+                        {
+                            Cv2.CvtColor(image_out, image_out, (ColorConversionCodes)myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 2]);
+                            break;
+                        }
+                    case myOPENCV.boxfilter:
+                        {
+                            OpenCvSharp.Size size;
+                            size.Width = myOPENCV_runlist[i, 2];
+                            size.Height = myOPENCV_runlist[i, 3];
+                            Cv2.BoxFilter(image_out, image_out, myOPENCV_runlist[i, 1], size);
+                            break;
+                        }
+                    case myOPENCV.blur:
+                        {
+                            OpenCvSharp.Size size;
+                            size.Width = myOPENCV_runlist[i, 1];
+                            size.Height = myOPENCV_runlist[i, 2];
+                            Cv2.Blur(image_out, image_out, size);
+                            break;
+                        }
+                    case myOPENCV.gaussianblur:
+                        {
+                            OpenCvSharp.Size size;
+                            double sigmaX, sigmaY;
+                            size.Width = myOPENCV_runlist[i, 1];
+                            size.Height = myOPENCV_runlist[i, 2];
+                            sigmaX = (double)myOPENCV_runlist[i, 3];
+                            sigmaY = (double)myOPENCV_runlist[i, 4];
+
+                            Cv2.GaussianBlur(image_out, image_out, size, sigmaX, sigmaY);
+                            break;
+                        }
+                    case myOPENCV.medianblur:
+                        {
+                            Cv2.MedianBlur(image_in, image_out, myOPENCV_runlist[i, 1]);
+                            break;
+                        }
+                    case myOPENCV.bilateralfilter:
+                        {
+                            Mat image_out2 = new Mat();
+                            double sigmaColor, sigmaSpace;
+                            sigmaColor = (double)myOPENCV_runlist[i, 2] * 2;
+                            sigmaSpace = (double)myOPENCV_runlist[i, 3] / 2;
+                            Cv2.BilateralFilter(image_out, image_out2, myOPENCV_runlist[i, 1], sigmaColor, sigmaSpace);
+                            image_out = image_out2;
+                            break;
+                        }
+                    case myOPENCV.dilate:
+                        {
+                            Mat image_element = new Mat();
+                            OpenCvSharp.Size size;
+                            size.Width = myOPENCV_runlist[i, 2];
+                            size.Height = myOPENCV_runlist[i, 3];
+                            image_element = Cv2.GetStructuringElement((MorphShapes)myOPENCV_runlist[i, 1], size);
+                            Cv2.Dilate(image_out, image_out, image_element);
+                            break;
+                        }
+                    case myOPENCV.erode:
+                        {
+                            Mat image_element = new Mat();
+                            OpenCvSharp.Size size;
+                            size.Width = myOPENCV_runlist[i, 2];
+                            size.Height = myOPENCV_runlist[i, 3];
+                            image_element = Cv2.GetStructuringElement((MorphShapes)myOPENCV_runlist[i, 1], size);
+                            Cv2.Erode(image_out, image_out, image_element);
+                            break;
+                        }
+                    case myOPENCV.morphologyex:
+                        {
+                            Mat image_element = new Mat();
+                            OpenCvSharp.Size size;
+                            size.Width = myOPENCV_runlist[i, 3];
+                            size.Height = myOPENCV_runlist[i, 4];
+                            image_element = Cv2.GetStructuringElement((MorphShapes)myOPENCV_runlist[i, 2], size);
+                            Cv2.MorphologyEx(image_out, image_out, (MorphTypes)myOPENCV_runlist[i, 1], image_element);
+                            break;
+                        }
+                    case myOPENCV.floodfill:
+                        {
+                            OpenCvSharp.Point point;
+                            point.X = myOPENCV_runlist[i, 1];
+                            point.Y = myOPENCV_runlist[i, 2];
+                            OpenCvSharp.Scalar scalar;
+                            scalar = myOPENCV_runlist[i, 3];
+                            Cv2.FloodFill(image_out, point, scalar);
+                            break;
+                        }
+                    case myOPENCV.pyrup:
+                        {
+                            OpenCvSharp.Size size;
+                            size.Width = image_out.Cols * 2;
+                            size.Height = image_out.Rows * 2;
+                            Cv2.PyrUp(image_out, image_out, size);
+                            break;
+                        }
+                    case myOPENCV.pyrdown:
+                        {
+                            OpenCvSharp.Size size;
+                            size.Width = image_out.Cols / 2;
+                            size.Height = image_out.Rows / 2;
+                            Cv2.PyrDown(image_out, image_out, size);
+                            break;
+                        }
+                    case myOPENCV.resize:
+                        {
+                            OpenCvSharp.Size size;
+                            InterpolationFlags interpolationFlags;
+                            size.Width = image_out.Cols * myOPENCV_runlist[i, 1] / 10;
+                            size.Height = image_out.Rows * myOPENCV_runlist[i, 2] / 10;
+                            interpolationFlags = (InterpolationFlags)myOPENCV_runlist[i, 3];
+                            Cv2.Resize(image_out, image_out, size, 0, 0, interpolationFlags);
+                            break;
+                        }
+                    case myOPENCV.threshold:
+                        {
+                            Cv2.Threshold(image_out, image_out, myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 2], (ThresholdTypes)myOPENCV_runlist[i, 3]);
+                            break;
+                        }
+                    case myOPENCV.canny:
+                        {
+                            Mat image_out2 = new Mat();
+                            Cv2.Canny(image_out, image_out2, myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 2], myOPENCV_runlist[i, 3]);
+                            image_out = image_out2;
+                            break;
+                        }
+                    case myOPENCV.sobel:
+                        {
+                            Cv2.Sobel(image_out, image_out, -1, myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 2], myOPENCV_runlist[i, 3]);
+                            break;
+                        }
+                    case myOPENCV.laplacian:
+                        {
+                            myOPENCV_runlist[i, 1] = 0;
+                            Cv2.Laplacian(image_out, image_out, 0, myOPENCV_runlist[i, 2], myOPENCV_runlist[i, 3]);
+                            break;
+                        }
+                    case myOPENCV.scharr:
+                        {
+                            Cv2.Scharr(image_out, image_out, -1, myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 2]);
+                            break;
+                        }
+                    case myOPENCV.convertscaleabs:
+                        {
+                            double alpha, beta;
+                            alpha = (double)myOPENCV_runlist[i, 1] / 10;
+                            beta = (double)myOPENCV_runlist[i, 2] / 10;
+                            Cv2.ConvertScaleAbs(image_out, image_out, alpha, beta);
+                            break;
+                        }
+                    case myOPENCV.addweighted:
+                        {
+                            Mat image_in2 = new Mat(my_imagesource2);
+                            double alpha, beta, gamma;
+                            alpha = (double)myOPENCV_runlist[i, 1] / 10;
+                            beta = (double)myOPENCV_runlist[i, 2] / 10;
+                            gamma = (double)myOPENCV_runlist[i, 3] / 10;
+                            Cv2.AddWeighted(image_out, alpha, image_in2, beta, gamma, image_out);
+                            break;
+                        }
+                    case myOPENCV.houghlines:
+                        {
+                            Scalar scalar = new Scalar(0x00, 0xFF, 0x00);//绿色
+                            LineSegmentPolar[] lines;
+                            OpenCvSharp.Size size = new OpenCvSharp.Size(image_out.Width, image_out.Height);
+                            Mat image_out3 = new Mat(size, MatType.CV_8UC3);
+                            lines = Cv2.HoughLines(image_out, 1, Cv2.PI / 180, myOPENCV_runlist[i, 1]);
+                            for (int ii = 0; ii < lines.Length; ii++)
+                            {
+                                //double rho, theta;                    
+                                OpenCvSharp.Point pt1, pt2;
+                                double a = Math.Cos(lines[ii].Theta), b = Math.Sin(lines[ii].Theta);
+                                double x0 = a * lines[ii].Rho, y0 = b * lines[ii].Rho;
+                                pt1.X = (int)Math.Round(x0 + 1000 * (-b));
+                                pt1.Y = (int)Math.Round(y0 + 1000 * (a));
+                                pt2.X = (int)Math.Round(x0 - 1000 * (-b));
+                                pt2.Y = (int)Math.Round(y0 - 1000 * (a));
+                                Cv2.Line(image_out3, pt1, pt2, scalar, 1, LineTypes.AntiAlias);
+                            }
+                            if (myOPENCV_runlist[i, 2] == 0)
+                            {
+                                Cv2.AddWeighted(image_out3, (double)myOPENCV_runlist[i, 3] / 10, image_in, (double)myOPENCV_runlist[i, 4] / 10, 0, image_out);
+                            }
+                            else
+                            {
+                                image_out = image_out3;
+                            }
+                            break;
+                        }
+                    case myOPENCV.houghlinep:
+                        {
+                            Scalar scalar = new Scalar(0x00, 0xFF, 0x00);//绿色
+                            LineSegmentPoint[] lines;
+                            OpenCvSharp.Size size = new OpenCvSharp.Size(image_out.Width, image_out.Height);
+                            Mat image_out3 = new Mat(size, MatType.CV_8UC3);
+                            lines = Cv2.HoughLinesP(image_out, 1, Cv2.PI / 180, myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 3], myOPENCV_runlist[i, 4]);
+                            for (int ii = 0; ii < lines.Length; ii++)
+                            {
+                                OpenCvSharp.Point point1, point2;
+                                point1.X = lines[i].P1.X;
+                                point1.Y = lines[i].P1.Y;
+                                point2.X = lines[i].P2.X;
+                                point2.Y = lines[i].P2.Y;
+                                Cv2.Line(image_out3, point1, point2, scalar, 1, LineTypes.AntiAlias);
+                            }
+                            if (myOPENCV_runlist[i, 2] == 0)
+                            {
+                                Cv2.AddWeighted(image_out3, 1, image_in, 0.8, 0, image_out);
+                            }
+                            else
+                            {
+                                image_out = image_out3;
+                            }
+                            break;
+                        }
+                    case myOPENCV.houghcircles:
+                        {
+                            Scalar scalar = new Scalar(0x00, 0xFF, 0x00);//绿色
+                            CircleSegment[] circles;
+                            OpenCvSharp.Size size = new OpenCvSharp.Size(image_out.Width, image_out.Height);
+                            Mat image_out3 = new Mat(size, MatType.CV_8UC3);
+                            circles = Cv2.HoughCircles(image_out, HoughMethods.Gradient, 1, myOPENCV_runlist[i, 1], myOPENCV_runlist[i, 2], myOPENCV_runlist[i, 3], 0, myOPENCV_runlist[i, 4]);
+                            for (int ii = 0; ii < circles.Length; ii++)
+                            {
+                                OpenCvSharp.Point center;
+                                center.X = (int)Math.Round(circles[ii].Center.X);
+                                center.Y = (int)Math.Round(circles[ii].Center.Y);
+                                int radius = (int)Math.Round(circles[ii].Radius);
+                                Cv2.Circle(image_out3, center.X, center.Y, radius, scalar);
+                                Cv2.Circle(image_out3, center, radius, scalar);
+                            }
+                            Cv2.AddWeighted(image_out3, 1, image_in, 0.6, 0, image_out);
+
+                            break;
+                        }
+                    case myOPENCV.remap:
+                        {
+                            OpenCvSharp.Size size = new OpenCvSharp.Size(image_out.Width, image_out.Height);
+
+                            Mat map_x = new Mat(size, MatType.CV_32FC1), map_y = new Mat(size, MatType.CV_32FC1);
+                            for (int ii = 0; ii < image_out.Rows; ii++)
+                            {
+                                for (int jj = 0; jj < image_out.Cols; jj++)
+                                {
+                                    if (myOPENCV_runlist[i, 1] == 0)
+                                    {
+                                        map_x.Set<float>(ii, jj, jj);//上下翻转
+                                        map_y.Set<float>(ii, jj, image_out.Rows - ii);//上下翻转
+                                    }
+                                    else if (myOPENCV_runlist[i, 1] == 1)
+                                    {
+                                        map_x.Set<float>(ii, jj, image_out.Cols - jj);//左右翻转
+                                        map_y.Set<float>(ii, jj, ii);//左右翻转
+                                    }
+                                    else if (myOPENCV_runlist[i, 1] == 2)
+                                    {
+                                        map_x.Set<float>(ii, jj, image_out.Cols - jj);//上下左右翻转
+                                        map_y.Set<float>(ii, jj, image_out.Rows - ii);//上下左右翻转
+                                    }
+                                    else if (myOPENCV_runlist[i, 1] == 3)
+                                    {
+                                        map_x.Set<float>(ii, jj, (float)myOPENCV_runlist[i, 2] / 10 * jj);//放大缩小
+                                        map_y.Set<float>(ii, jj, (float)myOPENCV_runlist[i, 2] / 10 * ii);//放大缩小
+                                    }
+
+                                }
+                            }
+                            Cv2.Remap(image_out, image_out, map_x, map_y);
+                            break;
+                        }
+                    case myOPENCV.warpaffine:
+                        {
+                            if (0 == myOPENCV_runlist[i, 1])
+                            {
+                                Mat rot_mat = new Mat(2, 3, MatType.CV_32FC1);
+                                OpenCvSharp.Point center = new OpenCvSharp.Point(image_out.Cols / 2, image_out.Rows / 2);
+                                double angle = myOPENCV_runlist[i, 2];
+                                double scale = (double)myOPENCV_runlist[i, 3] / 10;
+                                ///// 通过上面的旋转细节信息求得旋转矩阵
+                                rot_mat = Cv2.GetRotationMatrix2D(center, angle, scale);
+                                ///// 旋转已扭曲图像
+                                Cv2.WarpAffine(image_out, image_out, rot_mat, image_out.Size());
+                            }
+                            else
+                            {
+                                Point2f[] srcTri = new Point2f[3];
+                                Point2f[] dstTri = new Point2f[3];
+                                Mat warp_mat = new Mat(2, 3, MatType.CV_32FC1);
+                                Mat warp_dst;
+                                warp_dst = Mat.Zeros(image_out.Rows, image_out.Cols, image_out.Type());
+                                srcTri[0] = new Point2f(0, 0);
+                                srcTri[1] = new Point2f(image_out.Cols, 0);
+                                srcTri[2] = new Point2f(0, image_out.Rows);
+                                dstTri[0] = new Point2f((float)(image_out.Cols * myOPENCV_runlist[i, 2] / 100), (float)(image_out.Rows * myOPENCV_runlist[i, 2] / 100));
+                                dstTri[1] = new Point2f((float)(image_out.Cols * (1 - (float)myOPENCV_runlist[i, 3] / 100)), (float)(image_out.Rows * myOPENCV_runlist[i, 3] / 100));
+                                dstTri[2] = new Point2f((float)(image_out.Cols * myOPENCV_runlist[i, 4] / 100), (float)(image_out.Rows * (1 - (float)myOPENCV_runlist[i, 4] / 100)));
+                                warp_mat = Cv2.GetAffineTransform(srcTri, dstTri);
+                                Cv2.WarpAffine(image_out, image_out, warp_mat, image_out.Size());
+                            }
+                            break;
+                        }
+                    case myOPENCV.equalizehist:
+                        {
+                            Cv2.EqualizeHist(image_out, image_out);
+                            break;
+                        }
+                    case myOPENCV.facedetection:
+                        {
+                            if (0 == myOPENCV_runlist[i, 1])
+                            {
+                                var haarCascade = new CascadeClassifier(@"haarcascade_frontalface_alt.xml");
+                                Mat haarResult = DetectFace(image_out, haarCascade);
+                                image_out = haarResult;
+                            }
+                            else
+                            {
+                                var lbpCascade = new CascadeClassifier(@"lbpcascade_frontalface.xml");
+                                Mat lbpResult = DetectFace(image_out, lbpCascade);
+                                image_out = lbpResult;
+                            }
+
+
+
+                            break;
+                        }
+
+
+                    default: break;
+
+                }
+            }
+
+
+            return image_out;
+        }
+        private void pictureBox1_Click(object sender, EventArgs e)
+        {
+
+        }/// <summary>
+         /// 
+         /// </summary>
+         /// <param name="cascade"></param>
+         /// <returns></returns>
+        private Mat DetectFace(Mat src, CascadeClassifier cascade)
+        {
+            Mat result;
+            using (var gray = new Mat())
+            {
+                result = src.Clone();
+                Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
+
+                // Detect faces
+                Rect[] faces = cascade.DetectMultiScale(
+                    gray, 1.08, 2, HaarDetectionType.ScaleImage, new OpenCvSharp.Size(30, 30));
+
+                // Render all detected faces
+                foreach (Rect face in faces)
+                {
+                    var center = new OpenCvSharp.Point
+                    {
+                        X = (int)(face.X + face.Width * 0.5),
+                        Y = (int)(face.Y + face.Height * 0.5)
+                    };
+                    var axes = new OpenCvSharp.Size
+                    {
+                        Width = (int)(face.Width * 0.5),
+                        Height = (int)(face.Height * 0.5)
+                    };
+                    Cv2.Ellipse(result, center, axes, 0, 0, 360, new Scalar(255, 0, 255), 4);
+                }
+            }
+            return result;
+        }
+        public enum myOPENCV   //方法排排坐写这里面一一对应一个下标
+        {
+            cvt_color = 0,
+            boxfilter,
+            blur,
+            gaussianblur,
+            medianblur,
+            bilateralfilter,
+            dilate,
+            erode,
+            morphologyex,
+            floodfill,
+            pyrup,
+            pyrdown,
+            resize,
+            threshold,
+            canny,
+            sobel,
+            laplacian,
+            scharr,
+            convertscaleabs,
+            addweighted,
+            houghlines,
+            houghlinep,
+            houghcircles,
+            remap,
+            warpaffine,
+            equalizehist,
+            facedetection,
+            findcontours,
+            drawcontours,
+            convexhull,
+            boundingrect,
+            minarearect,
+            minenclosingcircle,
+            fillellipse,
+            approxpolydp,
+            moments,
+            contourarea,
+            arclength,
+            watershed,
+            inpaint,
+            calchist,
+            minmaxloc,
+            comparehist,
+            calcbackproject,
+            matchtemplate,
+            cornerharris,
+            goodfeaturestotrack,
+            cornersubpix,
+            drawkeypoints,
+            drawmatches,
+            ORB,
+
+
+            number  //用于统计总数
+        };
+    }
+}

+ 60 - 0
OpenCVDemo/Form1.resx

@@ -0,0 +1,60 @@
+<root>
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 13 - 0
OpenCVDemo/OpenCVDemo.csproj

@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
+
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <UseWindowsForms>true</UseWindowsForms>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="OpenCvSharp4" Version="4.4.0.20200915" />
+  </ItemGroup>
+
+</Project>

+ 24 - 0
OpenCVDemo/Program.cs

@@ -0,0 +1,24 @@
+using OpenCvSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace OpenCVDemo
+{
+    static class Program
+    {
+        /// <summary>
+        ///  The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.SetHighDpiMode(HighDpiMode.SystemAware);
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new Form1());
+        }
+    }
+}

+ 78 - 0
OpenCVTest/Globals.cs

@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenCVTest
+{
+    public  class Globals
+    {
+//选项
+public static string  CHOICES = "ABCDE";
+
+        //一行选项+题号列数,例如一行有3题,一题4个选项,所以总共有3*4+3个列
+        public static double CHOICE_COL_COUNT = 18;
+
+        //每题题选项数
+        public static double CHOICES_PER_QUE = 5;
+
+        //每个选项框里面白色点所占比例阈值,小于则说明该选项框可能被填涂
+        public static double WHITE_RATIO_PER_CHOICE = 0.80;
+
+        //受限于环境,光源较差的情况下或腐蚀膨胀参数设置不对,
+        //可能会有误判,这个参数这是比较两个都被识别为涂写的选项框是否有误判的阈值
+        public static double MAYBE_MULTI_CHOICE_THRESHOLD = 0.07;
+
+        //答题卡框与整个图片周长比的阈值
+        public static double CNT_PERIMETER_THRESHOLD = 0.35;
+
+        //答题卡框面积阈值
+        public static double SHEET_AREA_MIN_RATIO = 0.7;
+
+        //识别所涂写区域时的二值化参数
+        public static double[] ANS_IMG_THRESHOLD = new double[] { 88, 255 };
+
+        //识别所涂写区域时的膨胀参数
+        public static double ANS_IMG_DILATE_ITERATIONS = 9;
+
+        //识别所涂写区域时的腐蚀参数
+        public static double ANS_IMG_ERODE_ITERATIONS = 0;
+
+        //识别所涂写区域时的膨胀腐蚀的kernel
+        public static int[,] ANS_IMG_KERNEL =new int[2, 2];
+
+        //识别所有选项框区域时的二值化参数
+        public static double[] CHOICE_IMG_THRESHOLD = new double[] { 115, 255 };
+
+        //识别所有选项框区域时的膨胀参数
+        public static double CHOICE_IMG_DILATE_ITERATIONS = 6;
+
+        //识别所有选项框区域时的腐蚀参数
+        public static double CHOICE_IMG_ERODE_ITERATIONS = 3;
+
+        //识别所有选项框区域时的膨胀腐蚀的kernel
+        public static int [,]  CHOICE_IMG_KERNEL =new int[2,2];
+
+        //选项框面积的阈值,超过则认为这个轮廓不是选项框
+        public static double CHOICE_MAX_AREA = 400;
+
+        //选项框面积的阈值,小于则认为这个轮廓不是选项框
+        public static double CHOICE_MIN_AREA = 100;
+
+        //总共选项框 + 题号的个数,例如一行3题,总共20列,所以有3 * 20 * 4 + 3 * 20
+        public static double CHOICE_CNT_COUNT = 51* 6;
+
+        //调整亮度的竖向分块数目
+        public static double PROCESS_BRIGHT_COLS = 18;
+
+        //调整亮度的横向分块数目
+        public static double PROCESS_BRIGHT_ROWS = 16;
+
+        //调整亮度值
+        public static double BRIGHT_VALUE = 120;
+
+        public static string[] test_ans = new string[] { "A", "AD", "BD", "AC", "B", "BD", "A", "", "AD", "D", "", "", "B", "A", "A", "A", "B", "B", "B", "B", "A",
+            "B", "A", "A", "A", "B", "B", "B", "B", "B", "", "" };
+        public Dictionary<string, int> ORIENT_CODE = new Dictionary<string, int>() { { "col", 1 },{  "row", 0 } };
+        public Dictionary<int, string> score = new Dictionary<int, string>() { { 1, "A" }, { 2, "B" }, { 3, "C" }, { 4, "A" }, { 5, "B" }, { 6, "C" }, { 7, "A" }, { 8, "B" }, { 9, "C" } };
+    }
+}

+ 10 - 0
OpenCVTest/OpenCVTest.csproj

@@ -0,0 +1,10 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="OpenCvSharp4" Version="4.4.0.20200915" />
+  </ItemGroup>
+</Project>

+ 30 - 0
OpenCVTest/Program.cs

@@ -0,0 +1,30 @@
+using OpenCvSharp;
+using System;
+
+namespace OpenCVTest
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            Mat base_img = Cv2.ImRead(@"F:/20191204104138.jpg");
+            get_answer_from_sheet(base_img);
+        }
+        public static void get_answer_from_sheet(Mat base_img)
+        {
+            Cv2.ImShow("src", base_img);
+            Mat gray = new Mat();
+            Cv2.CvtColor(base_img, gray, ColorConversionCodes.BGR2GRAY);
+        }
+        public static void get_init_process_img(Mat roi_img) {
+            Mat h = new Mat();
+            Cv2.Sobel(roi_img, h, MatType.CV_32F, 0, 1, -1);
+            Mat v = new Mat();
+            Cv2.Sobel(roi_img, v, MatType.CV_32F, 1, 0, -1);
+            Mat img = new Mat();
+            Cv2.Add(h, v,img);
+            Cv2.ConvertScaleAbs(img,img);
+            Cv2.GaussianBlur(img, img, new Size { Width = 3, Height = 3 }, 0);
+        }
+    }
+}