opencv3.4.1+opencv_contrib3.4.1联合编译【vs2019+win10】


最近想通过OpenCV调用KCF跟踪算法学习一下,不过却发现OpenCV的tracking模块在opencv_contrib中,因此想使用这部分算法的话,就必须将opencv_contrib编译到opencv中,接下来介绍一下在win10平台的编译过程。

获取OpenCV源代码及安装CMake

第一步,先去Github上将两份源代码拷贝下来,以下是代码地址

opencv3.4.1源代码地址:https://github.com/opencv/opencv/tree/3.4.1
opencv_contrib3.4.1源代码地址:https://github.com/opencv/opencv_contrib/tree/3.4.1

注意,要保证两个版本是相同的。下载后,这里我将两份文件均放在E盘下的opencv文件夹中。并新建一个空文件夹opencv-3.4.1build来存储cmake生成的文件。

cv1
cv7
cv8

第二步,需要安装一下CMake,CMake是一个跨平台的编译工具。

下载地址:https://cmake.org/files

这里,我选择3.18.2版本的cmake-3.18.2-win64-x64.msi

cv2
下载后,双击直接运行安装即可

cv3
cv4

用CMake生成VS工程

安装好cmake后,双击运行CMake,将开头两项填好,Where is the source code是源路径,即opencv源码路径,where to build the binaries是目的路径,即生成opencv的VS工程路径。

cv5
接着,点击configure,选择编译工程的平台,这里我选择VS2019和x64,点击finish即可开始配置

cv6
耐心等待一会儿,不出意外的话,会出现如下画面,对!一片飘红

cv9
有很多红色选项,说明有问题,那么该怎么解决呢?首先我们去查看一下日志文件CMakeDownloadlog.txt,在文件夹opencv-3.4.1build中双击打开文件,会发现需要下载四个文件:opencv_ffmpeg.dllopencv_ffmpeg_64.dllffmpeg_version.cmakeippicv_2017u3_win_intel64_general_20170822.zip,对应网址如文件中所示

opencv_ffmpeg.dll下载地址:https://raw.githubusercontent.com/opencv/opencv_3rdparty/0a0e88972a7ea97708378d0488a65f83e7cc5e69/ffmpeg/opencv_ffmpeg.dll
opencv_ffmpeg_64.dll下载地址:
https://raw.githubusercontent.com/opencv/opencv_3rdparty/0a0e88972a7ea97708378d0488a65f83e7cc5e69/ffmpeg/opencv_ffmpeg_64.dll
ffmpeg_version.cmake下载地址:
https://raw.githubusercontent.com/opencv/opencv_3rdparty/0a0e88972a7ea97708378d0488a65f83e7cc5e69/ffmpeg/ffmpeg_version.cmake
ippicv_2017u3_win_intel64_general_20170822.zip下载地址:
https://raw.githubusercontent.com/opencv/opencv_3rdparty/dfe3162c237af211e98b8960018b564bc209261d/ippicv/ippicv_2017u3_win_intel64_general_20170822.zip

cv10
cv11
cv12
仔细观察一下会发现,配置opencv时,会先在源代码目录下建立.cache目录,CMake从国外网站自动下载到E:\opencv\opencv-3.4.1\.cache中,文件名为md5值+文件名,若是下载成功,会解压到目的路径E:\opencv\opencv-3.4.1bulid\3rdparty中。打开.cache目录会发现有的文件未下载成功,虽然有文件名,但是大小为0KB,见下面两张图

cv13
cv14
至此,可知,由于CMake从国外网站下载文件失败导致飘红,因此需要手动将文件全部下载下来。手动下载的文件并没有前缀md5值,如ippicv_2017u3_win_intel64_general_20170822.zip,为他手动加上前缀:0421e642bc7ad741a2236d3ec4190bdd-ippicv_2017u3_win_intel64_general_20170822.zip
然后将此文件放在E:\opencv\opencv-3.4.1\.cache\ippicv下替换原来的0KB文件,之后让CMake自己处理。

cv15
而另外三个手动下载的文件,则直接放在E:\opencv\opencv-3.4.1bulid\3rdparty\ffmpeg

cv16
四份文件的百度云链接:

链接:https://pan.baidu.com/s/1A-Q68VTKevPLJPntY9tyYg 提取码:b1cd

于是,我们变相得帮助CMake下载好文件并放在了对应位置。删除E:\opencv\opencv-3.4.1bulid中的内容,除了文件夹3rdparty。重新启动CMake,再走一下上面流程,因为此时文件均已下载好,所以速度会很快。注意,再编译一次虽然依旧会显示飘红,但此时打开CMakeDownloadlog.txt文件会发现四个文件均已匹配好,因此只要点击一下configure就可以了

cv20
终于变白了,显示Configuring done,于是接下来要配置opencv_contrib

cv21
这里一共有三处需要改动:

  1. 勾选上BUILD_opencv_world,将编译库为一个单独的opencv_worldxx.dll/lib文件
  2. 勾选上OPENCV_ENABLE_NONFREE,可使用需专利授权的算法,如SIFT
  3. OPENCV_EXTRA_MODULES_PATH添加路径,E:/opencv/opencv_contrib-3.4.1/modules,注意!这里不要直接拷贝路径,否则会变成E:\opencv\opencv_contrib-3.4.1\modules

cv17
cv18
cv19
然后,点击左下角configure,不出意外的话,会再次出现红色,表明文件下载失败,麻了!

cv22
失败文件还是记录在CMakeDownloadlog.txt文件中,打开看一下究竟是哪些文件呢

cv23
可以看见,之前下载好的四个文件均已匹配好,但是下载新的文件又失败了,于是手动将需要的文件下载下来,并给他们添加好md5值,放在各自的位置上。

