以VS2017+OpenCV3.4.7+opencv

以VS2017+OpenCV3.4.7+opencv,第1张

以VS2017+OpenCV3.4.7+opencv_contrib3.4.7 为例,用cmake编译,实现所有版本轻松编译,其他版本组合都可借鉴
说在前面:重新编译opencv,opencv_contrib3.4.7是为了使用opencv的跟踪算法,但是因为版权原因opencv官方没有公布,但是在git_hub上有opencv_contrib3.4.7扩展包,小编研究了一天摸透了所有的方法,网上很多编译教程,我发现多多少少都有小伙伴没能成功编译,现在详细记得把流程过一遍,保证不出错。


以VS2017 Opencv3.4.7为例。


放心我会教会你各种版本搭配的编译方法。


接下来开始吧!
补充1:好多小伙伴好奇cmake是干嘛的呢?**cmake可以利用源文件中的官方人员写好的CMakeLists.txt重新组织各个分文件.h,.cpp之间f复杂的关系,现在我们想要加入opencv_contrib就必须重新组织,所以需要我们重新编译,之前下载的是官方人员编译过好的,现在关系乱了就需要重新编译。


另外网上发行的opencv时已经编译好的,大部分函数实现看不见,函数转定义只能看见函数声明,我们还可以通过这次编译实现详细的观察opencv源代码。



补充2:opencv_contrib里面封装了 深度学习CNN算法,并且支持CUDE,sift, fast,跟踪,双目标定,线结构光标定算法就这些算法,我觉得很值得编译学习源码也是一种享受,毕竟开源,是珍贵的学习资料。


1.软件下载

下载安装VS2017,opencv3.7.4,opencv_contrib3.4.7,cmake-gui3.1.8,要保证opencv和opencv_contrib版本一致。


前提保证VS安装到位,因为Cmake需要提前安装好VS,软件下载列表如下:
cmke下载:(我用的3.18基本这个就可以 cmake版本要求不是很严格,具体的安装网上有记得把环境变量勾选,具体看网上教程)
https://blog.csdn.net/u011231598/article/details/80338941
opencv各版本:
https://github.com/opencv/opencv/releases
opencv_contrib各版本 :
https://github.com/opencv/opencv_contrib/releases
下载好解压先放着,兵马未动粮草先行哈哈哈。



2.编译过程重点

(关键点我粗写按照我的方法一步一步来应该不会出问题)

  1. 打开opencv,看见我标注的解释,要做的就是自己在这里面新建以一个newbuild文件用来存放我们一会接下来编译的文件。



  2. 打开cmake,输入如下路径注意路径不要有中文!!!中间会选择VS版本,和32位和64位

    按照上图3步,依次 *** 作,会有报错信息会显示如下,基本是爆红,如下图:

    我在图中标出来的方框,大意就是打开所显示的路径,查看具体信息。


    好,打开按照你的文件路径存放的CMakeDownloadLOg.txt文件,这个是编译汇报说明,里面有错误原因。


    上面这张图是我网上找的因为我在编译的时候没有截图,这个文件路径不要按照他的来,具体的 就在上文提到的自己新建的newbuild文件如图:

    打开它密密麻麻,大概意思是,你的opencv文件中的souce中的.cache文件全是空的,cmake试图帮你下载 但是 你的网下载不了,我试过了就算适用VPN也下载不了。


    好了具体就不打开了,直接上方法!

  3. 打开你如下的对应的文件夹,


你会发现具体的每个文件里面的小文件都是空的,对了问题就在这里,那我们就下载相应的文件替换不就可以了吗,是的!
but,其中的ffmpeg,ippicv这两个文件是是严格和你的opencv还有vs版本有关系,其他的文件和版本无关,这里我把其他的文件放在百度网盘,链接:百度网盘
提取码:fnsc
大家自行下载,网盘文件如下图:

细心的同学会发现我给出的文件怎么对比你的多出.ade文件,具体我也不知道,其实没有他也行,我担心其他小伙伴因为版本原因,可能会不同,以防万一,放在文件夹也无大碍。


  好了现在开始填充ffmpeg,和ippicv文件,具体的针对你的类型查看方式如下:
 打开你opencv->sources->3rdpart  会发现存在两个文件夹ffmpeg,和ippicv文件。


ffmpeg版本查询:
打开ffmpeg文件夹,里面有个ffmpeg.cmake文件,选择用记事本打开如下图

在第 1 行可以找到所需要下载的分支名,即 # Binaries branch name: ffmpeg/3.4_20190612(把你对应的版本号记下来 我的是20190612)

在第 3 行可以找到对应提交记录的哈希值,即 1c661e754812d3423e8c15ccb9cdab57fc122c44(这个哈希值其实没用不用记录,你会发现这个哈希值就是之前我说的0KB文件夹名字的前半部分)


