2016-11-02 33 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