10. OpenCvSharp摄像头的获取和使用——c#OpenCvSharp学习笔记

10. OpenCvSharp摄像头的获取和使用

在这里插入图片描述

项目概述

项目实现了基于OpenCvSharp和其它组件实现了摄像头或相机的读取,并在列表中显示出来并可以截图保存,还可以在画面中心绘制十字准星、ROI区域,还可对画面进行左右和上下的翻转,并且十字准星、ROI区域、左右翻转和上下翻转等功能支持关闭保存功能,便于下次调用。

源代码在本文底部

0基础原理

所实现程序的流程图如下:
在这里插入图片描述

1基础步骤和界面设计

1.1引用using OpenCvSharp;using OpenCvSharp.Extensions;
1.2将Picturebox、Label、Button、checkbox等控件进行布局、改名、调整形状和字体,形成如下界面:
在这里插入图片描述

2功能实现

2.1初始化变量

 private static VideoCapture my_VideoCapture;//摄像头设备
        private static bool Vopen_flag; //视频打开关闭状态
        Thread Video_thread; //视频播放线程
        private int VideoCapture_id = 0;//摄像头设备号,默认0,可根据下拉框调整
        private bool Collimator_flag ;//十字准星标识符
        private bool ROI_flag ;//ROI区域标识符
        private bool FlipX_flag;//左右翻转标识符
        private bool FlipY_flag;//上下翻转标识符

2.2摄像头(相机)设备列表的读取
2.2.1摄像头(相机)设备列表扫描函数
在这里插入图片描述

 private void Camera_devices_load()
        {
    
    
            //  comboBox1.Items.Add(SerialPort_Name[i]);

            comboBox1.Items.Clear();//清楚列表
            foreach (var i in EnumDevices.Devices)
            {
    
    
                //打印设备名称
                comboBox1.Items.Add(i);
            }
            if (comboBox1.Items.Count == 0)
            {
    
    
                MessageBox.Show("没有搜索到摄像头,请检查连线是否有问题" );
            }
            else 
            {
    
    
                comboBox1.SelectedIndex = 0;//默认移动第一个
            }
            
        
        }

2.2.2 枚举视频设备类

 public class EnumDevices
        {
    
    
            /// <summary>
            /// 枚举视频设备
            /// </summary>
            public static IEnumerable<string> Devices
            {
    
    
                get
                {
    
    
                    IMoniker[] monikers = new IMoniker[5];
                    var devEnum = Activator.CreateInstance(Type.GetTypeFromCLSID(SystemDeviceEnum)) as ICreateDevEnum;
                    IEnumMoniker moniker;
                    if (devEnum.CreateClassEnumerator(VideoInputDevice, out moniker, 0) == 0)
                    {
    
    
                        while (true)
                        {
    
    
                            int hr = moniker.Next(1, monikers, IntPtr.Zero);
                            if (hr != 0 || monikers[0] == null)
                                break;
                            yield return GetName(monikers[0]);
                            foreach (var i in monikers)
                            {
    
    
                                if (i != null)
                                    Marshal.ReleaseComObject(i);
                            }
                        }
                        Marshal.ReleaseComObject(moniker);
                    }
                    Marshal.ReleaseComObject(devEnum);
                }
            }
            /// <summary>
            /// 获取设备名称
            /// </summary>
            /// <param name="moniker"></param>
            /// <returns></returns>
            static string GetName(IMoniker moniker)
            {
    
    
                IPropertyBag property;
                object value;
                object temp = null;
                try
                {
    
    
                    Guid guid = typeof(IPropertyBag).GUID;
                    moniker.BindToStorage(null, null, ref guid, out temp);
                    property = temp as IPropertyBag;
                    int hr = property.Read("FriendlyName", out value, null);
                    Marshal.ThrowExceptionForHR(hr);
                    return value as string;
                }
                catch (Exception)
                {
    
    
                    return null;
                }
                finally
                {
    
    
                    if (temp != null)
                    {
    
    
                        Marshal.ReleaseComObject(temp);
                    }
                }
            }
            static readonly Guid SystemDeviceEnum = new Guid(0x62BE5D10, 0x60EB, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86);
            static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86);
            [Flags]
            enum CDef
            {
    
    
                None = 0x0,
                ClassDefault = 0x1,
                BypassClassManager = 0x2,
                ClassLegacy = 0x4,
                MeritAboveDoNotUse = 0x8,
                DevmonCMGRDevice = 0x10,
                DevmonDMO = 0x20,
                DevmonPNPDevice = 0x40,
                DevmonFilter = 0x80,
                DevmonSelectiveMask = 0xF0
            }
            [ComImport]
            [SuppressUnmanagedCodeSecurity]
            [Guid("3127CA40-446E-11CE-8135-00AA004BB851")]
            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            interface IErrorLog
            {
    
    
                [PreserveSig]
                int AddError([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In] System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo);
            }
            [ComImport]
            [Localizable(false)]
            [SuppressUnmanagedCodeSecurity]
            [Guid("55272A00-42CB-11CE-8135-00AA004BB851")]
            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            interface IPropertyBag
            {
    
    
                [PreserveSig]
                int Read([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [MarshalAs(UnmanagedType.Struct)] out object pVar, [In] IErrorLog pErrorLog);

                [PreserveSig]
                int Write([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In][MarshalAs(UnmanagedType.Struct)] ref object pVar);
            }

            [ComImport]
            [SuppressUnmanagedCodeSecurity]
            [Guid("29840822-5B84-11D0-BD3B-00A0C911CE86")]
            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            interface ICreateDevEnum
            {
    
    
                [PreserveSig]
                int CreateClassEnumerator([In][MarshalAs(UnmanagedType.LPStruct)] Guid pType, out IEnumMoniker ppEnumMoniker, [In] CDef dwFlags);
            }
        }

