Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使大型视频捕获设备与Unity一起工作_C#_Unity3d_Aforge - Fatal编程技术网

C# 使大型视频捕获设备与Unity一起工作

C# 使大型视频捕获设备与Unity一起工作,c#,unity3d,aforge,C#,Unity3d,Aforge,我想在Unity3D的飞机上做一个镜头秀。我正在使用AForge文档中的代码: 除了我通过Unity插入了一个网络摄像头,而不是一个常用的方式,它想在这里进行FilterInFocCollection。如果我没记错的话,Unity需要这个来识别网络摄像头 但是,我的代码无法正常工作,网络摄像头会启动(因为我的webcam.Play()),但不会发生其他任何事情。通过调试,我发现程序没有达到我的video_NewFrame函数,我认为在使用Unity时需要以某种方式进行初始化 我如何正确设置它 u

我想在Unity3D的飞机上做一个镜头秀。我正在使用AForge文档中的代码: 除了我通过Unity插入了一个网络摄像头,而不是一个常用的方式,它想在这里进行FilterInFocCollection。如果我没记错的话,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);
    }

}
使用UnityEngine;
使用系统集合;
使用系统图;
使用系统、绘图、成像;
使用System.IO;
使用大屏幕视频;
使用forge.Video.DirectShow;
使用热成像滤光片;
使用快速成像;
使用冲锋枪;
公共类加载视频:单行为{
公共视频捕获设备视频源;
网络摄像机;
void Start(){
webCam=新的WebCamTexture();
webCam.Play();
}
//每帧调用一次更新
对象b;
公共网络摄像机;
公共游戏对象原始种子;
无效更新(){
videoSource=新的VideoCaptureDevice(网络摄像头.deviceName);
videoSource.NewFrame+=新的NewFrameEventHandler(视频\新帧);
videoSource.Start();
originalFeed.GetComponent().material.mainTexture=originalFeedTexture;
}
公共委托void EventPrototype(System.EventArgs args);
纹理2D原始种子纹理;
void video_NewFrame(对象发送方,NewFrameEventArgs eventArgs)
{
Log(“你在这里的伴侣”);
位图视频=(位图)eventArgs.Frame.Clone();
MemoryStream MemoryStream=新的MemoryStream();
保存(memoryStream,ImageFormat.Jpeg);
字节[]bitmapRecord=memoryStream.ToArray();
原始FeedTexture.LoadImage(位图记录);
}
}

首先,我不确定一个团体能否团结一致。原因是它使用.NET4或更多,而Unity使用.NET3.5

除此之外,代码中还有几个问题

Unity使用1
WebCamTexture
开始从相机捕获帧

2
VideoCaptureDevice
被Forge用来开始从相机捕获帧

四个问题

1。您必须同时使用其中一个,而不是两个。你不能将两者结合起来,我相信相机一次只能从一个位置进入

当您执行
webCam.Play()时然后
视频源.Start(),您正在尝试使用多个API中的一个摄影机。如果要使用RGE API,应使用
VideoCaptureDevice

2。您正在呼叫
videoSource=新的视频捕获设备(webCam.deviceName)
并使用
videoSource.Start()启动相机更新功能中的每一帧。将其移动到
Start
功能,即可完成一次。您还需要注册一次
NewFrame
事件

3
originalFeedTexture
未初始化,但在
video\u NewFrame
Update
功能中使用

4。您可以通过该类获取网络摄像头的名称。最后的示例代码演示了如何使用。不要使用
WebCamTexture

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();
    }
}
5。极有可能从另一个
线程调用了
videoSource.NewFrame
。因此,当调用
video\u NewFrame
函数时,
originalFeedTexture.LoadImage(bitmapRecord)代码行将引发如下异常:

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

您必须找到在Unity的主线程或更新函数中调用该行代码的方法,因为您不能在另一个
线程中使用Unity API(Texture2D/originalFeedTexture)

从下面的代码开始,也许你可以让它工作。由于
.NET
版本的差异,我不确定整个AForge+Unity事件。此解决方案中没有解决问题5。你可以使用插件(免费)来实现这一点

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();
    }
}
帧现在存储在
originalFeedTexture
变量中。 如果需要
Texture2D
帧作为字节,可以通过网络发送:

字节:

字节:


您使用的是哪个版本的
a RGE
。@AlessandroD'Andria 2.2.5我对
2.2.5
有问题,并且降级到
2.2.0
(在我的情况下,事件从未引发过)。刚刚做了一个降级测试,完全相同的问题。您为什么使用a RGE访问相机帧?感谢您详细的回答!我尝试了你的第一段代码,它没有给出任何错误,但相机也没有激活。我同意在一场革命和团结之间可能会有一个问题,但我有几点意见。我事先在加载的图像上测试了一个RGE,使用了一些灰度函数,效果很好。如果这确实是一个大问题,是否可以通过降级到更高版本来解决?我将很快测试你的第二段代码,因为这可能会奏效。Kind认为“我在加载的图像上使用一些灰度函数预先测试了AForge,效果很好”。AForge API分为多个模块。某些模块使用新的
.NET API
Unity不支持。其他人不使用
.NETAPI
中的API,因此应该可以正常工作。async/await关键字就是一个例子。我希望图像处理API是独立的,甚至不需要
.NET4API
。也许,找到lowe版本,然后使用
.NET3.5
或更低版本构建它。要做的一件重要的事情是将一个RGE的所有DLL放在Asset文件夹中。我看你接受了这个答案。请告诉我哈
byte[] bytes = originalFeedTexture.EncodeToJPG();
byte[] bytes = originalFeedTexture.EncodeToPNG();