使用C#winform和opencvsharp做一个小软件

链接:https://pan.baidu.com/s/1pErTmMNXPNiTdfBSlTY8Sw
提取码:kbbq

2020.05.18更新
我把源码传到百度云了,需要的自取
链接:https://pan.baidu.com/s/1B6XFOKfxxhRf9jNNVhQH9A
提取码:5xzs


2020.04.09更新
这是去年五月份写的一个小软件了,当初就是用的这小程序拿到现在工作的机会,目前工作用的是C++和opencv,现在回来看当初写的东西还是有很多不成熟,大家如果有疑问可以下方留言,关于opencv的能回答就就回答,但是C#已经不用很久了,可能不能解答大家关于C#的疑问。后面看有空的花我写一些opencv的小技巧吧


从去年开始学习的python和opencv开发。
过年回来的时候面试公司内的自动化部门,面试通过且那边主管让我转到C#下开发软件(然而现在的部门处长不同意一直拖,弄到现在都没转调成),也一并学习了opencvsharp的使用。
在查阅资料的时候看到有位兄弟分享了自己写的一个小软件,收到启发决定自己也动手写一个程序,这样也加深对于C#和opencv库的使用和理解。

进入正题:

设计目的:
本次设计一个能够实现OpenCV部分功能的图像处理软件。目的在于方便图像处理人员在具体编写OpenCV程序前,提前能够对图像进行简单处理,进而帮助开发人员分析该如何对图像进行处理,C#中WinForm风格也让我想起大学时候学的C++下MFC的开发。

界面:
在这里插入图片描述
左边listbox是可以进行操作的方法,右侧的listbox是已经进行操作的内容,中间部分显示已进行处理的图像,中下部是操作流程。
在这里插入图片描述
窗体二是用于一些需要传递参数操作,比如模板匹配需要再传递另外一张图片和参数,可以根据再窗体一中选择的操作不同来显示修改或隐藏某些功能。

操作:
点击“打开图片”按钮选择一张图像文件,打开后中间部分就会显示图像内容。
在这里插入图片描述
需要什么操作双击左边listbox对应的选项即可完成对应操作,有些操作提供滑动条和参数的设定,这些都可以自己修改合适的 阈值,如果想重来点击“刷新图像”即可,这个按钮能删除已经进行的操作;
在这里插入图片描述
功能实现:

双击左侧选项触发listbox的double_click事件,通过将写好的listbox中选项的枚举,将选择的内容传递到处理函数中进行判断。

private void listBox1_DoubleClick(object sender, EventArgs e)
        {
            selectIndex = listBox1.SelectedIndex;
            handle(selectIndex);//将选择的序号传到处理函数中
        }
public  enum lb1_list//记录listbox1操作方法
        {
            gray,
            reverse,
            binary,
            gaussianBlur,
            blur,
            medianBlur,
            bilateralFilter,
            sobel,
            scharr,
            canny,
            Laplacian,
            carve,
            rever_lr,
            rever_tb,
            frost,
            sharp,
            dilate,
            erode,
            tophat,
            blackhat,
            gamma,
            log,
            hist,
            findContours,
            template,
            drawRect,
        }

最后再根据枚举对应转换成int类型的数字找到方法

			case (int)lb1_list.binary:
                    Cv2.ImShow("二值化处理", pictureMain);
                    Mat temp0 = new Mat();
                    pictureMain.CopyTo(temp0);
                    CvTrackbarCallback2 ctbc0 = new CvTrackbarCallback2(binary);
                    CvTrackbar cvtb0 = new CvTrackbar("程度", "二值化处理", 0, 10, ctbc0, temp0);
                    display("二值化");
                    break;

