使 AForge VideoCaptureDevice 与 Unity 一起工作
Making AForge VideoCaptureDevice work with Unity
我正在尝试在 Unity3D 中的飞机上进行相机展示。我正在使用 AForge 文档中的代码:http://www.aforgenet.com/framework/docs/html/f4d3c2ba-605c-f066-f969-68260ce5e141.htm
除了我通过 Unity 而不是 AForges 通常的方式插入网络摄像头,它想要制作 FilterInfoCollection。如果我没记错的话,这是 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);
}
}
首先,我不确定 AForge 是否可以在 Unity 中运行。原因是因为它使用.NET 4或更高版本,而Unity使用.NET 3.5。
除此之外,您的代码中还有几个问题。
1。WebCamTexture
被 Unity 用于开始从相机捕获帧。
2。VideoCaptureDevice
被 AForge 用于开始从相机捕获帧。
4个问题:
1。您必须使用一个,不能同时使用两个。你不能将两者结合起来,我相信一次可以从一个位置访问相机。
当您 webCam.Play();
然后 videoSource.Start();
时,您正在尝试使用多个 API 中的一个摄像头。如果要使用 AForge API.
,则应使用 VideoCaptureDevice
2。您正在调用 videoSource = new VideoCaptureDevice(webCam.deviceName);
并在 Update
函数中每帧以 videoSource.Start();
启动相机。这应该通过将其移动到 Start
函数来完成一次。您还需要注册一次NewFrame
活动。
3。 originalFeedTexture
未初始化,但在 video_NewFrame
和 Update
函数中使用。
4。您可以使用 WebCamDevice
class 获取网络摄像头名称。最后的示例代码显示了如何。不要为此使用 WebCamTexture
。
5。极有可能videoSource.NewFrame
是另一个Thread
的invoked/called。因此,当您的 video_NewFrame
函数被调用时,originalFeedTexture.LoadImage(bitmapRecord);
行代码将抛出如下所示的异常:
.... can only be called from the main thread
您可能必须找到一种方法在 Unity 的主线程或更新函数中调用该行代码,因为您不能在另一个 [=30] 中使用 Unity API(Texture2D/originalFeedTexture) =].
从下面的代码开始,也许你可以让它工作。由于 .NET
版本差异,不确定整个 AForge+Unity 事情。问题 #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();
}
}
I am trying to split the camera into frames, on which I then can use
AForges methods.
如果这就是你想要做的,你可以使用 Unity 的 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();
我正在尝试在 Unity3D 中的飞机上进行相机展示。我正在使用 AForge 文档中的代码:http://www.aforgenet.com/framework/docs/html/f4d3c2ba-605c-f066-f969-68260ce5e141.htm 除了我通过 Unity 而不是 AForges 通常的方式插入网络摄像头,它想要制作 FilterInfoCollection。如果我没记错的话,这是 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);
}
}
首先,我不确定 AForge 是否可以在 Unity 中运行。原因是因为它使用.NET 4或更高版本,而Unity使用.NET 3.5。
除此之外,您的代码中还有几个问题。
1。WebCamTexture
被 Unity 用于开始从相机捕获帧。
2。VideoCaptureDevice
被 AForge 用于开始从相机捕获帧。
4个问题:
1。您必须使用一个,不能同时使用两个。你不能将两者结合起来,我相信一次可以从一个位置访问相机。
当您 webCam.Play();
然后 videoSource.Start();
时,您正在尝试使用多个 API 中的一个摄像头。如果要使用 AForge API.
VideoCaptureDevice
2。您正在调用 videoSource = new VideoCaptureDevice(webCam.deviceName);
并在 Update
函数中每帧以 videoSource.Start();
启动相机。这应该通过将其移动到 Start
函数来完成一次。您还需要注册一次NewFrame
活动。
3。 originalFeedTexture
未初始化,但在 video_NewFrame
和 Update
函数中使用。
4。您可以使用 WebCamDevice
class 获取网络摄像头名称。最后的示例代码显示了如何。不要为此使用 WebCamTexture
。
5。极有可能videoSource.NewFrame
是另一个Thread
的invoked/called。因此,当您的 video_NewFrame
函数被调用时,originalFeedTexture.LoadImage(bitmapRecord);
行代码将抛出如下所示的异常:
.... can only be called from the main thread
您可能必须找到一种方法在 Unity 的主线程或更新函数中调用该行代码,因为您不能在另一个 [=30] 中使用 Unity API(Texture2D/originalFeedTexture) =].
从下面的代码开始,也许你可以让它工作。由于 .NET
版本差异,不确定整个 AForge+Unity 事情。问题 #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();
}
}
I am trying to split the camera into frames, on which I then can use AForges methods.
如果这就是你想要做的,你可以使用 Unity 的 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();