背景:在C#项目实践中,对与图像处理采用opencv优选的方案有两种,EMGU.CV和OpenCVSharp。
以下是两个的比较:
默认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
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、关键算法等。
整体工程量比较大,后续更新。