本文基于开源的GOCW和Directshow.net,实现图像采集等操作。最为关键的部分在于可以实现摄像头的控制,同时关于视频采集进行了实现。

具体的内容请关注首发于51CTO的课程《基于Csharp+OpenCV图像处理实战》
首先拖控件,拉出窗体具体样子。
二、引入Directshow.net,开启摄像头预览

using DirectShowLib;
namespace WINFORM_DEMO
{
    public partial class Form2 : Form
    {
        private Capture cam;
        public Form2()
        {
            InitializeComponent();
            //构造摄像头数据
            foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice))
            {
                cbCam.Items.Add(ds.Name);
            }
            //初始化摄像头
            InitVideoDevice();
        }
        ////helper////
        public void InitVideoDevice()
        {
            try
            {
                if (cam != null)
                    cam.Dispose();
                //读取参数
                int VIDEODEVICE = 0; // zero based index of video capture device to use
                const int VIDEOWIDTH = 640;// 是用默认(最大)分辨率
                const int VIDEOHEIGHT = 480; // Depends on video device caps
                const int VIDEOBITSPERPIXEL = 24; // BitsPerPixel values determined by device
                cam = new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, picPreview);
            }
            catch
            {
                MessageBox.Show("摄像头打开错误,请首先确保摄像头连接并至少支持1024*768分辨率!");
            }
        }
    }
}


在这里,我们通过引入Capture.cs达到获取所有摄像头的目的,实现了摄像头预览。注意这的ViDEODEVICE是0,那么通过修改其就可以开启其他摄像头,需要注意的是首先要进行关闭。这里通过一个简单的重构可以达到目的。

 ////helper////
        public void InitVideoDevice(int VIDEODEVICE = 0)
        {
            try
            {
                if (cam != null)
                    cam.Dispose();
                //读取参数
                const int VIDEOWIDTH = 640;// 是用默认(最大)分辨率
                const int VIDEOHEIGHT = 480; // Depends on video device caps
                const int VIDEOBITSPERPIXEL = 24; // BitsPerPixel values determined by device
                cam = new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, picPreview);
            }
            catch
            {
                MessageBox.Show("摄像头打开错误,请首先确保摄像头连接并至少支持1024*768分辨率!");
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            //获得选择的摄像头
            int iSelect = cbCam.SelectedIndex;
            //开启新摄像头
            InitVideoDevice(iSelect);
        }


