2016-11-02 8 views
2

私はUnity3Dで航空機にカメラショーを作ろうとしています。私はAForgeのドキュメントのコードを使用しています:http://www.aforgenet.com/framework/docs/html/f4d3c2ba-605c-f066-f969-68260ce5e141.htm を除いて、私はUnityからAForgesの代わりにFilterInfoCollectionを作成したいという通常の方法でWebcamを挿入します。私が間違っていない場合、これはUnityがWebカメラを認識するために必要です。AForge VideoCaptureDeviceをUnityと連携させるには

しかし、私のコードはこれまでどおりに動作していません。ウェブカメラが(webCam.Play()のために)起動しますが、何も起こりません。私が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はユニティに動作することを確認していません。これは、Unityが.NET 3.5を使用しているときに.NET 4以上を使用するためです。

これ以外にも、コードにいくつかの問題があります。

WebCamTextureUnityによって使用され、カメラからフレームのキャプチャを開始します。

VideoCaptureDeviceは、AForgeによって使用され、カメラからフレームのキャプチャを開始します。

4の問題

。あなたは一つではないの両方を使用する必要があります。両方を組み合わせることはできませんし、一度に1つの場所からカメラにアクセスできると思います。

webCam.Play();、次にvideoSource.Start();を実行したときに、複数のAPIから1台のカメラを使用しようとしています。 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);行はこのようになります例外がスローされます他のThreadでUnity API(Texture2D/originalFeedTexture)を使用することができないので、UnityのメインスレッドまたはUpdate関数でそのコード行を呼び出す方法を見つけることができます。

以下のコードから始めて、多分それを動作させることができます。この全体についてわからないAForge + Unity.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メソッドを使用することができた上で、フレームの中にカメラを分割しようとしています。それはあなたがやりたいなら

、あなたはその後、Texture2Dに変換ユニティのWebCamTextureを使用することができます。

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を事前にテストしましたが、うまくいきました。これが実際にAForgeの問題であれば、それ以降のバージョンにダウングレードすることで修正することは可能でしょうか?私はあなたの2番目のコードをすぐにテストするつもりです、それはトリックを行うかもしれないので。種類: –

+0

「読み込んだ画像にあるグレースケール関数であらかじめAForgeをテストしましたが、うまくいきました」AForge APIはモジュールに分割されています。いくつかのモジュールは、新しい '.NET API' Unityがサポートしていないものを使用しています。他の人は、.NET APIからAPIを使用しないので、うまく動作するはずです。これの例はasync/awaitキーワードです。私は、画像操作APIが独立していて、 '.NET 4 API 'は必要ないと考えています。たぶん、lowe版を見つけ、次に '.NET 3.5'以下でビルドしてください。一つの重要なことは、AForgeのすべてのDLLをAssetフォルダ**に置くことです。 – Programmer

+0

この回答を受け入れたことがわかりました。何が起こるか教えてください。私はあなたも[this](https://forum.unity3d)をチェックすべきだと思います。com/forums/experimental-scripting-previews.107 /)をご覧ください。 Unityは彼らの「.NET 4.6」をテストしている。あなたはそれをダウンロードして試してみたくなります。ちなみに、エディターでは今のところしか動作しません。スタンドアロン構築サポートは数ヶ月で追加されます。 – Programmer

関連する問題