i have a unity C# script that instantiates a Color32[] array to pass the pointer to a C++ method that sits in a DLL file. Within the C++ script, the pointer links the Color32[] array to a cv::Mat object that gets instantiated. Also within the C++ script, i retrieve a videostream and put it inside the cv::Mat object and image process it. After that within Unity, I assign the updated Color32[] array to a Texture2D and try to display it using a Sprite Renderer.
ISSUE: From Unity side the Color32[] seems to be empty (also when i put the code into the update() hook definition of the C# script). From C++ side the cv::Mat object holds the correctly processed image with multiple colors. (In case you wonder i reduced the used if-cases for clarity here). A helper method showed that there is only 1 color within the Color32[] after processing looking from c#.
For the Unity and C++ interaction I used these two example projects: by thomas and by amin.
I fear there could be an issue regarding data handling between managed and unmanaged execution which is why i ask for help.
Unity script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
[RequireComponent(typeof(SpriteRenderer))]
public class SpriteMaker : MonoBehaviour
{
SpriteRenderer rend;
private Color32[] rawImage;
internal static class OpenCVInterop
{
[DllImport("ImageProcessor_dll")]
internal static extern void Init();
[DllImport("ImageProcessor_dll")]
internal static extern void ImageProcessing(ref Color32[] rawImage);
}
void Start()
{
OpenCVInterop.Init();
rawImage = new Color32[640 * 240];
OpenCVInterop.ImageProcessing(ref rawImage);
Texture2D tex = new Texture2D(640, 240);
tex.SetPixels32(rawImage);
tex.Apply();
rend = GetComponent<SpriteRenderer>();
Sprite newSprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.one * 0.5f);
rend.sprite = newSprite;
}
}
C++ script:
#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
using namespace std;
VideoCapture _capture;
struct Color32
{
uchar red;
uchar green;
uchar blue;
uchar alpha;
};
extern "C" void __declspec(dllexport) __stdcall Init()
{
//implement size handoff for more dynamic
_capture.open(0);
if (_capture.isOpened())
{
std::cout << "VideoCapture is opened" << std::endl;
}
}
extern "C" void __declspec(dllexport) __stdcall ImageProcessing(Color32 **rawImage_Inbound)
{
Mat rawImage(640,240,CV_8UC4,*rawImage_Inbound);
// for debugging -> shows black image
imshow("frame", rawImage);
_capture >> rawImage;
for (int y = 0; y < rawImage.rows; y++)
{
for (int x = 0; x < rawImage.cols; x++)
{
Vec3b& color = rawImage.at<Vec3b>(Point(x, y));
float color0_int = color[0];
float color2_int = color[2];
float ID = (color2_int - color0_int) / (color2_int + color0_int);
if (ID >= -1 && ID < 0)
{
color[0] = 128;
color[1] = 128;
color[2] = 128;
}
else
{
color[0] = 255;
color[1] = 0;
color[2] = 0;
}
rawImage.at<Vec3b>(Point(x, y)) = color;
}
}
// for debugging -> shows processed image
imshow("frame", rawImage);
}