注1:以下若不做说明默认将opencv下载编译到我本机 C:\Users\HuntZou\Downloads\ 目录下,您需根据您自己的情况做一些替换。
注2:以下若不做说明则都是我自己试过的方法
编译
1. 下载cmake

2. 下载opencv源码

3. 解压缩opencv源码并进入到解压后的目录
4. 在解压后的目录创建一个build目录,用于存放cmake的输出文件
注:这是为了后面在命令行中使用cmake,你也可以直接使用cmake的gui

5. 在build目录中打开cmd,并使用下载好的cmake创建makefile

这一步需要下载一些东西,由于东西在外网,导致在这里卡半天,最终会报错

解决办法:
5.1 简单方法(使用代理):如果电脑上装了clash代理软件的话,直接开启clash的tun模式即可,我自己实验一次就成功了。

貌似windows命令行默认不走代理,clash开启该选项后会虚拟出一块网卡,所有流量都会经过该网卡,这样即使不走代理的软件也会被迫走代理。
貌似也可以直接设置命令行走代理,不过我没试 https://blog.csdn.net/u014723479/article/details/103698296
5.2 复杂方法(cmake期间不用下载):
5.2.1. 自己在下载好该文件
停止cmake,然后找到build目录下的 CMakeDownloadLog.txt
文件,在里面搜索关键字 ”https“ 可以找到文件的下载链接。

注:图示内容为可以正常下载情况下的截图,您该文件内容应该没这么完整,但也能找到一些url链接。
需要下载的文件一共有四个,共分为两类:
ffmpeg:opencv_videoio_ffmpeg.dll、opencv_videoio_ffmpeg_64.dll、ffmpeg_version.cmake
ippicv:ippicv_2020winintel6420191018general.zip
ippicv的链接直接下载即可
ffmpeg需要下载三个文件,但它们的url前缀都是一样的,将上述三个文件名替换一下下载即可
5.2.2. 将下载好的 ffmpeg 三个文件 放到 /3rdparty/ffmpeg/ 目录下
ippicv_2020_win_intel64_20191018_general.zip 放到 /3rdparty/ippicv/ 目录下
5.2.3. 打开opencv源码目录下的文件 /3rdparty/ippicv/ippicv.cmake 和 /3rdparty/ffmpeg/ffmpeg.cmake
注释掉以下部分:


重新开始cmake
6. cmake结束后会在build目录下生成一个opencv的vs工程,用vs打开即可,然后再用vs编译。


7. 编译结束之后报了一堆错误

这些错误分为两类:语法错误 和 链接错误
7.1 语法错误
打开错误出现的位置发现一些十六进制字符和日文,这有可能是文件编码方式不对导致的
解决办法:将文件编码修改为 ”utf8 with signature“ 后重新编译,详见:https://blog.csdn.net/pypyquixue/article/details/123448814
注:这篇文件说的是将编码修改为 GB2312,但我测试还是会编译报错,实测修改为 utf8 with signature 可以(可以修改该文件编码后,右键选择该文件单独进行编译,看能否编译通过)

7.2 链接错误
最后还剩一个链接错误,由于我本地没有debug的python链接库,且vs默认打包的是debug库,所以我干脆直接打包release库得了(构建debug版本见注7.2.1)
项目右键选择属性,按如下配置修改为release。

最终编译成功

注:
7.2.1 若不需要构建python版本的依赖的话,可以去掉python的构建,即可成功构建debug版本

7.2.2 其他解决方法:https://blog.csdn.net/hshqing/article/details/79316816 (我没试)
8. 此时只是编译成功了,build目录下还没有install目录,还需要install一下(原因参见 cmake的install)。如图操作即可

此时就大功告成了,依赖库在 x64 目录中,头文件在 include 中

测试
1. 创建项目并将项目配置成release模式
右键项目->属性

注:之所以使用release模式,是因为opencv使用了release方式构建。我通过上述 7.2.1 方法构建debug模式的opencv之后就能成功应用于debug模式的项目了
使用不同的构建方式会报如下错误(代码见下文)

我不太能理解,为什么依赖库的构建方式会对项目产生影响,我觉得很别扭。
2. 添加头文件搜索目录
C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\include

注:opencv中会有一些使用”<…>”方式的引用,配置该目录的作用就是告诉编译器去哪寻找这些引用
3. 添加依赖的库文件