2.2.3 刷新设备
在这里插入图片描述

 private void button2_Click(object sender, EventArgs e)
        {
    
    
            Camera_devices_load();

        }
       

2.3 摄像头打开
在这里插入图片描述

if (!Vopen_flag)
{

            try
            {
            my_VideoCapture = new VideoCapture(VideoCapture_id);
               

                /*     my_VideoCapture.Set(VideoCaptureProperties.FrameWidth, 1920);//宽度
                     my_VideoCapture.Set(VideoCaptureProperties.FrameHeight, 1080);//高度
                     my_VideoCapture.Set(VideoCaptureProperties.Fps,60);//高度  */


                /*     my_VideoCapture.Set(VideoCaptureProperties.FrameWidth, 640);//宽度
             my_VideoCapture.Set(VideoCaptureProperties.FrameHeight, 360);//高度
             my_VideoCapture.Set(VideoCaptureProperties.Fps,260);//高度  */

            }
            catch (Exception ex)
            {
                MessageBox.Show("OpenCV方式打开摄像头异常:" + ex.ToString());
                return;
            }
            if (my_VideoCapture.IsOpened())
            {
                Vopen_flag = true;
                Video_thread = new Thread(Play_Video);
                Video_thread.Start();
                pictureBox1.Image = null;
                button1.Text = "关闭摄像头";
            }
        }
        else
        {
            Vopen_flag = false;
            Video_thread.Abort();
            my_VideoCapture.Release();
            button1.Text = "打开摄像头";
        }

开启一个新线程

扫描二维码关注公众号,回复: 15203587 查看本文章
private void Play_Video()
        {
    
    
            while (Vopen_flag)
            {
    
    
             
                Mat v_mat = new Mat();
                          my_VideoCapture.Read(v_mat);
      
                          int sleepTime = (int)Math.Round(1000 / my_VideoCapture.Fps);
              
                Cv2.WaitKey(sleepTime);
                          if (v_mat.Empty())
                           {
    
    
                            break;
                            }

                if (FlipY_flag) Cv2.Flip(v_mat, v_mat, OpenCvSharp.FlipMode.X); //上下翻转
                if (FlipX_flag) Cv2.Flip(v_mat, v_mat, OpenCvSharp.FlipMode.Y); //左右翻转
                if (Collimator_flag)  //画准星
                {
    
    
                    Cv2.Line(v_mat, new OpenCvSharp.Point(v_mat.Cols / 2, v_mat.Rows / 2 + 35), new OpenCvSharp.Point(v_mat.Cols / 2, v_mat.Rows / 2 + 15), new Scalar(0, 0, 255), 2, LineTypes.Link8);
                    Cv2.Line(v_mat, new OpenCvSharp.Point(v_mat.Cols / 2, v_mat.Rows / 2 - 35), new OpenCvSharp.Point(v_mat.Cols / 2, v_mat.Rows / 2 - 15), new Scalar(0, 0, 255), 2, LineTypes.Link8);
                    Cv2.Line(v_mat, new OpenCvSharp.Point(v_mat.Cols / 2 + 35, v_mat.Rows / 2), new OpenCvSharp.Point(v_mat.Cols / 2 + 15, v_mat.Rows / 2), new Scalar(0, 0, 255), 2, LineTypes.Link8);
                    Cv2.Line(v_mat, new OpenCvSharp.Point(v_mat.Cols / 2 - 35, v_mat.Rows / 2), new OpenCvSharp.Point(v_mat.Cols / 2 - 15, v_mat.Rows / 2), new Scalar(0, 0, 255), 2, LineTypes.Link8);
                }

                if (ROI_flag)  //画ROI
                {
    
    
                    int V_width = v_mat.Width;
                    int V_height = v_mat.Height;
                    int start_x = v_mat.Width / 4;
                    int start_y = v_mat.Height / 4;
                    OpenCvSharp.Point strat_point = new OpenCvSharp.Point(v_mat.Width / 2, v_mat.Height / 2);
                    Rect ROI_rect = new Rect(start_x, start_y, V_width / 2, V_height / 2);
                    Mat srcImg = new Mat(v_mat, ROI_rect).Clone();
                    Cv2.Rectangle(v_mat, ROI_rect, new Scalar(255, 255, 0), 2);


                }

                this.pictureBox1.Invoke(new Action(() =>
                {
    
    
                    pictureBox1.Image = BitmapConverter.ToBitmap(v_mat);//在 pictureBox1上显示

                   
                }));

         
              

                v_mat.Release();//释放内存
            }
        }