最后, 添加摄像头属性控制,这里使用的是Dshow的相关内容,所以比较晦涩。

  /// <summary>
        /// Displays a property page for a filter
        /// </summary>
        /// <param name="dev">The filter for which to display a property page</param>
        private void DisplayPropertyPage(IBaseFilter dev)
        {
            //Get the ISpecifyPropertyPages for the filter
            ISpecifyPropertyPages pProp = dev as ISpecifyPropertyPages;
            int hr = 0;
            if (pProp == null)
            {
                //If the filter doesn't implement ISpecifyPropertyPages, try displaying IAMVfwCompressDialogs instead!
                IAMVfwCompressDialogs compressDialog = dev as IAMVfwCompressDialogs;
                if (compressDialog != null)
                {
                    hr = compressDialog.ShowDialog(VfwCompressDialogs.Config, IntPtr.Zero);
                    DsError.ThrowExceptionForHR(hr);
                }
                else
                {
                    MessageBox.Show("Item has no property page", "No Property Page", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                return;
            }
            //Get the name of the filter from the FilterInfo struct
            FilterInfo filterInfo;
            hr = dev.QueryFilterInfo(out filterInfo);
            DsError.ThrowExceptionForHR(hr);
            // Get the propertypages from the property bag
            DsCAUUID caGUID;
            hr = pProp.GetPages(out caGUID);
            DsError.ThrowExceptionForHR(hr);
            //Create and display the OlePropertyFrame
            object oDevice = (object)dev;
            hr = OleCreatePropertyFrame(this.Handle, 0, 0, filterInfo.achName, 1, ref oDevice, caGUID.cElems, caGUID.pElems, 0, 0, IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);
            Marshal.ReleaseComObject(oDevice);
            if (filterInfo.pGraph != null)
            {
                Marshal.ReleaseComObject(filterInfo.pGraph);
            }
            // Release COM objects
            Marshal.FreeCoTaskMem(caGUID.pElems);
    }


为了正确使用,你还需要添加
        //A (modified) definition of OleCreatePropertyFrame found here: http://groups.google.no/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/db794e9779144a46/55dbed2bab4cd772?lnk=st&q=[DllImport(%22olepro32.dll%22)]&rnum=1&hl=no#55dbed2bab4cd772
        [DllImport("oleaut32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        public static extern int OleCreatePropertyFrame(
            IntPtr hwndOwner,
            int x,
            int y,
            [MarshalAs(UnmanagedType.LPWStr)] string lpszCaption,
            int cObjects,
            [MarshalAs(UnmanagedType.Interface, ArraySubType = UnmanagedType.IUnknown)]
            ref object ppUnk,
            int cPages,
            IntPtr lpPageClsID,
            int lcid,
            int dwReserved,
            IntPtr lpvReserved);

以及
using System.Runtime.InteropServices;

并且在摄像头打开的时候添加相关变量定义。


        private void button1_Click(object sender, EventArgs e)
        {
            //获得选择的摄像头
            int iSelect = cbCam.SelectedIndex;
            //开启新摄像头
            InitVideoDevice(iSelect);
            //生成配套的视频控制界面
            if (theDevice != null)
            {
                Marshal.ReleaseComObject(theDevice);
                theDevice = null;
            }
            //Create the filter for the selected video input device
            string devicepath = cbCam.SelectedItem.ToString();
            theDevice = CreateFilter(FilterCategory.VideoInputDevice, devicepath);
        }


那么到这一步,基于开源的GOCW和Directshow.net,实现图像采集等操作就已经完成。下一步就是应该引入GOCW,实现实时图像处理。

附件列表

基于开源的GOCW和Directshow.net,实现摄像头预览、采集、录像等操作的更多相关文章

  1. 我开源了一个Go学习仓库|笔记预览

    前言 大半个月前我参与了字节后端面试,未通过第四面,面试总结写在了这篇文章: https://juejin.cn/post/7132712873351970823 在此文的末尾,我写到为了全面回顾Go ...

  2. C# 基于Directshow.Net lib库 USB摄像头使用DirectShow.NET获取摄像头视频流

    https://blog.csdn.net/u010118312/article/details/91766787 https://download.csdn.net/download/u010118 ...

  3. 基于开源方案构建统一的文件在线预览与office协同编辑平台的架构与实现历程

    大家好,又见面了. 在构建业务系统的时候,经常会涉及到对附件的支持,继而又会引申出对附件在线预览.在线编辑.多人协同编辑等种种能力的诉求. 对于人力不是特别充裕.或者项目投入预期规划不是特别大的公司或 ...

  4. 基于 WebRTC 的 RTSP 视频实时预览

    简介 背景 由于项目需要,需要使用摄像头预览功能,设备型号为海康威视.目前已存在的基于 FFmpeg 的方案延迟都太高,所以项目最终选择基于此方案. 方案 方案选用为基于 WebRTC 的视频即时通讯 ...

  5. 基于Metronic的Bootstrap开发框架经验总结(9)--实现Web页面内容的打印预览和保存操作

    在前面介绍了很多篇相关的<Bootstrap开发框架>的系列文章,这些内容基本上覆盖到了我这个Bootstrap框架的各个主要方面的内容,总体来说基本达到了一个稳定的状态,随着时间的推移可 ...

  6. DirectShow 进行视频预览和录制

    这一篇讲怎么采集摄像头图像并预览,以及录制视频到本地. 程序实现流程 这里通过使用 CaptureGraphBuilder 来简化 Graph 的创建流程. 具体流程如下: 初始化 COM 库 创建各 ...

  7. 基于开源软件在Azure平台建立大规模系统的最佳实践

    作者 王枫 发布于2014年5月28日 前言 Microsoft Azure 是微软公有云的唯一解决方案.借助这一平台,用户可以以多种方式部署和发布自己的应用. 这是一个开放的平台,除了对于Windo ...

  8. 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】

    文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...

  9. openfire:基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件

    基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfir ...

随机推荐

  1. google firebase in action

    google firebase in action firebase https://console.firebase.google.com/project/_/overview?purchaseBi ...

  2. 如何导出android内部存储的文件(不用root)

    这段时间公司项目,涉及到数据缓存,由于需要缓冲的数据太多.太大,通过网络请求,再缓存到本地sqlite数据库,太费时间,消耗流量.所以准备先在本地保存一个标准版sqlite数据库(包含数据),打包到a ...

  3. ES2020 All in One

    ES2020 All in One ES2020 new features / ES11 ES2020 中的10个新功能 1. BigInt BigInt是JavaScript中最令人期待的功能之一, ...

  4. [转]Linux 线程实现机制分析 Linux 线程实现机制分析 Linux 线程模型的比较:LinuxThreads 和 NPTL

    转载地址:https://www.cnblogs.com/MYSQLZOUQI/p/4233630.html 自从多线程编程的概念出现在 Linux 中以来,Linux 多线应用的发展总是与两个问题脱 ...

  5. 在测试自定义starter时,若出现无法找到helloservice的Bean的解决方法

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoc ...

  6. 微信小程序:Navigator导航组件

    导航组件:类似超链接标签. url:要跳转的页面路径,可以放绝对路径,也可以放相对路径,绝对路径指从pages作为根目录开始找到你要的页面. 找到你要找的页面的相对地址的方法:在vscode中,该页面 ...

  7. <span>居中

    在父元素中加style="text-align:center"; 比如下面这样 <head> </head> <body>     <di ...

  8. Centos8.2安装Mongodb4.4.2(社区版)

    1:下载 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-4.4.2.tgz 官网地址: 2:解压 tar -zxv ...

  9. Go的数组

    目录 数组 一.数组的定义 1.声明数组 2.初始化设值 3.指定位置设值 4.不指定长度初始化(了解) 二.数组的使用 三.数组的类型 四.数组的长度 五.迭代数组 1.初始化迭代 2.使用rang ...

  10. jmeter数据库链接配置

    通常使用数据库有3个要求,性能好.数据一致性有保障.数据安全可靠:数据库优化的前提也是这三个要求.有句玩笑话叫少做少犯错,不做不犯错.DB优化的思路就是少做,减少请求次数,减少数据传输量,减少运算量. ...