背景:在C#项目实践中,对与图像处理采用opencv优选的方案有两种,EMGU.CVOpenCVSharp

以下是两个的比较:

默认OpenCVSharp不支持GPU,主因是OpenCV需要根据不同的Cuda版本进行编译,第一耗时长、第二版本多,因此编译不起。

目的:介绍在C#中使用OpenCVSharpGPU的编译过程,解决工程化CPU的性能瓶颈、及机器学习算法结合的时候性能提升问题。

一、准备

GPU电脑准备,需要安装适合版本的cuda 及cudnn。

检测安装成功:

nvcc --version

安装CMacker

cmake --version

安装Visualstudio2022(已安装其它版本也可以)

需要选择c++组件

安装Git

先准备一个基础目录

d:\opencvbuild
--opencv
--opencv_contrib
--opencvcuda
--opencvsharp
--opencvsharpcuda
--test

二、构建OpenCV

下载OpenCV源码

cd d:\opencvbuild\opencv
git clone https://github.com/opencv/opencv

下载opencv_contrib代码,需要与Opencv版本匹配

cd d:\opencvbuild\opencv_contrib
git clone https://github.com/opencv/opencv_contrib

CMake设置

#源目录
d:\opencvbuild\opencv
#目标目录
d:\opencvbuild\opencvcuda
#编译器
vs2022
#点击Config
cuda关键字,勾选所有
ENABLE_FAST_MATH关键字,勾选
modules,设置contrib模块路径:d:\opencvbuild\opencv_contrib\opencv_contrib-xxx\modules
BUILD_opencv_world,可选
OPENCV_ENABLE_NONFREF,可选

点击Configure,等待完成后,点击Generate,再点击Open Project

三、编译OpenCV

通过CMaker打开VS2022,选择Release X64位,编译右侧解决方案

1,右键编译“ALL BUILD”,等一个小时
2,右键编译“INSTALL”

查看编译结果

cd d:\opencvbuild\opencv\opencvcuda\install
dir

四、编译OpenCVSharp

下载OpenCVSharp

cd d:\opencvbuild\opencvsharp
git clone https://github.com/shimat/opencvsharp
#在源码根目录,创建opencv_file文件夹,拷贝已编译文件给opencvsharp
mkdir opencv_files
cd opencv_files
mkdir opencv470_win_x64
xcopy /e /i /y "d:\opencvbuild\opencv\opencvcuda\install\include" "d:\opencvbuild\opencvsharp\opencv_files\opencv470_win_x64"
xcopy /e /i /y "d:\opencvbuild\opencv\opencvcuda\install\x64" "d:\opencvbuild\opencvsharp\opencv_files\opencv470_win_x64"

4.1 编译OpenCvSharpExtern C++工程

修改C++工程文件

记事本打开"opencvsharp\src\OpenCvSharpExtern"目录下“OpenCvSharpExtern.vcxprojOpenCvSharpExtern.vcxproj”文件
以我下载的源码是4.7为准,查找所有470,替换为正确的路径和位置。

VS2022设置工程

右键OpenCvSharpExtern工程,C/C++->预处理->预处理器定义,添加“ENABLED_CUDA”

VS2022编译工程文件

vs2022打开OpenCvSharp.sln
选择Release X64位,右键编译OpenCvSharpExtern工程

问题排查

1,OpenCvSharpExtern工程文件打不开,说明之前的修改c++文件改坏了,从新clone下
2,乱码错误,首先检查是否是X64编译
3,乱码错误,大概率是c++工程->VC++目录->库目录   设置不对

4.2 编译OpenCvSharp C#工程

VS2022设置工程

生成->条件编译符号->所有都加上"ENABLED_CUDA"

项目维护者已经好久不维护Gpu的支持了,编译工程会报大量错误

1,命名空间错误,添加必备的引用
2,DLL引用错误,一般都是因为全局常量DllExtern在NativeMethods下定义的,因此调对命名空间就行
3,需要将OpenCvSharpExtern.dll添加到工程并设置输出为文件。
4,部分缺失的函数可以注释掉

五、测试

添加引用:

OpenCvSharp.dll

拷贝C++扩展到输出目录

OpenCvSharpExtern.dll

拷贝OpencvCuda的Dll到输出目录

opencv460_win_x64\x64\vc17\bin\*.dll

在test目录,创建新的测试程序,需要选择X64 Debug

using OpenCvSharp;
using OpenCvSharp.Cuda;

Console.WriteLine("Hello, World!");
var count = Cv2.GetCudaEnabledDeviceCount();
Console.WriteLine(count);

六、总结

整个编译完整下来可能要一天时间。

OpenCVSharp支持的API有限,只支持:

1,GpuMat

2,设备检测

3,缓存

其余需要自己对应实现,工程量比较大,我正在整理它的扩展,也仅限于我能用到的Capture、关键算法等。

整体工程量比较大,后续更新。

06-21 19:30