• directshow、 Emgucv入门


    本示例主要测试了directshow、Emgucv的视频流采集功能,其中Emgucv还实现了人脸的识别。示例源码下载

    一、directshow的介绍

    实现原理:directshow可以将摄像头的数据流以事件的方式实时传递给程序,程序在此事件中拿到流后可以保存为图片(流可以经过多个filterGraph2对象)。directshow提供将数据绑定到picturebox控件上。以下为打开一个摄像头的步骤:

    1. 引入directshow.net控件

    此控件可以在网上搜索,即好下载,名称为DirectShowLib-2005,它是directshow的.net版本的封装.

    2. 初始化directshow相关的接口

    代码如下:

    int hr = 0;
    this.filterGraph2 = (IFilterGraph2)new FilterGraph();
    this.captureGraphBuilder2 = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
    this.mediaControl = (IMediaControl)this.filterGraph2;
    this.videoWindow = (IVideoWindow)this.filterGraph2;
    DsError.ThrowExceptionForHR(hr);

    说明:

    1. filterGraph2:流过滤器
    2. captureGraphBuilder2:视频设备处理
    3. mediaControl:视频控制,如:开启或关闭等
    4. videoWidow:视频显示在窗体上的一些信息设置类
    5. filterGraph2会被附加到captureGraphBuilder2对象.

    3. 找到摄像头设备

    int hr = 0;
    IEnumMoniker classEnum = null;
    IMoniker[] moniker = new IMoniker[1];
    object source = null;
    
    ICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();
    hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);
    DsError.ThrowExceptionForHR(hr);
    
    Marshal.ReleaseComObject(devEnum);
    
    if (classEnum == null)
        throw new Exception("classEnum is null");
    
    if (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)
    {
        Guid iid = typeof(IBaseFilter).GUID;
        moniker[0].BindToObject(null, null, ref iid, out source); //moniker绑定以 ibasefilter和object上
    }
    
    Marshal.ReleaseComObject(moniker[0]);
    Marshal.ReleaseComObject(classEnum);
    
    return (IBaseFilter)source;

    找到视频摄像头,将转换为一个IBaseFilter对象。

    4. 增加摄像头、视频处理过滤器

    将IBaseFilter对象加入到filterGraph2对象上,作为第一层视频的过滤,后面会放到picturebox控件上。然后再加入SampleGrabber对象,用于捕获每一帧的视频数据。

    5. 设置摄像头显示参数、预览参数、 设置保存的尺寸信息

    此步代码较多,就不在贴代码,后面给出源码下载地址.

    6. 绑定以pictruebox控件上,以及运行

    int hr = 0;
    hr = this.videoWindow.put_Owner(this.pictureBox.Handle);
    DsError.ThrowExceptionForHR(hr);
    
    hr = this.videoWindow.put_WindowStyle(WindowStyle.Child);
    DsError.ThrowExceptionForHR(hr);
    
    hr = this.videoWindow.put_Visible(OABool.True);
    DsError.ThrowExceptionForHR(hr);
    
    System.Drawing.Rectangle rc = this.pictureBox.ClientRectangle;
    hr = this.videoWindow.SetWindowPosition(0, 0, 640, 480);
    DsError.ThrowExceptionForHR(hr);

    二、emgucv的介绍

    emgucv是opencv的.net版本封装,并且opencv获取视频流的方式也是采用的directshow。由于进行了封装,打开和识别人像就极为简单了。

    1. 下载emgucv并安装,然后在系统环境变量中添加其安装路径.

    image
    至此,还需复制相关的dll到开发项目中:
    image

    2. 打开摄像头

    private VideoCapture capture;
    private Mat mat;
    private Common.DetectFace detectFace;
    public Form1()
    {
        InitializeComponent();
        CvInvoke.UseOpenCL = false;
        detectFace = new Common.DetectFace();
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        capture = new Emgu.CV.VideoCapture();
        capture.ImageGrabbed += Capture_ImageGrabbed;
        capture.Start();
    }
    
    private void Capture_ImageGrabbed(object sender, EventArgs e)
    {
        if (capture != null && capture.Ptr != IntPtr.Zero)
        {
            mat = new Mat();
            capture.Retrieve(mat, 0);
    
            var ls = detectFace.Detect(mat);
            foreach(var face in ls)
            {
                CvInvoke.Rectangle(mat, face, new Bgr(Color.Red).MCvScalar, 2);
            }
    
            imageBox1.Image = mat;
        }
    }

    说明:

    1. Capture_ImageGrabbed捕获到的就是实时的视频流,在此处就可以做相关的处理。
    2. 此处加入了对人脸的识别,并用红框表示出来。
  • 相关阅读:
    嵌入式整体框架——总结
    DSP Bios记忆
    三遥
    usb设备 配置 接口 端点
    ARM, MIPS, Power PC的比较
    STM32 IAP
    FSMC 总结
    BCD码与十进制的相互转换
    读 “cortexM3” 权威指南 小记(一)
    crc校验码的16 32位 查表法 算法记载
  • 原文地址:https://www.cnblogs.com/cqhaibin/p/7225177.html
Copyright © 2020-2023  润新知