Hi guys !
I'd like to use some OpenCV Tracker's inside a Unity Project. To do so, I created a .dll file that I imported inside my unity project.
Here is my code to create the DLL :
cv::Ptr<cv::TrackerKCF> Tracker;
cv::Rect2d roi;
// To use image date from Unity
struct Color32
{
uchar r;
uchar g;
uchar b;
uchar a;
};
// To pass ROI's position information beetwen c# and c++
struct Square
{
Square(int x, int y, int width, int height) : X(x), Y(y), Width(width), Height(height) {}
int X, Y, Width, Height;
};
extern "C" bool __declspec(dllexport) __stdcall InitTracker(Color32* frameData, int cameraWidth, int cameraHeight, Square & square)
{
Tracker = cv::TrackerKCF::create();
cv::Mat frame(cameraHeight, cameraWidth, CV_8UC4, frameData);
roi = selectROI("Selection", frame);
square = Square(roi.x, roi.y, roi.width, roi.height);
cv::rectangle(frame, roi, cv::Scalar(0, 0, 255));
cv::imshow("Init", frame);
// return true if the init is OK, false otherwise
return Tracker->init(frame, roi);
}
extern "C" bool __declspec(dllexport) __stdcall UpdateTracker(Color32* frameData, int cameraWidth, int cameraHeight, Square & square)
{
cv::Mat frame(cameraHeight, cameraWidth, CV_8UC4, frameData);
bool success = Tracker->update(frame, roi);
cv::rectangle(frame, roi, cv::Scalar(0, 0, 255));
cv::imshow("Uptade", frame);
square = Square(roi.x, roi.y, roi.width, roi.height);
return success;
}
extern "C" void __declspec(dllexport) __stdcall Close()
{
cv::destroyAllWindows();
}
And here is my c# script :
using System;
using System.Runtime.InteropServices;
using Uk.Org.Adcock.Parallel;
using UnityEngine;
// Define the structure to be sequential and with the correct byte size (4 ints = 4 bytes * 4 = 16 bytes)
[StructLayout(LayoutKind.Sequential, Size = 16)]
public struct CvSquare
{
public int X, Y, Width, Height;
public CvSquare(int x, int y, int width, int height) : this()
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
}
// To import the DLL's methods
internal static class TrackingCpp
{
[DllImport("TrackingCppToDLL")]
internal static extern void Close();
[DllImport("TrackingCppToDLL")]
internal static extern bool InitTracker(Color32[] frameData, int cameraWidth, int cameraHeight, ref CvSquare square);
[DllImport("TrackingCppToDLL")]
internal static extern bool UpdateTracker(Color32[] frameData, int cameraWidth, int cameraHeight, ref CvSquare square);
}
public class TrackingFromDLL : MonoBehaviour
{
private Color32[] pixels32;
private WebCamTexture _webcamTexture;
private const int imWidth = 640;
private const int imHeight = 480;
private CvSquare square;
void Start()
{
// initialized the webcam texture
WebCamDevice[] devices = WebCamTexture.devices;
_webcamTexture = new WebCamTexture(devices[0].name, imWidth, imHeight);
// Play the video source
_webcamTexture.Play();
}
void Update()
{
pixels32 = _webcamTexture.GetPixels32();
int nbPixel = pixels32.Length;
Color32[] reversePixels32 = new Color32[nbPixel];
Parallel.For(0, imHeight, i =>
{
for (int j = 0; j < imWidth; ++j)
{
// OpenCV's pixel (0,0) is the top-left pixel
int newPos = nbPixel - (i + 1) * imWidth + j;
reversePixels32[newPos] = pixels32[i * imWidth + j];
// OpenCV prefers BGRA instead of RBGA
byte tmp = reversePixels32[newPos].b;
reversePixels32[newPos].b = reversePixels32[newPos].r;
reversePixels32[newPos].r = tmp;
}
});
if (!isInitDone)
isInitDone = TrackingCpp.InitTracker(reversePixels32, imWidth, imHeight, ref square);
else
isUptadeSuccess = TrackingCpp.UpdateTracker(reversePixels32, imWidth, imHeight, ref square);
}
private void OnDestroy()
{
TrackingCpp.Close();
}
}
After that, I will use the CvSquare informations for some things in Unity and so far, everything is working fine but my project is crashing when using the method 'TrackingCpp.UpdateTracker' and more specifically the line 'bool success = Tracker->update(frame, roi);'
If I do the same but by using only cpp, I don't have any problems and the tracking is quite efficient but right now, I need to use it inside a Unity Project...
Anyone has any clue about how I can fix thoses crashes ? I'm also open to any suggestions / improvments !
Thanks !
Julien