赞
踩
环境: windows10
这种方式缺点:
1. 只能编译vcpkg支持的最新版本的oepncv。
到目前为止(20200210),支持的opencv最新版是4.1.1
2. 需要特定参数的时候,也不是很方便设置。
优点:
一个命令就编译到位!!!
第一步,安装vcpkg,解压到任意位置
第二步,编译vcpkg,打开cmd, 输入powershell,切换到vcpkg的解压位置,输入命令:.bootstrap-vcpkg.bat
第三步,编译opencv,输入以下命令:
.vcpkg install opencv4:x86-windows-static (表示编译win32版本的静态库) 或者
.vcpkg install opencv4:x64-windows (表示编译x64版本的动态库)
./vcpkg install opencv[contrib]:x86-windows-static (表示编译带有contrib功能的x86静态库)
./vcpkg install opencv[cuda]:x64-windows (表示编译带有cuda功能的x64动态库)
……
注意:上面出现了左斜杠和右斜杠,我记得我在用的时候都是对的,也有可能是我自己记错了。在实际操作的时候可以都试试,哪个对就用哪个吧。
第四步,导出opencv库:./vcpkg export opencv4:x64-windows --raw
这时你会在同目录下看到导出的库
这里注意,我编译的是opencv4.2.0,带有cuda功能的版本,需要配置cudnn大于7.5,相应的cuda也要升级。我自己安装的是cuda10.1.243+cudnn7.6.4.38。因为用到了dnn,所以编译的时候考虑到了dnn-cpu的加速,需要安装openvino。这些在开始编译之前需要配置好。
第一步,打开cmake-gui,分别输入source和build路径;
第二步,第一次configure,需要确认编译器,我用了vs2019,需要x86的选择win32,需要x64的选择x64
第三步,配置动态库,cuda,opencv_contrib等。
(我编译的动态库调用的时候没有出现下列警告或异常,但我编译的静态库调用的时候出现:[ WARN:0] global E:opencv-4.2.0sourcesmodulesdnnsrcop_inf_engine.cpp (721)
cv::dnn::InfEngineBackendNet::initPlugin DNN-IE: Can't load extension plugin (extra layers for some networks). Specify path via OPENCV_DNN_IE_EXTRA_PLUGIN_PATH parameter)
(参考 https://github.com/opencv/dldt/issues/248)
(原因:cpu_extension supports only SSE4 and AVX2 levels and OpenCV looks for corresponding plugins only if it has this optimization level enabled)
中间出现一些无法下载的红字时,可以打开build文件夹下的CMakeDownloadLog.txt,拷贝cmake-gui中的无法下载的内容在txt文件中搜索,找到下载地址,进行手动下载;放置的位置在txt文件的相应位置也有说明。
第四步,configure,若出现" CUDA backend for DNN module requires CC 5.3 or higher. Please remove unsupported architectures from CUDA_ARCH_BIN option.",这个错误,搜索CUDA_ARCH_BIN,将小于5.3的项都去掉,可以选择手动加上5.3
若遇到“CMake Warning at cmake/OpenCVDetectInferenceEngine.cmake:97 (message): InferenceEngine version have not been set, 2019R3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors. Call Stack (most recent call first): CMakeLists.txt:733 (include)”,搜索INF_ENGINE_RELEASE,改成自己的版本,我这里用的是2020.1版本,所以改成2020010000
注意,我再次编译动态库时,这个 INF_ENGINE_RELEASE相关的错误并没有提醒,但是版本号是2019030000,与我的openvino版本号并不一致。第一次编译时并没有注意到这个问题,导致imshow函数调用时异常,dnn::Net作为全局变量在封装动态库后调用像“进入死循环”。所以我再次重新编译,企图通过修改这个选项改善上面两个bug。 经过测试,只修复了“imshow函数调用时异常”。
备注:NVIDIA官网https://developer.nvidia.com/cuda-gpus,可以查询到目前所有的GPU算力为7.5 7.0 6.1 5.2 5.0 3.5 3.0 2.1 2.0。
我在编译的时候设置的算力有:5.3 6.1 7.0 7.5
CUDA-Enabled GeForce and TITAN Products: 对应的GPU型号台式机必须大于等于GeForce GTX 1050 笔记本必须大于等于GeForce GTX 1060 其他支持CUDA的GPU系列可以在上述网址查询。
第五步,configure没错误,可以选择设置CUDA_FAST_MATH,然后generate,产生opencv.sln。遇到错误“CMake Warning at cmake/OpenCVGenSetupVars.cmake:54 (message): CONFIGURATION IS NOT SUPPORTED: validate setupvars script in install directory Call Stack (most recent call first): CMakeLists.txt:947 (include)” 直接忽略即可
第六步,打开opencv.sln工程,选择release-x64(这里需要与第一次configure时的选择一致),解决方案下的CMakeTargets-ALL_BUILD右击生成
第七步,解决方案下的CMakeTargets-INSTALL右击生成。这时会在sln的同路径下的install文件夹中生成相应的动态库。
第一步,打开cmake-gui,分别输入source和build路径;
第二步,第一次configure,需要确认编译器,我用了vs2019,需要x86的选择win32,需要x64的选择x64
第三步,配置静态库,opencv_contrib等。
中间出现一些无法下载的红字时,可以打开build文件夹下的CMakeDownloadLog.txt,拷贝cmake-gui中的无法下载的内容在txt文件中搜索,找到下载地址,进行手动下载;放置的位置在txt文件的相应位置也有说明。
第四步,configure,若遇到“CMake Warning at cmake/OpenCVDetectInferenceEngine.cmake:97 (message):
InferenceEngine version have not been set, 2019R3 will be used by default.
Set INF_ENGINE_RELEASE variable if you experience build errors.
Call Stack (most recent call first):
CMakeLists.txt:733 (include)”,搜索INF_ENGINE_RELEASE,改成自己的版本,我这里用的是2020.1版本,所以改成2020010000
第五步,configure没错误,可以generate,产生opencv.sln。遇到错误“
CMake Warning at cmake/OpenCVGenSetupVars.cmake:54 (message):
CONFIGURATION IS NOT SUPPORTED: validate setupvars script in install directory
Call Stack (most recent call first):
CMakeLists.txt:947 (include)” 直接忽略即可
第六步,打开opencv.sln工程,选择release-x64(这里需要与第一次configure时的选择一致),解决方案下的CMakeTargets-ALL_BUILD右击生成
第七步,解决方案下的CMakeTargets-INSTALL右击生成。这时会在sln的同路径下的install文件夹中生成相应的静态库。
最后,可以将编译的库放在一个文件夹下:
细心的网友可以看到上图中有两个文件夹:cuda和engine,这两个文件夹分别是cuda的lib和bin的部分内容,以及openvino中推理部分的bin和lib的部分内容。因为在外部调用编译好的库文件时,需要设置链接器依赖项,动态库的话需要将dll放置到应用程序的同级目录下才能运行。否则会提示缺少dll或者无法识别的外部符号。
opencv在vs2019上的配置:
include:
E:opencv-4.2.0installinclude
RELEASE:
static runtime=多线程(/MT)
dynamic runtime=多线程(/MD)
DEBUG
static runtime=多线程(/MTd)
dynamic runtime=多线程(/MDd)
static lib:
E:opencv-4.2.0installx64vc16staticlib
E:opencv-4.2.0installx64vc16cuda
E:opencv-4.2.0installx64vc16engine
ade.lib
IlmImf.lib
ippicvmt.lib
ippiw.lib
ittnotify.lib
libjasper.lib
libjpeg-turbo.lib
libpng.lib
libprotobuf.lib
libtiff.lib
libwebp.lib
opencv_img_hash420.lib
opencv_world420.lib
quirc.lib
zlib.lib
cudart.lib
cudnn.lib
cublas.lib
inference_engine.lib
inference_engine_nn_builder.lib
dynamic lib:
E:opencv-4.2.0installx64vc16lib
E:opencv-4.2.0installx64vc16cuda
E:opencv-4.2.0installx64vc16engine
opencv_img_hash420.lib
opencv_world420.lib
cudart.lib
cudnn.lib
cublas.lib
inference_engine.lib
inference_engine_nn_builder.lib
运行程序提示缺少dll时,自行添加cuda或openvino相应部分的dll到exe路径下。
测试代码:
1. 基本功能
- Mat img = imread("lena.jpg",1);
- imshow("show window",img);
- Waitkey();
2. dnn功能-cpu加速版本
- #include "opencv2/opencv.hpp"
- #include <opencv2/dnn.hpp>
-
- using namespace std;
- using namespace cv;
- using namespace cv::dnn;
-
- Net tfnet;
- bool Init_vino(const char* training_path)
- {
- tfnet = readNetFromTensorflow(training_path); // 我这里用的是tf训练的模型,可以选择其他种类的模型,比如onnx ,对应函数为readNetFromONNX
- tfnet.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE );
- //cpu:DNN_BACKEND_INFERENCE_ENGINE DNN_BACKEND_OPENCV
- //gpu:DNN_BACKEND_CUDA
- tfnet.setPreferableTarget(DNN_TARGET_CPU);
- // cpu:DNN_TARGET_CPU
- // gpu:DNN_TARGET_CUDA
-
- return true;
- }
-
- int main()
- {
- // 模型可以自己在网上下载一些训练好的分类模型进行测试
- // https://github.com/merria28/onnx-models
- bool init_flag = Init_vino("./efficientnetB0/tf_model_efficientnetB0_1130.pb");
- Mat img = imread("testImage.jpg",1);
-
- int64 startTime, time;
- startTime = getTickCount();
-
- img .convertTo(rec_crop, CV_32F);
- img /= 255.0;
-
- int input_width = img.cols;
- int input_height = img.rows;
- int sz[] = { 1, 3, input_width, input_height }; // 1表示单张图片的测试
- Mat blob = Mat(4, sz, CV_32FC1);
-
- Mat channels[3];
- Mat outs;
-
- for (int j = 0; j < 3; j++)
- channels[j] = Mat(rec_crop.rows, rec_crop.cols, CV_32FC1,
- blob.ptr(0, j));
-
- split(rec_crop, channels);
-
- channels[2] = channels[2] - 0.4914;
- channels[2] = channels[2] / 0.2023;
- channels[1] = channels[1] - 0.4822;
- channels[1] = channels[1] / 0.1994;
- channels[0] = channels[0] - 0.4465;
- channels[0] = channels[0] / 0.2010;
-
- tfnet.setInput(blob);
- outs = tfnet.forward();
-
- Mat score_map = Mat(1, 2, CV_32FC1, outs.data); // 2表示分类模型的种类,取决于模型最后一层有几类。
-
- time = getTickCount() - startTime;
- timePerImg = (double)time / getTickFrequency() * 1e3;
- cout << "Total Process time = " << timePerImg << endl;
- return 0;
- }
3. dnn-gpu 测试
在第2点上的初始化部分稍作修改:
- bool Init_vino(const char* training_path)
- {
- tfnet = readNetFromTensorflow(training_path); // 我这里用的是tf训练的模型,可以选择其他种类的模型,比如onnx ,对应函数为readNetFromONNX
- tfnet.setPreferableBackend(DNN_BACKEND_CUDA);
- tfnet.setPreferableTarget(DNN_TARGET_CUDA);
-
- return true;
- }
查看运行时间,可以看到 DNN_BACKEND_OPENCV >
DNN_BACKEND_INFERENCE_ENGINE >
DNN_BACKEND_CUDA
测试结果:
测试方法 --> 91张图像经过efficientnetB0分类,运行时间参考平均时间和波动范围。
查找资料后:
对于第4点,在编译的时候设置CPUBASELINE=SSE4_2可以消除警告,可以参考
https://github.com/opencv/dldt/issues/248github.com对于第5点,GeForce GTX 1050 Ti测试结果不是很理想60+ms per image VS GeForce GTX 1660 Ti = 40+ms per image。 这个时间结果是基于我自己的模型和预处理及后处理的结果。GeForce GTX 1050 Ti结果稍逊,应该是跟GPU型号较弱有关。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。