最终我们就可以通过不同操作来预先判断我们图像在实际开发中需要进行怎么样的处理了。
下面贴附Form1源码:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void intrudBtn_Load(object sender, EventArgs e)
        {
            
        }
       
        public Mat pictureMain;//当前主窗体图像
        public Mat form2image;//窗体二图像
        public float form2Num1=50f;
        public float form2Num2 = 150f;//接受窗体二传入的参数一参数二
        string imageName;
        private void openBtn_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd1 = new OpenFileDialog();//创建打开文件夹窗体
            ofd1.Title = "请选择输入的图像";
            ofd1.InitialDirectory = @"";//初始化目录
            ofd1.Multiselect = false;//不可多选
            ofd1.Filter = "图像文件|*.jpg;*.png;*.bmp|全部文件|*.*";
            ofd1.ShowDialog();

            if (ofd1.FileName!=string.Empty)
            {
                try
                {
                    pictureShow.Load(ofd1.FileName);
                    imageName = ofd1.FileName;
                    textBox1.AppendText("\n\r打开文件:" + imageName);
                    textBox1.SelectionStart = this.textBox1.TextLength;
                    textBox1.ScrollToCaret();
                    pictureMain = new Mat(ofd1.FileName);
                }
                catch (Exception)
                {
                    MessageBox.Show("打开失败,请检查文件格式是否符合");
                }
                
            }

        }
        
        private void saveBtn_Click(object sender, EventArgs e)
        {
            
            if (pictureShow!=null)
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Title = "保存文件";
                sfd.Filter = "JPGE图像|*.jpg|PNG图像|*.png|BMP图像|*.bmp|所有文件|*.*";
                sfd.InitialDirectory = Environment.CurrentDirectory;
                sfd.ShowDialog();
                if (sfd.FileName != null)
                {
                    try
                    {
                        pictureShow.Image.Save(sfd.FileName);
                        textBox1.AppendText("\r\n图片已保存至:" + sfd.FileName);
                        textBox1.SelectionStart = textBox1.TextLength;
                        textBox1.ScrollToCaret();
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            else
            {
                MessageBox.Show("无可保存图片");
            }

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("本人第一个以C#和opencvsharp写的小程序,很多bug来不及慢慢优化,但也算包含一番心血,主要是将之前学习的内容再复习深化了解,感叹路漫漫其修远兮,昨日之日不可留,最终走回程序员这条路");
        }
        private void reflashBtn_Click(object sender, EventArgs e)
        {
            num = 1;
            listBox2.Items.Clear();
            textBox1.Text = "以下为通知信息:";
            if (imageName != string.Empty)
            {
                try
                {
                    pictureShow.Load(imageName);
                    pictureMain = new Mat(imageName);
                    pictureShow.Image = pictureMain.ToBitmap();
                }
                catch { }
                }

        }
        int num = 1;//记录处理次数
        public  enum lb1_list//记录操作方法
        {
            gray,
            reverse,
            binary,
            gaussianBlur,
            blur,
            medianBlur,
            bilateralFilter,
            sobel,
            scharr,
            canny,
            Laplacian,
            carve,
            rever_lr,
            rever_tb,
            frost,
            sharp,
            dilate,
            erode,
            tophat,
            blackhat,
            gamma,
            log,
            hist,
            findContours,
            template,
            drawRect,
        }
        public int selectIndex;
        /// <summary>
        /// 实现双击启动处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox1_DoubleClick(object sender, EventArgs e)
        {
            selectIndex = listBox1.SelectedIndex;
            handle(selectIndex);
        }
        
        

        /// <summary>
        /// 二值化Tbar处理函数
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="userdata"></param>
        public void binary(int pos, object userdata)
        {

            Mat a = (Mat)userdata;
            Mat b = new Mat();
            a.CopyTo(b);
            Cv2.Threshold(b, b, pos * 25, 255, ThresholdTypes.Binary);
            Cv2.ImShow("二值化处理", b);
            b.CopyTo(pictureMain);
            pictureShow.Image = pictureMain.ToBitmap();
            b.Release();
        }
        
        /// <summary>
        /// 高斯滤波
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="userdata"></param>
        public void gaussianBlur(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);

            Cv2.GaussianBlur(a, a, new OpenCvSharp.Size(pos*2+1, pos*2+1), 5);

            Cv2.ImShow("高斯滤波", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
        }
        /// <summary>
        /// 均值滤波
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="userdata"></param>
        public  void blur(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);

            Cv2.Blur(a, a, new OpenCvSharp.Size(pos+1, pos+1));

            Cv2.ImShow("均值滤波", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
        }

        public void medianBlur(int pos, object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Cv2.MedianBlur(a, a, pos*2+1);
            Cv2.ImShow("中值滤波", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
        }
        public void bilateralFilter(int pos, object userdata)
        {
            
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            Mat b = new Mat();
            src.CopyTo(b);
            Cv2.BilateralFilter(b, a, pos*5 + 1, 100, 100);
            Cv2.ImShow("双边滤波", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
            b.Release();
        }
        public void canny(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Cv2.Canny(a, a, pos * 25, pos * 25);
            Cv2.ImShow("canny边缘检测", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
            Thread.Sleep(50);
        }
        public void laplacian(int pos,object userdata)
        {
            Mat src=(Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Cv2.Laplacian(a, a, -1, pos*2 + 1);
            Cv2.ImShow("Laplacian边缘检测", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
        }
        public void dilate(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Mat structureElement = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(pos * 2 + 1, pos * 2 + 1));
            Cv2.Dilate(a, a, structureElement);
            Cv2.ImShow("膨胀处理", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
        }
        public void erode(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Mat structureElement = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(pos * 2 + 1, pos * 2 + 1));
            Cv2.Erode(a, a, structureElement);
            Cv2.ImShow("腐蚀处理", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = a.ToBitmap();
            a.Release();
        }
        public void tophat(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Mat stuctureElement = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(pos+1, pos+1), new OpenCvSharp.Point(-1, -1));
            Cv2.MorphologyEx(a, a, MorphTypes.TopHat, stuctureElement);
            Cv2.ImShow("顶帽处理", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = pictureMain.ToBitmap();
            a.Release();
        }
        public void blackhat(int pos, object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            src.CopyTo(a);
            Mat stuctureElement = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(pos + 1, pos + 1), new OpenCvSharp.Point(-1, -1));
            Cv2.MorphologyEx(a, a, MorphTypes.BlackHat, stuctureElement);
            Cv2.ImShow("黑帽处理", a);
            a.CopyTo(pictureMain);
            pictureShow.Image = pictureMain.ToBitmap();
            a.Release();
        }
        public void drawRect(int pos,object userdata)
        {
            Mat src = (Mat)userdata;
            Mat a = new Mat();
            Mat gray = new Mat();
            src.CopyTo(gray);
            if (gray.Channels()==3)
            {
                Cv2.CvtColor(gray, gray, ColorConversionCodes.BGR2GRAY);
            }
            gray.CopyTo(a);
            Cv2.Threshold(~a, a ,pos *25, 255, ThresholdTypes.Binary);
            //Cv2.Canny(a, a, pos*10, 255);
            HierarchyIndex[] hierarchy;
            OpenCvSharp.Point[][] coutours;
            Cv2.FindContours(a, out coutours,out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
            OpenCvSharp.Point[][] contours_ploy = new OpenCvSharp.Point[coutours.Length][];
            RotatedRect[] RotatedRect_ploy = new RotatedRect[coutours.Length];
            Rect[] rect_poly = new Rect[coutours.Length];
            for (int i = 0; i < coutours.Length; i++)
            {
                contours_ploy[i] = Cv2.ApproxPolyDP(coutours[i], 10, true);//计算凸包
                rect_poly[i] = Cv2.BoundingRect(coutours[i]);//最小外接矩形,我们不用,
                if (contours_ploy[i].Length>5)//拟合的线条数不少于5
                {
                    RotatedRect temp1 = Cv2.MinAreaRect(contours_ploy[i]);//最小外接矩形,能旋转
                    RotatedRect_ploy[i] = temp1;//将该矩形放入集合中
                }
            }
            Point2f[] pot = new Point2f[4];
            for (int i = 0; i < RotatedRect_ploy.Length; i++)
            {
                pot = RotatedRect_ploy[i].Points();
                double line1 = Math.Sqrt((pot[1].Y - pot[0].Y) * (pot[1].Y - pot[0].Y)+ (pot[1].X - pot[0].X) * (pot[1].X - pot[0].X));
                double line2=Math.Sqrt((pot[3].Y - pot[0].Y) * (pot[3].Y - pot[0].Y) + (pot[3].X - pot[0].X) * (pot[3].X - pot[0].X));
                if (line1*line2<9000)//太小直接pass
                {
                    continue;
                }

                for (int j = 0; j < 4; j++)
                {
                    Cv2.Line(pictureMain, (OpenCvSharp.Point)pot[j], (OpenCvSharp.Point)pot[(j + 1) % 4], Scalar.Green,3);
                }
            }
            Cv2.ImShow("最小外包矩形", a);
            pictureShow.Image = pictureMain.ToBitmap();
            a.Release();
        }
        public void handle(int selectIndex)
        {

            switch (selectIndex)
            {
                case (int)lb1_list.gray:
                    if (pictureMain.Channels() == 3)
                    {
                        Cv2.CvtColor(pictureMain, pictureMain, ColorConversionCodes.BGR2GRAY);
                        pictureShow.Image = pictureMain.ToBitmap();
                        display("灰度化");
                    }
                    else
                    {
                        MessageBox.Show("已是灰度图像,不要重复操作");
                    }
                    break;
                case (int)lb1_list.reverse:
                    pictureMain = ~pictureMain;
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("反色");
                    break;
                case (int)lb1_list.binary:
                    Cv2.ImShow("二值化处理", pictureMain);
                    Mat temp0 = new Mat();
                    pictureMain.CopyTo(temp0);
                    CvTrackbarCallback2 ctbc0 = new CvTrackbarCallback2(binary);
                    CvTrackbar cvtb0 = new CvTrackbar("程度", "二值化处理", 0, 10, ctbc0, temp0);
                    display("二值化");
                    break;

                case (int)lb1_list.gaussianBlur:
                    Cv2.ImShow("高斯滤波", pictureMain);
                    Mat temp1 = new Mat();
                    pictureMain.CopyTo(temp1);

                    CvTrackbarCallback2 ctbc1 = new CvTrackbarCallback2(gaussianBlur);
                    CvTrackbar cvtb1 = new CvTrackbar("程度", "高斯滤波", 0, 10, ctbc1, temp1);

                    display("高斯滤波");
                    break;
                case (int)lb1_list.blur:
                    Cv2.ImShow("均值滤波", pictureMain);
                    Mat temp2 = new Mat();
                    pictureMain.CopyTo(temp2);

                    CvTrackbarCallback2 ctbc2 = new CvTrackbarCallback2(blur);
                    CvTrackbar cvtb2 = new CvTrackbar("程度", "均值滤波", 0, 10, ctbc2, temp2);

                    display("均值滤波");
                    break;
                case (int)lb1_list.medianBlur:
                    Cv2.ImShow("中值滤波", pictureMain);
                    Mat temp3 = new Mat();
                    pictureMain.CopyTo(temp3);

                    CvTrackbarCallback2 ctbc3 = new CvTrackbarCallback2(medianBlur);
                    CvTrackbar cvtb3 = new CvTrackbar("程度", "中值滤波", 0, 10, ctbc3, temp3);

                    display("中值滤波");
                    break;
                case (int)lb1_list.bilateralFilter:
                    Cv2.ImShow("双边滤波", pictureMain);
                    Mat temp4 = new Mat();
                    pictureMain.CopyTo(temp4);

                    CvTrackbarCallback2 crbc4 = new CvTrackbarCallback2(bilateralFilter);
                    CvTrackbar cvtb4 = new CvTrackbar("程度", "双边滤波", 0, 10, crbc4, temp4);

                    display("双边滤波");
                    break;
                case (int)lb1_list.sobel://-1 -2  -1
                    Mat sobelx = new Mat();
                    Mat sobely = new Mat();
                    Cv2.Sobel(pictureMain, sobelx, -1, 1, 0);
                    Cv2.Sobel(pictureMain, sobely, -1, 0, 1);
                    Cv2.AddWeighted(sobelx, 0.5, sobely, 0.5, 0, pictureMain);//gamma为加到结果上的值
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("sobel边缘检测");
                    break;
                case (int)lb1_list.scharr://-3   -10  -3
                    Mat scharrx = new Mat();
                    Mat scharry = new Mat();
                    Cv2.Scharr(pictureMain, scharrx, -1, 1, 0);
                    Cv2.Scharr(pictureMain, scharry, -1, 0, 1);
                    Cv2.AddWeighted(scharrx, 0.5, scharry, 0.5, 0, pictureMain);
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("scharr边缘检测");
                    break;
                case (int)lb1_list.canny:
                    Cv2.ImShow("canny边缘检测", pictureMain);
                    Mat temp_canny = new Mat();
                    pictureMain.CopyTo(temp_canny);
                    if (temp_canny.Channels() == 3)
                    {
                        Cv2.CvtColor(temp_canny, temp_canny, ColorConversionCodes.BGR2GRAY);
                    }
                    CvTrackbarCallback2 ctbc_canny = new CvTrackbarCallback2(canny);
                    CvTrackbar cvtb_canny = new CvTrackbar("程度", "canny边缘检测", 0, 10, ctbc_canny, temp_canny);
                    display("canny边缘检测");
                    break;
                case (int)lb1_list.Laplacian:
                    Cv2.ImShow("Laplacian边缘检测", pictureMain);
                    Mat temp_Laplacian = new Mat();
                    pictureMain.CopyTo(temp_Laplacian);
                    CvTrackbarCallback2 ctbc_Laplacian = new CvTrackbarCallback2(laplacian);
                    CvTrackbar cvrb_laplacian = new CvTrackbar("程度", "Laplacian边缘检测", 0, 10, ctbc_Laplacian, temp_Laplacian);
                    display("laplacian边缘检测");
                    break;
                case (int)lb1_list.carve:
                    if (pictureMain.Channels() != 1)
                    {
                        Cv2.CvtColor(pictureMain, pictureMain, ColorConversionCodes.BGR2GRAY);
                    }

                    for (int i = 0; i < pictureMain.Rows; i++)
                    {
                        for (int j = 0; j < pictureMain.Cols; j++)
                        {
                            int newP = 2 * pictureMain.Get<byte>(i, j) - pictureMain.Get<byte>(i, j + 1) - pictureMain.Get<byte>(i + 1, j) + 100;

                            if (newP > 255)
                            {
                                newP = 255;
                            }
                            else if (newP < 0)
                            {
                                newP = 0;
                            }
                            pictureMain.Set(i, j, (byte)newP);
                        }
                    }
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("浮雕");
                    break;
                case (int)lb1_list.rever_lr:
                    Mat imx_lr = new Mat(pictureMain.Size(), MatType.CV_32FC1);
                    Mat imy_lr = new Mat(pictureMain.Size(), MatType.CV_32FC1);
                    for (int i = 0; i < pictureMain.Rows; i++)
                    {
                        for (int j = 0; j < pictureMain.Cols; j++)
                        {
                            imx_lr.Set(i, j, (float)(pictureMain.Cols - j - 1));
                            imy_lr.Set(i, j, (float)i);
                        }
                    }
                    Cv2.Remap(pictureMain, pictureMain, imx_lr, imy_lr);
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("左右反转");
                    break;
                case (int)lb1_list.rever_tb:
                    Mat imx_tb = new Mat(pictureMain.Size(), MatType.CV_32FC1);
                    Mat imy_tb = new Mat(pictureMain.Size(), MatType.CV_32FC1);
                    for (int i = 0; i < pictureMain.Rows; i++)
                    {
                        for (int j = 0; j < pictureMain.Cols; j++)
                        {
                            imx_tb.Set(i, j, (float)j);
                            imy_tb.Set(i, j, (float)(pictureMain.Rows - i - 1));
                        }
                    }
                    Cv2.Remap(pictureMain, pictureMain, imx_tb, imy_tb);
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("上下反转");
                    break;
                case (int)lb1_list.frost:
                    Mat imx_frost = new Mat(pictureMain.Size(), MatType.CV_32FC1);
                    Mat imy_frost = new Mat(pictureMain.Size(), MatType.CV_32FC1);
                    Random rm = new Random();
                    for (int i = 0; i < pictureMain.Rows; i++)
                    {
                        for (int j = 0; j < pictureMain.Cols; j++)
                        {
                            imx_frost.Set(i, j, (float)(j + rm.Next(-5, 5)));
                            imy_frost.Set(i, j, (float)(i + rm.Next(-5, 5)));
                        }
                    }
                    Cv2.Remap(pictureMain, pictureMain, imx_frost, imy_frost);
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("毛玻璃");
                    break;
                case (int)lb1_list.sharp:
                    Mat mask = new Mat(new OpenCvSharp.Size(3, 3), MatType.CV_32FC1);
                    mask.Set<float>(0, 1, -1); mask.Set<float>(1, 0, -1); mask.Set<float>(1, 1, 5); mask.Set<float>(1, 2, -1); mask.Set<float>(2, 1, -1);
                    Mat temp_sharp = new Mat();
                    pictureMain.CopyTo(temp_sharp);
                    Cv2.Filter2D(pictureMain, temp_sharp, -1, mask);
                    Cv2.WaitKey(500);
                    temp_sharp.CopyTo(pictureMain);
                    pictureShow.Image = temp_sharp.ToBitmap();
                    display("锐化");
                    mask.Release();
                    temp_sharp.Release();
                    break;
                case (int)lb1_list.dilate:
                    Cv2.ImShow("膨胀处理", pictureMain);
                    Mat temp_dilate = new Mat();
                    pictureMain.CopyTo(temp_dilate);
                    CvTrackbarCallback2 ctbc_dilate = new CvTrackbarCallback2(dilate);
                    CvTrackbar cvtb_dilate = new CvTrackbar("程度", "膨胀处理", 0, 10, ctbc_dilate, temp_dilate);
                    display("膨胀");
                    break;
                case (int)lb1_list.erode:
                    Cv2.ImShow("腐蚀处理", pictureMain);
                    Mat temp_erode = new Mat();
                    pictureMain.CopyTo(temp_erode);
                    CvTrackbarCallback2 ctbc_erode = new CvTrackbarCallback2(erode);
                    CvTrackbar cvtb_erode = new CvTrackbar("程度", "腐蚀处理", 0, 10, ctbc_erode, temp_erode);
                    display("腐蚀");
                    break;
                case (int)lb1_list.gamma:
                    if (pictureMain.Channels() == 1)
                    {
                        Mat temp_gray = new Mat(pictureMain.Size(), MatType.CV_16UC1);
                        for (int i = 0; i < pictureMain.Rows; i++)
                        {
                            for (int j = 0; j < pictureMain.Cols; j++)
                            {
                                temp_gray.Set(i, j, Math.Abs(pictureMain.Get<byte>(i, j) * pictureMain.Get<byte>(i, j)));//因为pictureMain为8UC1,所以这里一定要使用<byte>,不能使用其他类型
                            }
                        }
                        Cv2.Normalize(temp_gray, temp_gray, 0, 255, NormTypes.MinMax);
                        Cv2.ConvertScaleAbs(temp_gray, temp_gray);
                        temp_gray.CopyTo(pictureMain);
                        pictureShow.Image = pictureMain.ToBitmap();
                        temp_gray.Release();
                    }
                    else
                    {
                        Mat temp_gamma = new Mat(pictureMain.Size(), MatType.CV_32FC3);
                        Vec3f channels = new Vec3f();
                        for (int i = 0; i < pictureMain.Rows; i++)
                        {
                            for (int j = 0; j < pictureMain.Cols; j++)
                            {
                                channels.Item0 = Math.Abs(pictureMain.Get<Vec3b>(i, j).Item0 * pictureMain.Get<Vec3b>(i, j).Item0);
                                channels.Item1 = Math.Abs(pictureMain.Get<Vec3b>(i, j).Item1 * pictureMain.Get<Vec3b>(i, j).Item1);
                                channels.Item2 = Math.Abs(pictureMain.Get<Vec3b>(i, j).Item2 * pictureMain.Get<Vec3b>(i, j).Item2);
                                temp_gamma.Set(i, j, channels);
                            }
                        }
                        Cv2.Normalize(temp_gamma, temp_gamma, 0, 255, NormTypes.MinMax);
                        Cv2.ConvertScaleAbs(temp_gamma, temp_gamma);
                        temp_gamma.CopyTo(pictureMain);
                        pictureShow.Image = pictureMain.ToBitmap();
                        temp_gamma.Release();
                    }
                    display("gamma调整");
                    break;
                case (int)lb1_list.log:
                    Mat[] temp_log = pictureMain.Split();
                    for (int i = 0; i < pictureMain.Rows; i++)
                    {
                        for (int j = 0; j < pictureMain.Cols; j++)
                        {
                            temp_log[0].Set(i, j, Math.Log(temp_log[0].Get<float>(i, j), 1.2));
                            temp_log[1].Set(i, j, Math.Log(temp_log[1].Get<float>(i, j), 1.2));
                            temp_log[2].Set(i, j, Math.Log(temp_log[2].Get<float>(i, j), 1.2));
                        }
                    }
                    Cv2.Merge(temp_log, pictureMain);
                    Cv2.Normalize(pictureMain, pictureMain, 0, 255, NormTypes.MinMax);
                    pictureShow.Image = pictureMain.ToBitmap();

                    //Mat temp_log = new Mat(pictureMain.Size(), MatType.CV_8UC3);
                    //pictureMain.CopyTo(temp_log);
                    //if (pictureMain.Channels()==3)
                    //{
                    //    Vec3i channels = new Vec3i();
                    //    for (int i = 0; i < pictureMain.Rows; i++)
                    //    {
                    //        for (int j = 0; j < pictureMain.Cols; j++)
                    //        {
                    //            //float a = pictureMain.Get<Vec3b>(i, j).Item0;
                    //            //float b = pictureMain.Get<Vec3b>(i, j).Item1;
                    //            //float c = pictureMain.Get<Vec3b>(i, j).Item2;
                    //            channels.Item0 = (int)Math.Log(pictureMain.Get<Vec3b>(i, j).Item0,1.2);
                    //            channels.Item1 = (int)Math.Log(pictureMain.Get<Vec3b>(i, j).Item1,1.2);
                    //            channels.Item2 = (int)Math.Log(pictureMain.Get<Vec3b>(i, j).Item2,1.2);
                    //            temp_log.Set<Vec3i>(i, j, channels);
                    //        }
                    //    }//这个操作有毒,不能归一化,还把GR通道置0,放弃
                    //temp_log.Normalize(255,0, NormTypes.MinMax);
                    //float e1 = temp_log.Get<Vec3b>(0,0).Item0;
                    //float f = temp_log.Get<Vec3b>(0,0).Item1;
                    //float g = temp_log.Get<Vec3b>(0, 0).Item2;
                    //Cv2.Normalize(temp_log, temp_log, 0, 255, NormTypes.MinMax);
                    //Cv2.ConvertScaleAbs(temp_log, temp_log);
                    //temp_log.CopyTo(pictureMain);
                    //pictureShow.Image = pictureMain.ToBitmap();
                    //temp_log.Release();

                    display("log亮部增强");
                    break;
                case (int)lb1_list.tophat:
                    Mat temp_tophat = new Mat();
                    pictureMain.CopyTo(temp_tophat);
                    Cv2.ImShow("顶帽处理", pictureMain);
                    CvTrackbarCallback2 ctbc_topat = new CvTrackbarCallback2(tophat);
                    CvTrackbar cvtb_tophat = new CvTrackbar("程度", "顶帽处理", 0, 20, ctbc_topat, temp_tophat);
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("顶帽");
                    break;
                case (int)lb1_list.blackhat:
                    Mat temp_blackhat = new Mat();
                    pictureMain.CopyTo(temp_blackhat);
                    Cv2.ImShow("黑帽处理", pictureMain);
                    CvTrackbarCallback2 ctbc_blackhat = new CvTrackbarCallback2(blackhat);
                    CvTrackbar cvtb_blackhat = new CvTrackbar("程度", "黑帽处理", 0, 20, ctbc_blackhat, temp_blackhat);
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("黑帽");
                    break;
                case (int)lb1_list.hist:
                    if (pictureMain.Channels() == 1)
                    {
                        Mat[] image = { pictureMain };
                        Mat temp_hist = pictureMain;
                        int[] channels = new int[] { 0 };
                        int[] histsize = new int[] { 256 };
                        Mat mask_hist = new Mat();
                        Mat hist = new Mat();
                        Rangef[] range = new Rangef[1];
                        range[0].Start = 0f;
                        range[0].End = 256f;
                        Cv2.CalcHist(image, channels, mask_hist, hist, 1, histsize, range);
                        Mat histImage = new Mat(256, 256, MatType.CV_8UC3);
                        double minValue, maxValue;
                        Cv2.MinMaxLoc(hist, out minValue, out maxValue);
                        for (int i = 0; i < 256; i++)
                        {
                            int len = (int)(hist.Get<float>(i) / maxValue * 256);
                            Cv2.Line(histImage, i, histImage.Rows, i, histImage.Rows - len, Scalar.White, 2);
                        }
                        Cv2.ImShow("灰度图像直方图", histImage);
                    }
                    else
                    {
                        Mat[] images = pictureMain.Split();
                        Mat[] bImage = { images[0] };
                        Mat[] gImage = { images[1] };
                        Mat[] rImage = { images[2] };

                        Mat mask_hist = new Mat();
                        Mat[] hists = { new Mat(), new Mat(), new Mat() };
                        int[] channels = { 0 };
                        int[] histSize = { 256 };
                        Rangef[] range = new Rangef[1];
                        range[0].Start = 0f;
                        range[0].End = 256f;
                        Cv2.CalcHist(bImage, channels, mask_hist, hists[0], 1, histSize, range);//dim为需要统计直方图通道的个数
                        Cv2.CalcHist(gImage, channels, mask_hist, hists[1], 1, histSize, range);
                        Cv2.CalcHist(rImage, channels, mask_hist, hists[2], 1, histSize, range);

                        Mat[] histImage = { new Mat(256, 256, MatType.CV_8UC3), new Mat(256, 256, MatType.CV_8UC3), new Mat(256, 256, MatType.CV_8UC3) };
                        Scalar[] color = { Scalar.Blue, Scalar.Green, Scalar.Red };
                        for (int i = 0; i < 3; i++)
                        {
                            double minVal = 0f;
                            double maxVal = 0f;
                            Cv2.MinMaxLoc(hists[i], out minVal, out maxVal);
                            for (int j = 0; j < 256; j++)
                            {
                                int len = (int)(hists[i].Get<float>(j) / maxVal * 256);
                                Cv2.Line(histImage[i], j, histImage[0].Rows, j, histImage[0].Rows - len, color[i], 2);
                            }
                        }
                        Cv2.ImShow("b", histImage[0]);
                        Cv2.ImShow("g", histImage[1]);
                        Cv2.ImShow("r", histImage[2]);
                    }
                    display("直方图显示");
                    break;
                case (int)lb1_list.findContours:
                    MessageBox.Show("假如卡死了,是计算量太大的缘故,请重新调整canny参数一参数二,默认参数一50,参数二150");
                    Mat temp_find = new Mat();
                    if (pictureMain.Channels() == 3)
                    {
                        Cv2.CvtColor(pictureMain, temp_find, ColorConversionCodes.BGR2GRAY);
                    }


                    Cv2.Canny(temp_find, temp_find, form2Num1, form2Num2);

                    HierarchyIndex[] hierarchy;
                    OpenCvSharp.Point[][] coutours;
                    Cv2.FindContours(temp_find, out coutours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone);
                    for (int i = 0; i < coutours.Length; i++)
                    {
                        Cv2.DrawContours(pictureMain, coutours, i, Scalar.RandomColor(), 1);
                    }
                    pictureShow.Image = pictureMain.ToBitmap();
                    display("绘制轮廓");
                    break;
                case (int)lb1_list.template:
                    if (form2image != null && pictureMain.Rows > form2image.Rows && pictureMain.Cols > form2image.Cols)
                    {
                        Mat result = new Mat(pictureMain.Cols - form2image.Cols, pictureMain.Rows - form2image.Cols, MatType.CV_32FC1);
                        Cv2.MatchTemplate(pictureMain, form2image, result, TemplateMatchModes.CCoeff);
                        double maxVal, minVal;
                        OpenCvSharp.Point minLoc, maxLoc;
                        Cv2.Normalize(result, result, 0, 1, NormTypes.MinMax);
                        Cv2.MinMaxLoc(result, out minVal, out maxVal, out minLoc, out maxLoc);
                        Cv2.ImShow("匹配的图像", form2image);
                        pictureMain.Rectangle(maxLoc, new OpenCvSharp.Point(maxLoc.X + form2image.Cols, maxLoc.Y + form2image.Rows), Scalar.Red);
                        pictureShow.Image = pictureMain.ToBitmap();
                        textBox1.AppendText("\r\n模板匹配程度为:" + minVal * 100 + " % ");
                    }
                    else if (form2image == null)
                    {
                        MessageBox.Show("请在窗口二中传入匹配图像");
                    }
                    else
                    {
                        MessageBox.Show("匹配图像需要比原始图像小");
                    }
                    display("模板匹配");
                    break;
                case (int)lb1_list.drawRect:
                    Cv2.ImShow("最小外包矩形", pictureMain);
                    Mat tempRect = new Mat();
                    pictureMain.CopyTo(tempRect);
                    CvTrackbarCallback2 crbc_rect = new CvTrackbarCallback2(drawRect);
                    CvTrackbar cvtb_rect = new CvTrackbar("程度", "最小外包矩形", 0, 20, crbc_rect, tempRect);
                    MessageBox.Show("这个处理内存占用巨大,不要拖动太多次");
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 图像处理后更新信息
        /// </summary>
        /// <param name="name"></param>
        public void display(string name)
        {
            textBox1.AppendText("\r\n图像运行"+ name+ "处理成功");
            textBox1.SelectionStart = this.textBox1.TextLength;
            textBox1.ScrollToCaret();
            listBox2.Items.Add(num + ". "+ name);
            num++;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            form2.Show(this);
        }

        private void initalBtn_Click(object sender, EventArgs e)
        {
            pictureMain = null;
            pictureShow.Image = null;
            num = 1;
            listBox2.Items.Clear();
            textBox1.Text = "以下为通知信息:";
        }
    }```

参考地址:https://blog.csdn.net/you_big_father/article/details/86088531

  • 15
    点赞
  • 127
    收藏
    觉得还不错? 一键收藏
  • 43
    评论
要在 WinForms 中配置 OpenCvSharp,您可以按照以下步骤进行操作: 1. 首先,确保已经安装了 OpenCvSharp 库。您可以在 NuGet 包管理器中搜索并安装 "OpenCvSharp4"。 2. 在您的 WinForms 项目中,右键单击项目名称,然后选择 "管理 NuGet 包"。在 NuGet 包管理器中搜索并安装 "OpenCvSharp4"。 3. 确保您的项目引用了正确的命名空间。在您的代码文件的顶部添加以下引用语句: ```csharp using OpenCvSharp; ``` 4. 在您的 WinForms 窗体上添加一个 PictureBox 控件,用于显示图像。 5. 创建一个按钮或其他触发事件的控件,以加载和处理图像。 6. 在按钮的点击事件处理程序中,添加以下代码来加载和显示图像: ```csharp private void LoadAndDisplayImage() { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Image Files (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp"; if (openFileDialog.ShowDialog() == DialogResult.OK) { Mat image = new Mat(openFileDialog.FileName); pictureBox.Image = image.ToBitmap(); } } ``` 上述代码会打开一个文件对话框,允许用户选择图像文件。选择的图像会加载到一个 `Mat` 对象中,并将其转换为 `Bitmap` 格式以便在 PictureBox 控件中显示。 请注意,您可能还需要根据您的具体需求添加其他 OpenCvSharp 的图像处理代码。上述代码仅提供了一个简单的示例,用于加载和显示图像。 希望这可以帮助您在 WinForms 中配置 OpenCvSharp!如有任何问题,请随时提问。
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值