EmguCV и OpenCV – Вызов в C# функций Dll C++ / EmguCV / Recog.ru - Распознавание образов для программистов


EmguCV и OpenCV – Вызов в C# функций Dll C++

Иногда возникает необходимость использовать и EmguCV проект и OpenCV совместно. Например, у вас есть распространяемая библиотека связанная с OpenCV, а разработчик пишет программу на C# с EmguCV.
Пусть у нас есть C++ библиотека (возьмем распознавание DataMatrix капельных кодов) с определенной выходной функцией:
#pragma once

#include "opencv2/core/core_c.h"
#include "opencv2/imgproc/imgproc_c.h"

int 
#ifdef WIN32
__stdcall 
#endif
DataMatrixDripReader( int* Img_, char* out_buf, int size_buf )
{
	IplImage* Img = (IplImage*) Img_;
	…

Рассмотрим процесс подключения данной функции в C# с EmguCV. Для того, чтобы подключить библиотеку нам понадобится использовать:
using System.Runtime.InteropServices;

Далее подключаем библиотеку BlobDM64.dll (распознавание капельных DataMatrix) следующим образом:
namespace …Ваш проект…
{
   public partial class Form1 : Form
   {
      [DllImport("BlobDM64.dll", CallingConvention = CallingConvention.StdCall)]
       unsafe public static extern int DataMatrixDripReader(IntPtr Img, StringBuilder buf, int size);

Пусть у вас есть некоторая функция получения фреймов (можете посмотреть примеры CameraCapture и MotionDetect в EmguCV):
private void ProcessFrame(object sender, EventArgs e)
{
         using (Image<Bgr, Byte> image = _capture.RetrieveBgrFrame())
         …
}

Если мы собираемся вызывать функцию DataMatrixDripReader, то надо добавить unsafe
— небезопасный режим, поскольку в этой функции будет обращение к памяти.
unsafe private void ProcessFrame(object sender, EventArgs e)
{
         using (Image<Bgr, Byte> image = _capture.RetrieveBgrFrame())
         … Что-то делаем с image
}

Для вызова внешней функции выполняем следующее:
IntPtr image2 = CvInvoke.cvCreateImage(new System.Drawing.Size( image.Width, image.Height), IPL_DEPTH.IPL_DEPTH_8U, 3);            
CvInvoke.cvCopy( image.Ptr, image2, IntPtr.Zero);
StringBuilder buffer = new StringBuilder (2000);         
int res = DataMatrixDripReaderCSharp( image2, buffer, 2000 );
if (res == 0)
{
       // Выдача измененного результата на экран
       CvInvoke.cvCopy(image2, motionImage.Ptr, IntPtr.Zero);
}
CvInvoke.cvReleaseImage( ref image2); // Не забываем освобождать память


Главное не забывать, что при подобной работе память нужно освобождать самостоятельно.
  • 0
  • 11 августа 2013, 13:23
  • vidikon

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.