cv24
cv25
cv28
cv26
但在这里,我当个马后跑,若是仅仅将E:\opencv\opencv-3.4.1\.cache中各文件夹的缺失文件都补充好,最后批生成时依旧会发生一大堆错误,失败一百多个,如下图所示,简直是血泪教训,这里检查了很多次!

cv29
因此这里我参考别人的博客多做了一步,将下载后的12份文件,拷贝到E:\opencv\opencv_contrib-3.4.1\modules\xfeatures2d\src,具体原因不详。
12份文件【其实是13份,多了一个压缩包文件】百度云链接:

链接:https://pan.baidu.com/s/1jnp8FbMyZJnwNbN0hjur6A 提取码:lzaa

cv30
cv31
像之前流程一样,删除E:\opencv\opencv-3.4.1bulid中的内容,除了文件夹3rdparty。重新启动CMake,再走一下两步流程,因为此时两步文件均已下载好,天不怕地不怕,直接configure到底。最后点击Generate即可。

cv27

为了以防万一,最好检查一下CMakeDownloadlog.txt文件,看一下有没有缺失文件,根据我的经验,第一步中四个文件一般不会缺失,可能第二步中补充opencv_contrib模块时会文件会提醒有文件未下载成功,你可能会问,不是我们已经将文件下载好并补充到文件夹了吗,但事实就是这样,你最好去目的文件夹中检查一下有没有对应文件,若是缺少,直接补上就行

cv32
cv33

用VS2019编译OpenCV

在输出目录E:\opencv\opencv-3.4.1bulid中,找到OpenCV.sln文件,双击打开。

cv34点击菜单栏中的生成选项,再点击批生成

cv35

如下图所示,勾选上四个选项,再点击生成

cv36

耐心等待,直到输出以下信息

cv37

CMake编译生成的OpenCV库,在E:\opencv\opencv-3.4.1bulid\install下,我发现它没有x64目录,取而代之只有一个lib目录,但根据我的研究,x64目录中bin文件夹里的文件,在这个bin目录里都有

cv38
cv39

cv40
至此,在VS2019环境下编译成功的install文件,同时包括Debug和Release的依赖库,这里放上百度云链接

链接:https://pan.baidu.com/s/14SEBWzHpOfemEvfGRTQeDQ 提取码:xkni

配置OpenCV环境

首先添加一下环境变量,我这里是D:\opencv3.4.1\install\bin更改好环境变量后重启电脑生效

cv41
cv42

双击打开VS2019,新建一个空项目,再新建一个新的cpp文件,选择Debug|x64

cv43

在解决方案中右击工程,打开工程属性,为工程配置包含目录

cv44

为工程配置库目录

cv45

添加附加依赖项,在Debug模式下添加opencv_world341d.libopencv_img_hash341d.lib
在Release模式下添加opencv_world341.libopencv_img_hash341.lib

cv46

OpenCV自带的KCF跟踪算法体验

在C++文件中写入如下代码

#include <opencv2/opencv.hpp> 
#include <opencv2/video.hpp> 
#include <opencv2/tracking.hpp>
#include <opencv2/tracking/tracker.hpp>
using namespace cv;
void draw_rectangle(int event, int x, int y, int flags, void*);
Mat firstFrame;
Point previousPoint, currentPoint;
Rect2d bbox;
int main(int argc, char* argv[])
{
	//启用摄像头进行跟踪
	//VideoCapture capture(0);
	Mat frame;
	//capture >> frame;
	//使用事先录好的视频进行检验
	VideoCapture capture;
	frame = capture.open("D:\\1.mp4"); 
	if (!capture.isOpened())
	{
		printf("can not open ...\n");
		return -1;
	} //获取视频的第一帧,并框选目标 
	capture.read(firstFrame);
	if (!firstFrame.empty())
	{
		namedWindow("output", WINDOW_AUTOSIZE);
		imshow("output", firstFrame);
		setMouseCallback("output", draw_rectangle, 0);
		waitKey();
	}

	//使用不同跟踪算法进行跟踪 
	//Ptr<TrackerMIL> tracker= TrackerMIL::create(); 
	//Ptr<TrackerTLD> tracker= TrackerTLD::create();									   
	Ptr<TrackerKCF> tracker = TrackerKCF::create();
	//Ptr<TrackerMedianFlow> tracker = TrackerMedianFlow::create();										  
	//Ptr<TrackerBoosting> tracker= TrackerBoosting::create(); 

	capture.read(frame);
	tracker->init(frame, bbox);
	namedWindow("output", WINDOW_AUTOSIZE);
	while (capture.read(frame))
	{
		tracker->update(frame, bbox);
		rectangle(frame, bbox, Scalar(255, 0, 0), 2, 1);
		imshow("output", frame);
		if (waitKey(20) == 'q') return 0;
	}
	capture.release();
	destroyWindow("output"); return 0;
}

void draw_rectangle(int event, int x, int y, int flags, void*)
{
	if (event == EVENT_LBUTTONDOWN) { previousPoint = Point(x, y); }
	else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
	{
		Mat tmp; firstFrame.copyTo(tmp);
		currentPoint = Point(x, y);
		rectangle(tmp, previousPoint, currentPoint, Scalar(0, 255, 0, 0), 1, 8, 0);
		imshow("output", tmp);
	}
	else if (event == EVENT_LBUTTONUP)
	{
		bbox.x = previousPoint.x;
		bbox.y = previousPoint.y;
		bbox.width = abs(previousPoint.x - currentPoint.x);
		bbox.height = abs(previousPoint.y - currentPoint.y);
	}
	else if (event == EVENT_RBUTTONUP) {
		destroyWindow("output");
	}
}

cv47
ok,大功告成!

猜你喜欢

转载自blog.csdn.net/Star_ID/article/details/122905907