ippicv版本查询::
同样再上面的3rdpart文件夹打开ippicv文件夹中的ippicv.cmake文件夹
在第 26 行可以找到所需要下载的分支名(这里以 win64 为例)。


可以通过 OPENCV_ICV_NAME 变量的定义 来获取,如:set(OPENCV_ICV_NAME “set(OPENCV_ICV_NAME “ippicv_2019_mac_intel64_general_20180723.tgz”)”),其中的时间为 20180723,那么选对应的分支即可。


(不用在乎你的事.tgz还是.zip一样的)

在第 5 行可以找到对应提交记录的哈希值,即 32e315a5b106a7b89dbed51c28f8120a48b368b4(我的和你的不同别担心)

好了现在打开这两个文件下载网址
如果这个打不开用国内的国内下载网址
下载上面记录的两个文件的版本号:

对于下载下来的文件,对照你的opencv\sources.cache中的ffmpeg,ippicv中的空文件名字去你下载下来的两个文件中分别去找,找到放在从我下载下来的放在百度网盘种的ffmpeg,ippicv中 这两个是我建的方便你们放文件,放完之后记得对照原来的0KB文件更改文件名,(你会发现文件名前半部分就是哈希值)


以上是放置好的,好了现在你的.cache就把文件补全了,现在把你原来文件夹的.cache删了,换成现在的.cache文件,就是你们从网盘下载的,再补全fmpeg,ippicv的.cache.

  1. 好了再次点击你的再次点击configure ,出现以下就代表成功了。


  2. 第一次编译完成之后,我们需要将额外的opencv_contrib加到工程中进行第二次编译,在配置表中找到“OPENCV_EXTRA_MODULES_PATH”,设置其参数值为open_contrib源码包中的modles目录。



    现在开始!
    按照如下如勾选注意点都在图中标出

    这个 也要勾上,别问为什么,问就是我也不知道

    点击Configure 没有错的话错,再点击Generate。


    大功告成如下图。



3.VS2017 编译配置

开始到了编译阶段这个简单了。



1. 批生成

点击箭头所指按钮,直接启动你的VS,接下来就在vs里面 *** 作了。


哈哈哈,结束Cmake。


紧接着点击生成->批处理

出现以下图片,如果你不需要Release,这两个相应的Realse就不要选了,我对比了,不选可以很节省时间,而且内存很小。




经过时间漫长的等待,(Debug大概15分钟)。


就结束了。


(这里有个注意点,有的小伙伴可能电脑安装了Python,会出现报错无法打开 python36_d.lib 的问题我直接给你传送门,按图索骥,就可以解决:传送门)
编译完成成了,接下来就是和普通的opencv配置一样了。


**1.环境变量配置:**电脑->高级设置->环境变量->path新建输入你的对应的bin文件,(其实bin文件就是动态链接库)D:\OPEN\opencv3.4.7\opencv\newbuild\install\x64\vc15\bin

2.打开属性资源管理器,我是采用属性表配置,这样很方便,新建下一个项目直接将属性表放入就可以。


右击Debug64,新建属性表进入配置环节。




3.在VC++目录中:

包含目录: 中放入(你按照我的路径对比找到你的路径)
D:\OPEN\opencv3.4.7\opencv\newbuild\install\include
D:\OPEN\opencv3.4.7\opencv\newbuild\install\include\opencv
D:\OPEN\opencv3.4.7\opencv\newbuild\install\include\opencv2

设置库目录:
D:\OPEN\opencv3.4.7\opencv\newbuild\install\x64\vc15\lib

具体如图:

3.然后是附加依赖项:
链接器->输入->附加依赖项
输入:(对应版本修改数字就行,注意这是Debug版本)

opencv_world347d.lib
opencv_img_hash347d.lib

好了现在就大功告成了。


开始体验下跟踪算法具体如下:

#include 
#include 


cv::Mat frame, gray; //源图像和源灰度图像
cv::Mat framecopy;  //用于拷贝出的源图像
cv::Mat framerect, framerecthsv;  //矩形选取后的图像
cv::Rect rect;      //鼠标选取的矩形


//直方图
int histSize = 200;
float histR[] = { 0,255 };
const float *histRange = histR;
int channels[] = { 0,1 };
cv::Mat dstHist;


//保存目标轨迹  
std::vector<cv::Point> pt;


//鼠标控制
bool firstleftbutton = false;
bool leftButtonDownFlag = false; //左键单击后视频暂停播放的标志位 
cv::Point rectstartPoint; //矩形框起点    
cv::Point rectstopPoint; //矩形框终点    
void onMouse(int event, int x, int y, int flags, void* ustc); //鼠标回调函数    




