2016-04-21 13 views
2

Ich arbeite gerade an meiner Diplomarbeit (MSc Computer Science), die ein Augmented Reality Projekt mit OpenCV C++ in Unity3D integriert ist (für den Rendering-Teil). Um OpenCV mit Unity3D zu integrieren, habe ich den OpenCV (C++) Code als DLL exportiert und dann importiere ich diese DLL in Unity3D, um auf die Methoden der DLL zuzugreifen. Außerdem hat mir die Universität etwas Geld gegeben, um OpenCV für Unity zu kaufen ist in C# mit OpenCV für Java implementiert) und ich verwende es auch in Unity3D. Das Problem ist, dass es SURF Feature Extractor nicht unterstützt und deshalb implementiere ich meinen C++ Code nicht direkt in C# mit diesem Asset.Weitergabe von Daten von Unity3D an C++ dll und umgekehrt

Also ich möchte ein Frame (Mat) von Unity3D (C#) an die C++ - DLL übergeben, dann einige Berechnungen und danach einige Mat-Objekte, zum Beispiel die Rotationsmatrix, Übersetzungsvektor und die Kamera-Pose zurückgeben. Das Wichtigste ist, dass ich nicht weiß, wie man den Mat-Frame von Unity3D an die C++ - DLL übergibt.

Kann mir jemand erklären, wie man das erreicht und können Sie auch einen Beispielcode veröffentlichen?

EDIT: Der Unity3D Vermögenswert, kann ich bin mit hier: OpenCV for Unity3D

+0

ja, ich bin mit diesen Vermögenswert Sie erwähnt. Ich werde meinen Beitrag bearbeiten und einfügen. Ich dachte, ich dürfe keine externen Links posten. Danke – user43053534

+0

Das Traurige ist, dass SIFT und SURF nicht auf diesem Asset implementiert sind. Deshalb habe ich meinen Code in C++ implementiert, wo SIFT und SURF verfügbar sind, und dann importiere ich die DLL in Unity3D. – user43053534

+0

Ja, ich bin in der Lage, die C++ DLL mit Unity zu integrieren, ich kann einfache Methoden wie das Hinzufügen von zwei Zahlen aufrufen Ergebnis, aber der Hauptpunkt der Frage war, wie ein Bild (Mat-Typ) von Unity an die C++ - DLL übergeben werden, dann wird der Algorithmus einige Berechnungen durchführen und sie zurück an Unity. – user43053534

Antwort

1

ich die Lösung nur gefunden (ohh yeahhhhhhhh) :)

Zunächst einmal musste ich mein C# konvertieren Mat (Rahmen) in ein Array von Bytes. Dann habe ich einen Zeiger erstellt, um auf das Array der Byteadresse zu zeigen (was die Bilddaten sind). Danach habe ich die C++ - DLL-Methode aufgerufen und den Zeiger als Argument übergeben (und auch die Breite und Höhe des Bildes). Schließlich habe ich in der C++ - DLL die C++ - Matte mit dem Array von Bytes aus C# rekonstruiert.

-Code in Unity3D (C#):

 //frame is the C# Mat and byte_array our array of byes 

     //to initialize the size of our byte array (image pixels * channels) 
     byte_array= new byte[frame.cols() * frame.rows() * frame.channels()]; 
     //copy the frame data to our array 
     Utils.copyFromMat (frame,byte_array); 
     //initialize a pointer with the apropriate size (array size) 
     IntPtr pointer = Marshal.AllocHGlobal(byte_array.Length); 
     Marshal.Copy (byte_array, 0, pointer , byte_array.Length); 
     //here i call the C++ method (I imported a C++ dll) 
     myCplusplusMethod(pointer ,frame.height(),frame.width()); 
     //free the pointer 
     Marshal.FreeHGlobal(pointer); 

Jetzt, um das Bild in C++ unter Verwendung der übergebenen Daten von C# zu rekonstruieren:

void myCplusplusMethod(unsigned char* data,int height,int width){ 
    //btw you have to get the correct type. In my situation I use debug from C# and I found out that my image is CV_8UC3 type. 
    Mat constructed= Mat(height, width, CV_8UC3, data); 
    //..do whatever using the image.. (calculations , etc).. 
} 
+0

Gute Arbeit. Gut, um es hier zu veröffentlichen. Alter, das ist, was ich vorgeschlagen habe, ein Byte-Array zu verwenden. Sie können Ihre eigene Antwort "ankreuzen", es ist cool. – Fattie