使用 OpenCV VideoCapture (C++) 更新 Texture2D (Unity) 并使用 Sprite Renderer 显示时混淆输出

Confusing output when updating a Texture2D (Unity) with OpenCV VideoCapture (C++) and displaying with Sprite Renderer

背景: 类似问题 我使用了答案中的代码段。但是,它不能解决我的问题。我必须补充一点,我是Unity编程的初学者!

目标: 通过 opencv c++ 脚本接收视频直播,并从 unity 脚本访问它以显示在场景中。

在场景中显示直播的方法: Sprite渲染器。

问题: 查看下面的屏幕截图,网络摄像头输出显示四次并排并带有条纹(它应该显示我在摄像头前面)。 imshow 显示正确的网络摄像头图像。

当前代码:

C++:

...

extern "C" void __declspec(dllexport) Init()
{
    _capture.open(0);
}

extern "C" void __declspec(dllexport) NDVIStreamer(unsigned char* data, int width, int height)
{
    Mat _currentFrame(height, width, CV_8UC4, data);
    _capture >> _currentFrame;
  
    imshow("lennart", _currentFrame);

    memcpy(data, _currentFrame.data, _currentFrame.total() * _currentFrame.elemSize());

    
}

注意: 将数据指针分配给 _currentFrame 并没有改变任何东西——从我的角度来看——这应该已经完成​​了工作。它没有。

C#:

...

[RequireComponent(typeof(SpriteRenderer))]
public class SpriteMaker : MonoBehaviour
{
    SpriteRenderer rend;

    [DllImport("NDVIstreamer_dll2")]
    private static extern void NDVIStreamer(IntPtr data, int width, int height);

    [DllImport("NDVIstreamer_dll2")]
    private static extern void Init();

    private Texture2D tex;
    private Color32[] pixel32;

    private GCHandle pixelHandle;
    private IntPtr pixelPtr;
    
    void Start()
    {
        rend = GetComponent<SpriteRenderer>();

        tex = new Texture2D(640, 240, TextureFormat.RGBA32, false);
        pixel32 = tex.GetPixels32();
        //Pin pixel32 array
        pixelHandle = GCHandle.Alloc(pixel32, GCHandleType.Pinned);
        //Get the pinned address
        pixelPtr = pixelHandle.AddrOfPinnedObject();

        Init();

        MatToTexture2D();

        //create a sprite from that texture
        Sprite newSprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.one * 0.5f);
        rend.sprite = newSprite;

        pixelHandle.Free();
    }

    void MatToTexture2D()
    {
        NDVIStreamer(pixelPtr, tex.width, tex.height);

        tex.SetPixels32(pixel32);
        tex.Apply();
    }
}

添加此代码即可完成工作(代码取自程序员):

    Mat resizedMat(height, width, _currentFrame.type());
    resize(_currentFrame, resizedMat, resizedMat.size());

    Mat argb_img;
    cvtColor(resizedMat, argb_img, COLOR_RGB2BGRA);
    vector<Mat> bgra;
    split(argb_img, bgra);
    swap(bgra[0], bgra[3]);
    swap(bgra[1], bgra[2]);

    flip(argb_img, argb_img, -1);