内容为:
# 以下均省略目录前缀
# 全名应该是 C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\x64\vc17\lib\opencv_calib3d460.lib
# 这三行注释的不用复制
opencv_calib3d460.lib
opencv_core460.lib
opencv_dnn460.lib
opencv_features2d460.lib
opencv_flann460.lib
opencv_gapi460.lib
opencv_highgui460.lib
opencv_imgcodecs460.lib
opencv_imgproc460.lib
opencv_ml460.lib
opencv_objdetect460.lib
opencv_photo460.lib
opencv_stitching460.lib
opencv_video460.lib
opencv_videoio460.lib
注1:这些其实就是 C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\x64\vc17\lib 目录下的所有文件名
注2:您需要自己加上目录前缀,例如我的是:C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\x64\vc17\lib
注3:您也可以在“库目录”选项中统一配置目录,然后这些库文件就不用带目录前缀了。(见 “其他” 部分)

4. 添加动态库文件
4.1 拷贝文件方式
将 C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\x64\vc17\bin 目录下所有的文件都拷贝到项目的 源代码目录
下

4.2 环境变量方式
添加动态库的环境变量
C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\x64\vc17\bin

注1:因为是动态库文件,默认系统里面有,所以不会将其打包进项目。但是系统中如果没有则需要在项目打包之后将上述动态库都拷贝到exe同级目录下
注2:修改环境变量之后需重启一下vs,我本人因为没重启vs导致即使加了环境变量还是一直报错,卡了好久
注3:我个人是不太喜欢这种做法的,为了一个项目却需要修改系统的环境变量,我觉得很别扭。
5. 测试代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main()
{
cv::Mat img = cv::imread("C:\\Users\\HuntZou\\Documents\\Personal\\Projects\\filter_defect\\imgs\\filter_5.jpg");
cv::imshow("img", img);
cv::waitKey(0);
}
我本地测试OK
其他
1. vs中依赖配置方式说明
vs中有几个地方可以设置依赖关系:
1.1. vc++中的”包含目录“和”库目录“

包含目录是”#include <…>“搜索的目录,等价于下面的 1.2
库目录是库搜索目录,即设置了该目录后,再在 1.4 中添加依赖就不用设置地址前缀,等价于下面的 1.3
注:上述两个等价的区别是:在这里做的配置是以环境变量的形式参与项目编译的,而下面做的配置是以编译过程中加入的参数参与项目的编译。这里可能是有一些历史包袱在的,早期的vs,在这里的设置相当于全局设置,对所有项目生效(目前的版本都仅对当前项目生效),这就说得通了。
1.2. c/c++ ——> 常规 下的”附加包含目录“

同 1.1 中的 ”包含目录“
1.3. 链接 -> 常规 下的”附加库地址“

同 1.1 中的 ”库目录“
1.4. 链接 -> 输入 下的 ”附加依赖“

需要手动指定项目所依赖的lib文件,类比java项目中添加jar文件
参考:https://www.cnblogs.com/wjune-0405/p/14900410.html
2. Qtcreator中的使用
在pro文件中添加以下代码:
# 头文件搜索目录
INCLUDEPATH += C:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\include
# 添加的依赖库lib文件(省略.lib后缀,后面的\表示命令换行符,若写成单行则不需要)
LIBS += -LC:\Users\HuntZou\Downloads\opencv-4.6.0\build\install\x64\vc17\lib \
-lopencv_calib3d460 \
-lopencv_core460 \
-lopencv_dnn460 \
-lopencv_features2d460 \
-lopencv_flann460 \
-lopencv_gapi460 \
-lopencv_highgui460 \
-lopencv_imgcodecs460 \
-lopencv_imgproc460 \
-lopencv_ml460 \
-lopencv_objdetect460 \
-lopencv_photo460 \
-lopencv_stitching460 \
-lopencv_video460 \
-lopencv_videoio460
编译方式还是需要和opencv的编译方式保持一致,动态库需拷贝到源码目录或设置环境变量(同上)。

3. 如何判断是静态库的缺失还是动态库的缺失?
一般来说,如果代码运行报错“无法解析的外部符号xxx”,则可能是静态库的缺失(只有声明没有实现)
如果是动态库的缺失,一般会直接报“找不到xxx.dll”