温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

EMGU 控制USB摄像头

发布时间:2020-07-31 13:26:53 来源:网络 阅读:2571 作者:Raevo 栏目:开发技术

  接到新任务,用来监控3D打印机的摄像头,需要对其进行控制。之前我没有做过任何这方面的工作,很是挠头。不过有脚本和开源两个强大的工具,我也不是很害怕。

  首先有人指明需要用到的库是OpenCV。CV是指Computer vision, 从名字就能判断这是专注于视频处理的库。很快我就找到了python的调用demo.并且成功的带动了手边的摄像头。http://opencv.org/安装后,就能在sources/samples/python/demo文件夹下面找到完整的demo程序。

  不过这不能解决项目问题。我们的项目要求在.net环境下开发。所以很快,我就找到了成熟的.net平台下OpenCV解决方案,名叫EMGU;

 同样的,EMGU也完整的demo例程。在EMGU3.1版本的安装路径下面\Solution\VS2013-2015文件夹中,就有摄像头的驱动例子:实现摄像头实时采样,只需要几行代码:

... private static Capture _cameraCapture; ... void run(){     try          {             _cameraCapture = new Capture();          }          catch (Exception e)          {             MessageBox.Show(e.Message);             return;          }           Application.Idle += ProcessFrame; ... void ProcessFrame(object sender, EventArgs e)       {          Mat frame = _cameraCapture.QueryFrame(); }

通过Applicaiton.Idle+= ProcessFrame的加载事件,非常优雅的实现了摄像头的驱动。

 进一步,EMGU中有Websevice的例子。但是例子中传输的是一串字符串,采用的是net.tcp协议。我尝试传输p_w_picpath,结果在旁边电脑成功访问了我的摄像头,但是卡顿非常严重。(暂时分析不出来卡顿的原因)

host端代码:

using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.ServiceModel; using System.ServiceModel.Description; using System.Text; using Emgu.CV; namespace Webservice_Host {    class Program    {       static void Main(string[] args)       {           Uri uri = new Uri("net.tcp://localhost:8082/ImageService");           NetTcpBinding binding = new NetTcpBinding();           binding.Security.Mode = SecurityMode.None;                     //WSHttpBinding binding = new WSHttpBinding();          binding.MaxReceivedMessageSize = 2147483647;          ServiceHost host = new ServiceHost(typeof(ImageService));          ServiceBehaviorAttribute serviceBehavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();          serviceBehavior.IncludeExceptionDetailInFaults = true;          // Create endpoint          host.AddServiceEndpoint(typeof(IImageService), binding, uri);          host.Open();          Console.WriteLine("Service is ready, press any key to terminate.");          Console.ReadKey();          host.Close();         }    } }
ImageService.cs using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Structure; namespace Webservice_Host {    public class ImageService : IImageService    {       public Image<Bgr, Byte> GrabFrame()       {                     Capture _capture = new Capture();           Mat frame=new Mat();           //_capture.Retrieve(frame,0);           //Image<Bgr, Byte> img = frame.ToImage<Bgr, Byte>();          Image<Bgr, Byte> img = _capture.QueryFrame().ToImage<Bgr, Byte>();          if (_capture != null)              _capture.Dispose();          return img;       }    } }

IImageService.cs using System; using System.Collections.Generic; using System.Text; using Emgu.CV; using Emgu.CV.Structure; using System.ServiceModel; namespace Webservice_Host {    [ServiceContract]    [XmlSerializerFormat]    public interface IImageService    {       [OperationContract(IsOneWay = false)]       Image<Bgr, Byte> GrabFrame();    }      }

client端代码:

//---------------------------------------------------------------------------- //  Copyright (C) 2004-2016 by EMGU Corporation. All rights reserved.        //---------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.ServiceModel; using System.Threading; using Emgu.CV; namespace Webservice_Client {    public partial class Form1 : Form    {       private bool _started;       private Webservice_Host.IImageService _p_w_picpathGrabber;       private NetTcpBinding _binding;       private static Queue<IImage> p_w_picpathQ;       public Form1()       {          InitializeComponent();          _binding = new NetTcpBinding();          _binding.Security.Mode = SecurityMode.None;          _binding.MaxReceivedMessageSize = 2147483647;          Queue<IImage> p_w_picpathQ = new Queue<IImage>();           //System.Collections.Queue p_w_picpathQ= new System.Collections.Queue();            _started = false;       }               public bool Started       {          get { return _started; }          set          {             _started = value;             serviceUrlBox.Enabled = !_started;             if (!_started)             {                  //stop grabing frames                //Application.Idle -= ProcessImage;                 // System.Timers.Timer t =new System.Timers.Timer(1);                //  t.Start();                // t.Elapsed+= ProcessImage;             }             else             {                //start to grab frames                             _p_w_picpathGrabber = new ChannelFactory<Webservice_Host.IImageService>(                    _binding,                    new EndpointAddress(serviceUrlBox.Text)                    ).CreateChannel();                 //System.Timers.Timer t =new System.Timers.Timer(50);                 //t.Start();                 ////button2.Click += ProcessImage;                 //t.Elapsed+= ProcessImage;                 //// Application.Idle                  Thread rx_p_w_picpath_thread = new Thread(new ThreadStart(get_p_w_picpath));                 Thread show_p_w_picpath_thread = new Thread(new ThreadStart(show_p_w_picpath));                 rx_p_w_picpath_thread.Start();                 show_p_w_picpath_thread.Start();             }          }       }       private void get_p_w_picpath()       {           Queue<IImage> p_w_picpathQ = new Queue<IImage>();           while (true)           {               p_w_picpathQ.Enqueue(_p_w_picpathGrabber.GrabFrame());           }       }       private void show_p_w_picpath()       {           while (true) {             //  if (p_w_picpathQ.Count>0&&p_w_picpathQ!=null)             //  p_w_picpathBox1.Image=p_w_picpathQ.Dequeue();           }       }       private void ProcessImage(object sender, EventArgs e)       {          p_w_picpathBox1.Image = _p_w_picpathGrabber.GrabFrame();       }       private void button1_Click(object sender, EventArgs e)       {          Started = !Started;          if (Started == true)             button1.Text = "Stop";          else               button1.Text = "Start";                               }       private void ReleaseResource()       {          Started = false;       }       private void button2_Click(object sender, EventArgs e)       {       }    } }

IImageService

using System; using System.Collections.Generic; using System.Text; using Emgu.CV; using Emgu.CV.Structure; using System.ServiceModel; namespace Webservice_Host {    [ServiceContract]    [XmlSerializerFormat]    public interface IImageService    {       [OperationContract(IsOneWay = false)]       Image<Bgr, Byte> GrabFrame();    }      }

到此为止,我对EMGU带摄像头的尝试就结束了。后面我采用EMGU做了两件事情,都是和网络摄像头有关:一是用ASP.NET用网页控制远程web摄像头拍照并传过来实时图像。二是将EMGU截图封装成为dll的方法,交给其他工程师使用。


总体而言,也可能是受制于我的编程功力,无法用EMGU来实现更复杂的摄像头访问应用。但是EMGU作为OpenCV在.net平台的封装,其项目重心用在了图像识别算法的封装而不是多媒体应用上:我们可以看到大量的例程进行图像识别等算法,调用起来非常方便。


而对于将摄像头转成流媒体源的工作,我找到了更加有效的框架,即微软自带的Media Foudation框架。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI