最近使用EmguCV,一直疑惑个问题EmguCV到底和OpenCV有什么关联。看我来扒一扒。
1.下载EmguCV的源码下来,先查找函数接口。
我们找到文件夹 Emgu.CV.Extern 发现里面全是C++ 代码。这个应该就是CVextern.dll的源代码。
随便打开一个*.h 看下。我这里打开core文件夹下的mat_c.h文件。可以看到头文件中内容如下:
#pragma once
#ifndef EMGU_MAT_C_H
#define EMGU_MAT_C_H
#include "opencv2/core/core_c.h" //这是很熟悉的Opencv的头文件
#include "opencv2/core/ocl.hpp" //这是很熟悉的Opencv的头文件
#include "emgu_c.h"
typedef uchar* (CV_CDECL *MatAllocateCallback)(int depthType, int channel, int totalInBytes, void* allocateDataActionPtr);
typedef void (CV_CDECL *MatDeallocateCallback)(void* freeDataActionPtr);
CVAPI(cv::MatAllocator*) emguMatAllocatorCreate(MatAllocateCallback allocator, MatDeallocateCallback deallocator, void* allocateDataActionPtr, void* freeDataActionPtr);
CVAPI(void) cveMatAllocatorRelease(cv::MatAllocator** allocator);
CVAPI(cv::Mat*) cveMatCreate();
再看上面CVAPI 在opencv中的意义:
#define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL
CV_EXTERN_C 的宏定义是#define CV_EXTERN_C extern "C"
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的
CV_EXPORTS 的宏定义为# define CV_EXPORTS __declspec(dllexport)
可见CV_EXPORTS暂时无实质性内容,只是一个预留宏定义,是为了OpenCV在编程上的可扩展性预留的
rettype是宏定义的参数了,这里放具体的类型,表示函数的返回类型!
CV_CDECL的宏定义是#define CV_CDECL __cdecl __cdecl是VC的关键词。
看过后是不是很熟悉,是DLL的导出函数格式。再看些头文件均是如此导出的,也就是opencv中的函数均通过这种方式在cvextern.dll中导出。
2.再看emgu中是怎么调用opencv的函数的。
我在文件夹Emgu.cv下的Pinvoke下CvInvokeCore.cs下找到下面的代码
[DllImport(ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention, EntryPoint = "cveReshape")]
public static extern IntPtr cvReshape(
IntPtr arr,
IntPtr header,
int newCn,
int newRows);
ExternLibrary的内容是“cvextern” CallingConvention =Cdecl = 2, 被调用方清理堆栈。这是使用平台 invoke 调用非托管函数的默认约定。
这是调用cvextern.dll的格式,查看下来,cs代码中有大量的这类代码,将opencv中函数引用过来。所以在我们调用某些函数的时候均使用CVinvoke.XXXX来调用。如果这里没有,我们可以扩展进去。只要上面的CVAPI有导出,。
3.有个疑问3.1版本,如何实现调用opencv,而不需要加载opencv的库。
4.Emgu的跨平台特性看似使用了mono。
总结:Emgu的底层基础是opencv,然后在这基础上建立起了新的庞大的大厦。
以上只是初步探秘,随着深入可能有些看法会转变,也请高手共同探讨。后面找到了官网的Emgu的结构图,我们可以看的更清楚。也验证了我们从源代码推测的部分结论。