2016-04-21 4 views
2

В настоящее время я работаю над своей диссертацией (MSc Computer Science), которая представляет собой проект дополненной реальности с использованием OpenCV C++, интегрированного с Unity3D (для части рендеринга). Чтобы интегрировать OpenCV с Unity3D, я экспортировал код OpenCV (C++) в качестве dll, а затем импортирую эту DLL в Unity3D для доступа к методам dll и т. Д. Кроме того, университет дал мне немного денег, чтобы купить OpenCV для Unity (это реализован в C# с использованием OpenCV для Java), и я использую его также в Unity3D. Проблема в том, что он не поддерживает средство выделения SURF, поэтому я не внедряю свой код на C++ прямо в C#, используя этот актив.Передача данных из dll Unity3D в C++ и обратно

Итак, я хочу передать кадр (Mat) из Unity3D (C#) в dll C++, затем выполнить некоторые вычисления и после этого вернуть некоторые объекты Mat, например, матрицу поворота, вектор трансляции и положение камеры. Самое главное, что я не знаю, как передать рамку Mat из Unity3D в dll C++.

Может ли кто-нибудь объяснить мне, как достичь этого, а также вы можете отправить образец кода?

EDIT: Актив Unity3D, который я использую, можно найти здесь: OpenCV for Unity3D

+0

да я использую этот актив вы упомянули. Я отредактирую свой пост и включу его. Я думал, что мне не разрешено публиковать внешние ссылки. спасибо – user43053534

+0

Печально то, что SIFT и SURF не реализованы в этом активе. Вот почему я реализовал свой код на C++, где доступны SIFT и SURF, а затем я импортирую dll в Unity3D – user43053534

+0

Да, я могу интегрировать dll C++ с Unity, я могу назвать простые методы, такие как добавление двух чисел и возврат результат, но основной вопрос заключался в том, как передать изображение (тип Mat) из Unity в dll C++, тогда алгоритм выполнит некоторые вычисления и вернет их обратно в Unity. – user43053534

ответ

1

Я только что нашел решение (ооо yeahhhhhhhh) :)

Прежде всего, мне нужно, чтобы преобразовать мой C# Mat (frame) в массив байтов. Затем я создал указатель, чтобы указать на массив адресов байтов (который является данными изображения). После этого я вывел метод dll C++ и передал указатель в качестве аргумента (а также ширину и высоту изображения). Наконец, в C++ dll я восстановил C++ Mat, используя массив байтов из C#.

Код в 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); 

Теперь для того, чтобы восстановить изображение в C++, используя переданные данные из C#:

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

Хорошая работа. Хорошо для размещения здесь. Чувак, это то, что я предложил использовать массив байтов. Вы можете «пометить» свой собственный ответ, это круто. – Fattie