Как я могу использовать библиотеки C# в проект с использованием OpenCV++ с GUI VB.NET ?


Я разработал приложение, написанное на неуправляемом C++, которое использует OpenCV и до сих пор просто использует встроенный highgui lib для отображения результатов.

Вместе с VB.net разработчик теперь я хотел бы упаковать его в продукт, подходящий для продажи.

Два усовершенствования, которые я решил сделать, это добавить графический интерфейс, а во-вторых улучшить модуль распознавания лиц, заменив его решением 3rd party.

Проблемы в том, что 3rd party SDK только имеет C# API, и, очевидно, другой программист хотел бы реализовать интерфейс в VB.

Я мог бы перенести свой код на C# и использовать EmguCV, убивая двух зайцев одним выстрелом, однако база кода довольно велика, и я не думаю, что у меня есть время, но это вариант.

Что я хотел бы знать, так это куда идти отсюда. Я портирую на MC++, использую смешанные нативные и управляемые сборки, сам пишу GUI в Qt и т. д.

Также как бы я отображал поток Iplimage в .NET Контроль WinForm?

3 2

3 ответа:

Возможно ли в вашей ситуации реализовать какой-то простой, высокоуровневый API вашего собственного кода OpenCV, чтобы он легко взаимодействовал с C# с помощью PInvoke? У меня была похожая проблема в прошлом, то, что я сделал, было упаковать мой родной код примерно с 15 функциями, которые были легко доступны из C# (используя PInvoke). Я не знаю, возможно ли это сделать легко в вашем случае, если нет, вы можете попробовать кодировать несколько классов в MC++ и попытаться скомпилировать свой код OpenCV с помощью MC++, в конце концов, основное использование od C++/CLI-это создание моста между нативным c++ и управляемыми языками (хотя лично я все еще предпочитаю делать хороший нативный API и PInvoke его из C#.

Что касается IplImage, если вы используете EmguCV, есть свойство .Bitmap, которое дает вам управляемый класс System.Drawing.Bitmap, который можно использовать, не копируя базовые буферы (я отрисовывал 5 живых потоков с камер в моем приложении, и это работало довольно хорошо). Если, с другой стороны, вы хотите сделать это вручную, без использования EmguCV, я призываю вас чтобы проверить их исходный код и посмотреть, как они реализуют эту функциональность и делают это самостоятельно (в основном, вам нужно захватить указатель на память и получить несколько свойств, таких как шаг изображения, ширина, высота и создать класс Bitmap самостоятельно с их помощью).

Edit: я нашел код, который использовал для рендеринга изображения, обработанного в OpenCV:

C++ код:

void __stdcall GetRectifiedImage(Calibration* calib, int left, int** dataPtr, int* stride)
{
    CvMat* mat = ((CalibrationImpl*)calib)->imagesRectified[left > 0 ? 0 : 1];

    *dataPtr = mat->data.i;
    *stride = mat->step;
}

Этот код в основном заполняет dataPtr и stride (предполагая, что ширина и высота известны)

C# Пинвоук:

[DllImport("Stereo.dll")]
public static extern void GetRectifiedImage(IntPtr calib, int left, out IntPtr data, out int stride);

Использование C# (с EmguCV):

StereoNative.GetDepthImage(calib, out ptr, out stride);
pictureBox5.Image = new Image<Gray, byte>(640, 480, stride, ptr).Bitmap;
Без Emgu вам нужно было бы увидеть, как они реализуют свойство .Bitmap, и просто сделать это самостоятельно, чтобы создать свой собственный объект Bitmap.

Я использовал EmguCV, и это хорошо работает. Я также поместил свой код OpenCV C++ в управляемую библиотеку DLL, и это тоже хорошо работает. Вы также можете иметь исходный код .NET и приемник для COM-интерфейсов, которые можно вызывать на стороне C++.

Хотя я решил портировать на MC++ для полноты и потому, что я уже провел исследование, есть два других решения, которые я мог бы использовать.

Во-первых, я мог бы вызвать компонент C# из собственного C++ путемвстраивания mono runtime в проект. Выглядело интересно, и я буду исследовать его для использования в других проектах.

Или я мог бы использоватьCLR Hosting API . Выглядело больше Хака, чем первое, но выполнимо.

Наконец для все, кто заинтересован в поиске информации, необходимой для переноса C++ в его управляемую форму, смотрите эту ссылку. Похоже, родной язык C++ - это единственный язык, который может быть скомпилирован как управляемый без изменения кода. Поправьте меня, если я ошибаюсь. EDIT: я ошибаюсь ..