Windows下编译并测试OpenCV

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

注2:以下若不做说明则都是我自己试过的方法

编译

1. 下载cmake

https://cmake.org/download/

2. 下载opencv源码

https://opencv.org/releases/

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”

Leave a Comment