2.4截图功能
在这里插入图片描述

private void button3_Click(object sender, EventArgs e)
        {
    
    
            SaveFileDialog saveImageDialog = new SaveFileDialog();
            saveImageDialog.Title = "图片保存";
            saveImageDialog.Filter = "jpg图片|*.JPG|gif图片|*.GIF|png图片|*.PNG|jpeg图片|*.JPEG|BMP图片|*.BMP";//文件类型过滤,只可选择图片的类型
            saveImageDialog.FilterIndex = 1;//设置默认文件类型显示顺序 
            saveImageDialog.FileName = "图片保存"; //设置默认文件名,可为空
            saveImageDialog.RestoreDirectory = true; //OpenFileDialog与SaveFileDialog都有RestoreDirectory属性,这个属性默认是false,打开一个文件后,那么系统默认目录就会指向刚才打开的文件。如果设为true就会使用系统默认目录
            if (saveImageDialog.ShowDialog() == DialogResult.OK)
            {
    
    
                string fileName = saveImageDialog.FileName.ToString();
                if (fileName != "" && fileName != null)
                {
    
    
                    string fileExtName = fileName.Substring(fileName.LastIndexOf(".") + 1).ToString();
                    System.Drawing.Imaging.ImageFormat imgformat = null;
                    if (fileExtName != "")
                    {
    
    
                        switch (fileExtName)
                        {
    
    
                            case "jpg":
                                imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
                                break;
                            case "png":
                                imgformat = System.Drawing.Imaging.ImageFormat.Png;
                                break;
                            case "gif":
                                imgformat = System.Drawing.Imaging.ImageFormat.Gif;
                                break;
                            case "bmp":
                                imgformat = System.Drawing.Imaging.ImageFormat.Bmp;
                                break;
                            default:
                                imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
                                break;
                        }
                        try
                        {
    
    
                            MessageBox.Show("保存路径:" + fileName, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            pictureBox1.Image.Save(fileName, imgformat);
                        }
                        catch
                        {
    
    
                            MessageBox.Show("图片保存失败!");
                        }
                    }
                }
            }
        }

2.5 其它功能
在这里插入图片描述
2.5.1 功能存储,在Settings.settings中建立以下变量。
在这里插入图片描述
并在Form1中添加Camer_flag_load()函数,进行初始化。
在这里插入图片描述

  private void Camer_flag_load()
    {
    
    
        //初始化十字准星标识符
        Collimator_flag = Properties.Settings.Default.Collimator_flag;
        if (Collimator_flag) checkBox1.Checked = true;
        else checkBox1.Checked = false;
        //初始化ROI区域标识符
        ROI_flag = Properties.Settings.Default.ROI_flag;
        if (ROI_flag) checkBox2.Checked = true;
        else checkBox2.Checked = false;
        //初始化十字准星标识符
        FlipX_flag = Properties.Settings.Default.FlipX_flag;
        if (FlipX_flag) checkBox3.Checked = true;
        else checkBox3.Checked = false;
        //初始化ROI区域标识符
        FlipY_flag = Properties.Settings.Default.FlipY_flag;
        if (FlipY_flag) checkBox4.Checked = true;
        else checkBox4.Checked = false;

    }

2.5.2 具体功能实现
放置在Play_Video()函数中。

在这里插入图片描述

源代码:https://download.csdn.net/download/sunsoldeir1/87324867

猜你喜欢

转载自blog.csdn.net/sunsoldeir1/article/details/128392181