Передача cv :: Mat из C ++ в C # (управляемая)

Я пишу обертку для использования кода C ++ в C #).

У меня есть функция, которая должна вернуть cv::Mat вернуться к C #, но я не могу найти способ передать Mat в C #.

Пример:

Я хотел бы иметь что-то вроде этого:

cv::Mat MyProject::ReturnColorMat()
{
return _colorMat;
}

Я знаю, что C # работает с EmguЕсть ли преобразование между двумя?

Я пытался передать byte array из Mat, и это сработало, но я хотел бы передать Mat сам.

Это вообще возможно?

0

Решение

Вы можете создать COM-интерфейс в C # и создать из него файл .tlb, который можно использовать в C ++.
Таким образом, вы можете использовать тот же интерфейс для ссылки на управляемый объект.

C #

  [ComVisible(true)]

[Guid("12345678-3914-41F0-BB26-122986A93788")]

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

public interface IMat
{...}

public class ManagedMat : IMat
{...}

[DllImport("cppProjectname.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern int call2Cpp(IMat obj);

C ++

#import "projectname.tlb" no_registry raw_interfaces_only

// use IMat to access the ManagedMat object
extern "C"  int __declspec(dllexport) call2Cpp( IMat obj )
{...}
0

Другие решения

Собственные и управляемые структуры по-разному размещаются в памяти, поэтому для успешного прохождения структур через управляемую / неуправляемую границу требуются дополнительные шаги для сохранения целостности данных. (посмотреть здесь)

Можно преобразовать cv :: Mat в Bitmap на стороне C ++, а затем получить Bitmap в C #, используя PInvoke.
На стороне C ++ вы можете использовать эту функцию, взятую из Вот

CBitmap* IplImageToCBitmap(IplImage* img)
{
CDC dc;
CDC memDC;

if (!dc.CreateDC("DISPLAY", NULL, NULL, NULL))
return NULL;

if (!memDC.CreateCompatibleDC(&dc))
return NULL;

CBitmap* bmp = new CBitmap();
CBitmap* pOldBitmap;

bmp->CreateCompatibleBitmap(&dc, img->width, img->height);
pOldBitmap = memDC.SelectObject(bmp);

CvvImage cvImage; // you will need OpenCV_2.2.0- to use CvvImage
cvImage.CopyOf(img);
cvImage.Show(memDC.m_hDC, 0, 0, img->width, img->height, 0, 0);
cvImage.Destroy();

memDC.SelectObject(pOldBitmap);
memDC.DeleteDC();
dc.DeleteDC();

return bmp;
}

а затем оберните вашу функцию таким образом

extern "C" __declspec( dllexport) HRESULT WrappedFunction(HBITMAP * hBitmap);

HRESULT WrappedFunction(/*[out]*/ HBITMAP * hBitmap)
{
cv::Mat aMat = YourFunction();

CBitmap *bmp = IplImageToCBitmap((IplImage*) &aMat);

*hBitmap = (HBITMAP)bmp->Detach();

return S_OK;
}

Затем на стороне C # вы можете сделать:

IntPtr ret;
WrappedFunction( out ret );
Bitmap b = Image.FromHbitmap( ret );
0

По вопросам рекламы [email protected]