【问题标题】:Emgucv Image to texture2d on UnityEmgucv图像到Unity上的texture2d
【发布时间】:2014-06-28 06:47:49
【问题描述】:
public class testEmguCV : MonoBehaviour
{
    private Capture capture;

    void Start() 
    {
        capture = new Capture();
    }

    void Update()
    {
        Image<Gray, Byte> currentFrame = capture.QueryGrayFrame();
        Bitmap bitmapCurrentFrame = currentFrame.ToBitmap();
        MemoryStream m = new MemoryStream();
        bitmapCurrentFrame.Save(m, bitmapCurrentFrame.RawFormat);

        Texture2D camera = new Texture2D(400, 400);
        if (currentFrame != null)
        {
            camera.LoadImage(m.ToArray());
            renderer.material.mainTexture = camera;
        }
     }
} 

我使用上面的代码在统一的从 emgucv 相机到 texture2d 的相机馈送之间进行转换,但我遇到了 bitmapCurrentFrame.Save(m, bitmapCurrentFrame.RawFormat); 的问题 它给出了以下错误

ArgumentNullException:参数不能为空。参数名称: 编码器 System.Drawing.Image.Save(System.IO.Stream 流, System.Drawing.Imaging.ImageCodecInfo 编码器, System.Drawing.Imaging.EncoderParameters (encoderParams) System.Drawing.Image.Save(System.IO.Stream 流, System.Drawing.Imaging.ImageFormat 格式)(包装 remoting-invoke-with-check) System.Drawing.Image:Save (System.IO.Stream,System.Drawing.Imaging.ImageFormat) WebcamUsingEmgucv.Update () (在 Assets/WebcamUsingEmgucv.cs:51)

经过几个小时的思考和搜索,我不知道发生了什么,请帮忙

【问题讨论】:

  • 我遇到了确切的问题,你解决了吗?
  • 我通过使用 Unity 安装文件夹中的 system.drawing.dll 解决了这个问题。以前我使用 Windows 文件夹中的 system.drawing.dll 导致错误。

标签: unity3d emgucv


【解决方案1】:

我在我们的项目中使用了您的示例,谢谢!但我将其修改为:

void Update()
{
    if(capture == null)
    {
        Debug.LogError("Capture is null");
        return;
    }
    Image<Gray, Byte> currentFrame = capture.QueryGrayFrame();
    MemoryStream m = new MemoryStream();
    currentFrame.Bitmap.Save(m, currentFrame.Bitmap.RawFormat);

    Texture2D camera = new Texture2D(400, 400);
    if (currentFrame != null)
    {
        camera.LoadImage(m.ToArray());
        renderer.material.mainTexture = camera;
    }
}

这是工作! Fps 平均约 30-35。祝你好运!

【讨论】:

    【解决方案2】:

    尝试使用这个: https://github.com/neutmute/emgucv/blob/3ceb85cba71cf957d5e31ae0a70da4bbf746d0e8/Emgu.CV/PInvoke/Unity/TextureConvert.cs 它有这样的东西:

    public static Texture2D ImageToTexture2D<TColor, TDepth>(Image<TColor, TDepth> image, bool correctForVerticleFlip)
         where TColor : struct, IColor
         where TDepth : new()
      {
         Size size = image.Size;
    
         if (typeof(TColor) == typeof(Rgb) && typeof(TDepth) == typeof(Byte))
         {
            Texture2D texture = new Texture2D(size.Width, size.Height, TextureFormat.RGB24, false);
            byte[] data = new byte[size.Width * size.Height * 3];
            GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            using (Image<Rgb, byte> rgb = new Image<Rgb, byte>(size.Width, size.Height, size.Width * 3, dataHandle.AddrOfPinnedObject()))
            {
               rgb.ConvertFrom(image);
               if (correctForVerticleFlip)
                  CvInvoke.cvFlip(rgb, rgb, FLIP.VERTICAL);
            }
            dataHandle.Free();
            texture.LoadRawTextureData(data);
            texture.Apply();
            return texture;
         }
         else //if (typeof(TColor) == typeof(Rgba) && typeof(TDepth) == typeof(Byte))
         {
            Texture2D texture = new Texture2D(size.Width, size.Height, TextureFormat.RGBA32, false);
            byte[] data = new byte[size.Width * size.Height * 4];
            GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            using (Image<Rgba, byte> rgba = new Image<Rgba, byte>(size.Width, size.Height, size.Width * 4, dataHandle.AddrOfPinnedObject()))
            {
               rgba.ConvertFrom(image);
               if (correctForVerticleFlip)
                  CvInvoke.cvFlip(rgba, rgba, FLIP.VERTICAL);
            }
            dataHandle.Free();
            texture.LoadRawTextureData(data);
    
            texture.Apply();
            return texture;
         }
    
         //return null;
      }
    

    如果你不想使用 InterOp 你也可以使用类似的东西

    cameraframe.Convert<Rgb,byte>().Data.Cast<byte>().ToArray<byte>() 
    

    并使用它而不是使用 interOp 的部分

    这两种解决方案都对我有用。请记住在替换之前破坏纹理。在我这样做之前我遇到了内存泄漏问题。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • @JoshBurgess 抱歉,我修复了帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 2018-02-11
    • 1970-01-01
    相关资源
    最近更新 更多