int main(int argc, char** argv)
{
	cv::VideoCapture video;
	video.open("11.mp4");
	if (!video.isOpened())
	{
		printf("could not open video....\r\n");
		getchar();
		return -1;
	}
	double fps = video.get(CV_CAP_PROP_FPS); //获取视频帧率    
	double pauseTime = 1000 / fps; //两幅画面中间间隔    
	cv::namedWindow("srcvideo", CV_WINDOW_NORMAL);
	//设置图像中鼠标事件
	cv::setMouseCallback("srcvideo", onMouse, 0);
	bool first = false;
	while (true)
	{
		//当鼠标左键没有按下时
		if (!leftButtonDownFlag)
		{
			video >> frame;
			try
			{
				cv::resize(frame, frame, cv::Size(300, 600));
			}
			catch (const std::exception& exception)
			{
				printf(exception.what());
				break;
			}
		}
		//图像为空或Esc键按下退出播放    
		if (!frame.data || cv::waitKey(pauseTime) == 27)
		{
			break;
		}
		//如果已经截取了图像进行处理
		if (rectstartPoint != rectstopPoint && !leftButtonDownFlag)
		{
			cv::Mat imageHSV;
			cv::Mat calcBackImage;
			cvtColor(frame, imageHSV, cv::COLOR_BGR2HSV);


			//反向投影
			cv::calcBackProject(&imageHSV, 2, channels,
				dstHist, calcBackImage, &histRange);
			cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER +
				cv::TermCriteria::EPS, 10, 1);
			cv::CamShift(calcBackImage, rect, criteria);
			//更新模板
			cv::Mat imageROI = imageHSV(rect);
			framerecthsv = imageHSV(rect);
			calcHist(&imageROI, 2, channels, cv::Mat(),
				dstHist, 1, &histSize, &histRange);
			normalize(dstHist, dstHist, 0.0, 1.0, cv::NORM_MINMAX);   //归一化  
			rectangle(frame, rect, cv::Scalar(255, 0, 0), 3);    //目标绘制    
			pt.push_back(cv::Point(rect.x + rect.width / 2,
				rect.y + rect.height / 2));
			for (int i = 0; i < pt.size() - 1; i++)
			{
				cv::line(frame, pt[i], pt[i + 1], cv::Scalar(0, 255, 0), 2.5);
			}
		}
		cv::imshow("srcvideo", frame);
		cv::waitKey(50);
	}


	video.release();
	cv::waitKey(0);
	return 0;
}


//鼠标回调函数
void onMouse(int event, int x, int y, int flags, void * ustc)
{
	//鼠标左键按下
	if (event == CV_EVENT_LBUTTONDOWN)
	{
		leftButtonDownFlag = true; //更新按下标志位
		rectstartPoint = cv::Point(x, y); //设置矩形的开始点
		rectstopPoint = rectstartPoint;   //刚按下时结束点和开始点一样
	}
	//当鼠标按下并且开始移动时
	else if (event == CV_EVENT_MOUSEMOVE && leftButtonDownFlag)
	{
		framecopy = frame.clone();  //复制源图像
		rectstopPoint = cv::Point(x, y); //设置矩形的结束点
		if (rectstartPoint != rectstopPoint)
		{
			//当矩形的开始点和结束点不同后在复制的图像上绘制矩形
			cv::rectangle(framecopy, rectstartPoint, rectstopPoint,
				cv::Scalar(255, 255, 255));
		}
		cv::imshow("srcvideo", framecopy);
	}
	//当鼠标抬起时
	else if (event == CV_EVENT_LBUTTONUP)
	{
		leftButtonDownFlag = false;//按下鼠标标志位复位
		rect = cv::Rect(rectstartPoint, rectstopPoint);//设置选中后的矩形
		framerect = frame(rect); //通过矩形获取到选取后的图像
		cv::imshow("selectimg", framerect);//显示出来选择后的图像
		cv::cvtColor(framerect, framerecthsv, cv::COLOR_BGR2HSV);
		//直方图计算
		calcHist(&framerecthsv, 2, channels, cv::Mat(), dstHist, 1, &histSize, &histRange, true, false);
		//归一化显示
		normalize(dstHist, dstHist, 0, 255, CV_MINMAX);
	}
}

百度网盘:32位opencv3.4.7+contrib3.4.7编译好的:
链接:https://pan.baidu.com/s/1pvFcRGheDwjmZYHTDuR9AQ?pwd=f75o
提取码:f75o

64位opencv3.4.7+contrib3.4.7编译好的:
链接:https://pan.baidu.com/s/1xxUWUQnoTbpO8yFXpA9N2A?pwd=j8rp
提取码:j8rp

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/567238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存