以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,跟踪,双目标定,线结构光标定算法就这些算法,我觉得很值得编译学习源码也是一种享受,毕竟开源,是珍贵的学习资料。
下载安装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
下载好解压先放着,兵马未动粮草先行哈哈哈。
(关键点我粗写按照我的方法一步一步来应该不会出问题)
- 打开opencv,看见我标注的解释,要做的就是自己在这里面新建以一个newbuild文件用来存放我们一会接下来编译的文件。
- 打开cmake,输入如下路径注意路径不要有中文!!!中间会选择VS版本,和32位和64位
按照上图3步,依次 *** 作,会有报错信息会显示如下,基本是爆红,如下图:
我在图中标出来的方框,大意就是打开所显示的路径,查看具体信息。好,打开按照你的文件路径存放的CMakeDownloadLOg.txt文件,这个是编译汇报说明,里面有错误原因。
上面这张图是我网上找的因为我在编译的时候没有截图,这个文件路径不要按照他的来,具体的 就在上文提到的自己新建的newbuild文件如图:
打开它密密麻麻,大概意思是,你的opencv文件中的souce中的.cache文件全是空的,cmake试图帮你下载 但是 你的网下载不了,我试过了就算适用VPN也下载不了。好了具体就不打开了,直接上方法!
- 打开你如下的对应的文件夹,
你会发现具体的每个文件里面的小文件都是空的,对了问题就在这里,那我们就下载相应的文件替换不就可以了吗,是的!
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.
-
好了再次点击你的再次点击configure ,出现以下就代表成功了。
-
第一次编译完成之后,我们需要将额外的opencv_contrib加到工程中进行第二次编译,在配置表中找到“OPENCV_EXTRA_MODULES_PATH”,设置其参数值为open_contrib源码包中的modles目录。
现在开始!
按照如下如勾选注意点都在图中标出
这个 也要勾上,别问为什么,问就是我也不知道
点击Configure 没有错的话错,再点击Generate。大功告成如下图。
开始到了编译阶段这个简单了。
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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)