2016-11-02 35 views
2

工作我试图让在Unity3D的平面上的摄像头表演。我使用的代码从AForge文档:http://www.aforgenet.com/framework/docs/html/f4d3c2ba-605c-f066-f969-68260ce5e141.htm 除了我将通过统一,而不是通常的AForges方式一个摄像头,它希望让FilterInfoCollection。如果我没有错,Unity需要识别摄像头。制作AForge VideoCaptureDevice使用Unity

但是我的代码是不工作什么那么,摄像头开始(因为我webCam.Play的()),但没有什么事情发生。通过调试,我发现程序没有达到我的video_NewFrame函数,我相信在使用Unity时需要以某种方式进行初始化?

如何设置这个正确?

using UnityEngine; 
using System.Collections; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.IO; 
using AForge.Video; 
using AForge.Video.DirectShow; 
using AForge.Imaging.Filters; 
using AForge.Imaging; 
using AForge; 

public class LoadVideo : MonoBehaviour { 

    public VideoCaptureDevice videoSource; 
    WebCamTexture webCam; 
    void Start(){ 
     webCam = new WebCamTexture(); 
     webCam.Play(); 
    } 

    // Update is called once per frame 
    object b; 
    public WebCamDevice wc; 
    public GameObject originalFeed; 
    void Update() { 
     videoSource = new VideoCaptureDevice(webCam.deviceName); 
     videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame); 
     videoSource.Start(); 
     originalFeed.GetComponent<Renderer>().material.mainTexture = originalFeedTexture; 
    } 
    public delegate void EventPrototype(System.EventArgs args); 

    Texture2D originalFeedTexture; 
    void video_NewFrame(object sender, NewFrameEventArgs eventArgs) 
    { 
     Debug.Log("you here mate"); 
     Bitmap video = (Bitmap)eventArgs.Frame.Clone(); 
     MemoryStream memoryStream = new MemoryStream(); 
     video.Save(memoryStream, ImageFormat.Jpeg); 
     byte[] bitmapRecord = memoryStream.ToArray(); 

     originalFeedTexture.LoadImage(bitmapRecord); 
    } 

} 
+0

您正在使用什么版本的'AForge'的? –

+0

@ AlessandroD'Andria 2.2.5 –

+0

我有'2.2.5'和降级到'2.2.0'的问题(在我的情况下,事件从未提出过)。 –

回答

1

首先,我不知道,AForge将团结奋斗。原因是因为它使用.NET 4或更多,而Unity使用.NET 3.5。

除此之外,还有在你的代码的几个问题。

WebCamTexture用于通过统一开始从照相机捕获的帧。

VideoCaptureDevice被使用AForge开始捕捉相机的帧。

4问题

。你必须使用一个不能同时使用。您无法将两者结合在一起,并且我认为可以一次从一个位置访问相机。

当你做了webCam.Play();然后videoSource.Start();,你试图从多个API使用一个摄像头。如果您想使用AForge API,则应使用VideoCaptureDevice

。你正在呼吁videoSource = new VideoCaptureDevice(webCam.deviceName);并与videoSource.Start();Update函数每帧开始相机。这应该通过将其移动到Start函数来完成一次。您还需要注册一次NewFrame事件。

originalFeedTexture未初始化,但用于video_NewFrameUpdate函数。

。您可以通过WebCamDevice类获得摄像头名称。最后的示例代码显示了如何。不要使用WebCamTexture

。很有可能videoSource.NewFrame是从另一个Thread调用/调用的。所以,当你的video_NewFrame函数被调用时,originalFeedTexture.LoadImage(bitmapRecord);行代码会抛出看起来像这样的例外:

....只能从主线程调用

你可以有在Unity的主线程或更新函数中找到调用该行代码的方法,因为您无法在另一个Thread中使用Unity API(Texture2D/originalFeedTexture)。

从下面的代码开始,也许你可以得到它的工作。不知道这整个AForge + 团结东西由于.NET版本的差异。问题#5在此解决方案中没有修复。你可以使用Unity Threading Helper插件(免费)。

public class LoadVideo : MonoBehaviour 
{ 
    public VideoCaptureDevice videoSource; 
    public GameObject originalFeed; 
    Texture2D originalFeedTexture; 

    void Start() 
    { 
     init(); 
    } 

    void init() 
    { 
     originalFeedTexture = new Texture2D(128, 128); 

     //Get WebCam names 
     WebCamDevice[] devices = WebCamTexture.devices; 
     if (devices.Length <= 0) 
     { 
      Debug.LogError("No Web Cam Found....Exiting"); 
      return; //Exit 
     } 
     videoSource = new VideoCaptureDevice(devices[0].name); 
     videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame); 
     videoSource.Start(); 
    } 

    void stop() 
    { 
     videoSource.SignalToStop(); 
    } 

    void Update() 
    { 
     originalFeed.GetComponent<Renderer>().material.mainTexture = originalFeedTexture; 
    } 

    public delegate void EventPrototype(System.EventArgs args); 

    void video_NewFrame(object sender, NewFrameEventArgs eventArgs) 
    { 
     Debug.Log("you here mate"); 
     Bitmap video = (Bitmap)eventArgs.Frame.Clone(); 
     MemoryStream memoryStream = new MemoryStream(); 
     video.Save(memoryStream, ImageFormat.Jpeg); 
     byte[] bitmapRecord = memoryStream.ToArray(); 

     originalFeedTexture.LoadImage(bitmapRecord); 
    } 

    //Make sure to stop when run time ends 
    void OnDisable() 
    { 
     stop(); 
    } 
} 

我试图分裂摄像机进入帧上,然后我可以使用 AForges方法。

如果这是你想做的事,你可以使用统一的WebCamTexture然后将其转换为Texture2D

WebCamTexture webCam = new WebCamTexture (160, 120); 
webCam.play(); 
Texture2D originalFeedTexture = new Texture2D(webCam.width, webCam.height); 
originalFeedTexture.SetPixels(webCam.GetPixels()); 
originalFeedTexture.Apply(); 
///Use it then destroy it 
Object.Destroy(originalFeedTexture); 

框架现在是存储在originalFeedTexture变量。 如果你需要为字节,也许对发送了网络Texture2D帧:

JPG字节:

byte[] bytes = originalFeedTexture.EncodeToJPG(); 

PNG字节:

byte[] bytes = originalFeedTexture.EncodeToPNG(); 
+0

感谢您的精心解答!我试过你的第一段代码,它没有给出任何错误,但是相机并没有启动。我同意AForge和Unity之间可能存在问题,但我有一些评论。我在加载的图像上预先测试了一些灰度函数,效果很好。如果这确实是一个AForge问题,是否可以通过降级到更高版本进行修复?我会尽快测试你的第二段代码,因为这可能会诀窍。亲切的问候 –

+0

“我事先在加载的图像上测试了一些灰度函数,效果良好”AForge API分为多个模块。一些模块使用Unity不支持的新.NET API。其他人不使用'.NET API'中的API,因此应该可以正常工作。一个例子是async/await关键字。我期望图像处理API是独立的,甚至不需要'.NET 4 API'。也许,找到lowe版本然后用'.NET 3.5'或更少的版本来构建它。一个重要的事情是**将AForge的所有DLL放入资源文件夹**中。 – Programmer

+0

我看到你接受了这个答案。请告诉我发生了什么事。我也认为你应该检查[this](https://forum.unity3d。com/forums/experimental-scripting-previews.107 /)。 Unity正在测试他们的.NET 4.6。你很多人想要下载并尝试它。顺便说一下,它现在只能在编辑器中运行。独立构建支持将在几个月内添加。 – Programmer