从源代码构建支持 CUDA 的 OpenCV
简介
OpenCV 是一个开源的计算机视觉和机器学习软件库,图像算法必备!
编译 OpenCV 一般对相关软件版本都有要求,请谨慎选择版本,本文编译的 OpenCV 版本是 3.4.2。
构建环境
构建步骤
预安装软件
- Visual Studio、CUDA Toolkit、CMake 提前安装好。
- 下载解压 OpenCV 与 opencv_contrib 源代码并解压。
 
运行 CMake
运行 CMake 选择 OpenCV 源代码路径与编译生成路径

选择编译环境
点击 Configure 配置选择编译环境

配置编译内容
点完第一次 Configure 后界面一片红,不用在意,先根据需要配置编译内容
- 勾选 “with_cuda”:支持 CUDA 环境的 OpenCV。
- 勾选 “build_opencv_world”:会把所有的库生成为一个 dll 与 lib,很方便使用,但不建议勾选,如果编译时报错又未完成的编译库,依旧可以生成,但是使用时会报:“无法解析的外部符号”,却又很难找出原因。
- 勾选 “opencv_enable_nonfree”:可以使用具有专利保护的算法。
- 配置 “opencv_extra_modules_path” 为扩展模块的源码路径 “…/opencv_contrib-3.4.2/modules”:可以使用 OpenCV 一些受专利保护算法的扩展模块。
 
生成
点击 Configure 直至没有红色部分,点击 Generate 生成项目

下载缺失的文件
CMake 构建期间会联网下载一些库,如果下载失败了,此时直接编译代码,有些库会编译失败。找到生成目录下 “CMakeDownloadLog.txt” 文件,里边记录了下载失败的文件名称,以及下载地址与下载位置。

可以手动下载并拷贝到指定位置,或者使用一段简单的代码解析文件内容,批量下载,使用 C# 编写较为容易,想使用其他语言编写自行修改。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 
 | using System;using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Net;
 using System.Text;
 using System.Threading.Tasks;
 
 namespace CMakeDownLoadErrorFile
 {
 class Program
 {
 static void Main(string[] args)
 {
 
 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
 
 string fileCMakeDownloadLog = @"D:\Software\opencv\CMakeDownloadLog.txt";
 var vFileList = GetFileList(fileCMakeDownloadLog).Where(o => o.StartsWith("do_copy") || o.StartsWith("do_unpack")).ToList();
 for (int i = 0; i < vFileList.Count; i++)
 {
 var vItemSplit = vFileList[i].Split(' ');
 var vItemType = vItemSplit[0];
 var vItemFileName = vItemSplit[1].Replace("\"", "");
 var vItemMD5 = vItemSplit[2].Replace("\"", "");
 var vItemUrl = vItemSplit[3].Replace("\"", "");
 var vItemPath = vItemSplit[4].Replace("\"", "");
 
 var vSavePath = $"{vItemPath}/{vItemFileName}";
 
 string strFolderPath = Path.GetDirectoryName(vSavePath);
 if (!Directory.Exists(strFolderPath))
 {
 Directory.CreateDirectory(strFolderPath);
 }
 
 Console.WriteLine($"{DateTime.Now} 下载文件:{vItemFileName}\t({i + 1}/{vFileList.Count})");
 DownLoadFile(vItemUrl, $"{vSavePath}");
 }
 Console.WriteLine("下载完成!");
 Console.ReadKey();
 }
 
 
 
 
 
 
 public static List<string> GetFileList(string strPath)
 {
 string[] strText = null;
 List<string> listText = new List<string>();
 try
 {
 strText = File.ReadAllLines(strPath);
 foreach (string strLine in strText)
 {
 listText.Add(strLine);
 }
 }
 catch (Exception)
 { }
 return listText;
 }
 
 
 
 
 
 
 public static void DownLoadFile(string fileUrl, string savePath)
 {
 using (var web = new WebClient())
 {
 web.DownloadFile(fileUrl, savePath);
 }
 }
 }
 }
 
 | 
 
下载完成后测试有一处需要手动拷贝文件,否则编译时找不到文件,拷贝:”…/{生成目录}/downloads/xfeatures2d” 目录下文件至 “…/opencv_contrib-3.4.2/modules/xfeatures2d/src”。
编译项目
运行 Visual Studio 打开生成目录下 “OpenCV.sln”,点击菜单栏:生成 -> 批生成,勾选 Debug 模式与 Release 模式的 ALL_BUILD 与 INSTALL 项目,点击生成即可生成最完整的项目包,也可根据实际需要勾选,或者直接在项目中右键生成。等待生成完成即可。

结束
如果出现编译失败,可以尝试保证网络完好后再次生成,有些文件似乎还是会通过联网下载。
编译完成后:”…/{生成目录}/install” 即为最后生成文件,我这里生成的 install 中的 bin 目录配置环境变量后就可以正常使用,include 与 lib 目录则引用到开发项目中。
项目引用
C++ 项目在引用 OpenCV 附加依赖项时需要区分 Debug 与 Release 库:
其中以 *342d.lib 结尾的文件为 Debug 生成;
其中以 *342.lib 结尾的文件为 Release 生成;
可以使用以下命令生成文件名,方便项目引用时拷贝。
| 12
 
 | dir *342d.lib > lib_debug_file.txtdir *342.lib > lib_release_file.txt
 
 | 
不同的目录
可能由于软件版本问题,有人生成的目录会是:”…/{生成目录}/install/x64/vc15/bin”,环境变量引用即可,似乎没有什么区别。