引文:鉴于好多小伙伴跟我一样动手能力不强,特在此分享配置opencv流程,同时保存防止以后重新配置时一头雾水。
首先说明,因为我只写C++和go,所以python的话看这个不适用,同时这里是在vs2022环境下进行配置,如果小伙伴们用久了vscode,会发现VSIED的字体会更粗,但是对比度比vscode更加明显,如果是想用vscode和VSIDE联合编程,在不跨平台的情况下,vscode也可以进行配置,就配置json文件的时候使用MSVC编译器进行配置就好,跟g++略有差异,如果需要,以后我也会发布vscode上的配置,或者是跨平台的opencv库编译。
准备前工具,VS2022,opencv4.7.0, opencv4.7.0-contrib,迅雷,cmake工具,梯子(有最好)。
VS2022安装首先直接搜vs2022就好,然后选择社区版,自己玩社区版就够了,以后上班去大公司就给你免费专业版用了,hhh。
之后就会下好一个vs2022的在线安装的一个工具Visual Studio Installer ,然后勾选C++桌面开发,右边安装详细信息跟我一样就好啦,如果有需要开发应用程序的需求,右边的通用windows平台开发也可以勾选。(语言记得选简体中文嗷,还有安装路径可以自定义,最好别安装在系统盘,如果是只有一个盘的话倒无所谓,建议最好放在固态硬盘,机械硬盘有点慢)。
安装完成之后界面如下,我们点击创建新项目,然后选择空项目或控制台项目,区别就在于控制台项目会给你写好一个helloworld,还有一些教程注释,这里就不多赘述我们选择空项目。
这里最好分开,不要放在同一个目录,这样的话就可以分开,相当于解决方案下的文件夹里有一个文件夹Test是项目Test,更结构化,比较推荐。
进入界面直接添加cpp文件就好,这里会丢在同一个文件夹
可以看到文件和项目文件放在了同一个文件夹下,但是我不建议大家这么写,因为文件一旦躲起来,比如说十几二十个cpp文件和.h/hpp文件,是很乱的所以我建议大家按下面的方法写弄
下面图所示,把头文件和cpp文件分开装,并在项目文件夹里写明这是Code文件,这样对你以后需要进行项目移植也很有帮助,包括更新库上传github等等都非常有帮助,同时有一点十分重要,养成一个良好的编程习惯,以及自身所掌握资源的合理布局是很重要的 。
然后我们随便写一段程序,可以看到编译成功了,(如果一开始创建了cpp文件,然后跟我一样把他给创文件夹归类了,记得在源文件哪里重新添加现有项,把原来的cpp移除掉)。
这样我们安装VS2022就告一段段落啦。
首先我们进入github,没账号的去创建一个(不会github的程序员那还叫程序员吗),搜索栏搜索cmake,找到人家的仓库,然后点击tags(标签),选最新的版本进入,然后找到图中的东西
可以看到这两个,这两个是windows用户选择的安装包,这里推荐下载压缩包,可以直接用,另外一个跟装软件一样,卸载还得控制面板卸载,另一个文件夹一删就可以了。当你把压缩包下好解压好之后,文件结构应该是这样的:
记得把下好的东西归类好,不会的可以参照我上面的那个目录设置。之后我们把bin文件夹这个目录放到系统环境去,看图:
看蓝色的那一条,路径设置好就行了,集体流程就是 新建-->浏览就搞定了,很简单。之后我们试一下cmd(Win + r键,Win键就是你电脑上那个田的图标,看看我说的多详细,各位同胞要注意细节,女生就是喜欢细节上的感动,所以你们给我哭!)命令行,输入cmake --version,可以看到版本号,如果没有看到的,看看环境变量有没有添加对。
到此,cmake就安装好了,很简单的呐。
这个安装可以去官网,也可以去github上下载,这里提一句,之前说工具要迅雷,这是因为迅雷下载更快,有梯子的全过程都挂梯子,具体操作看图:
contrib包一定要下载跟版本号对应的,切记!!!!!!!!!!!!!!!,如果说你碰到下载速度很慢的话,可以这样操作:选择复制下载链接,然后在迅雷新建下载任务的,把下载链接复制上去下载,速度嘎嘎快。
下载完之后文件应该是这样的:
然后我们把扩展文件夹丢进opencv-4.7.0中,
这样就弄好opencv了。
现在正式进入主题,我们首先找到刚刚安装的cmake里的bin文件夹,打开然后双击 cmake-gui .exe
创建文件夹:
然后cmake里上面的选opencv-4.7.0的路径,下面的选你刚刚创建的文件夹我这里是opencv-windows:
之后会出现这个框,按照图片上的选就行,如果你是VS别的版本你就选你自己的,第二个是你不选就默认x64就是64位,如果说你选VS2022的时候下面两个框卡住重叠了,下面的按钮,你随便选一个其他的再选回来,他就出来了。
然后就finish,等他自己跑完(时间快慢依据电脑性能而异,较大的影响是运行内存):
跑完之后就是一片红:
这很正常不要怕,之后还有几个选项要勾选,
有一个Search框,里面按照图片打字母就行 ,这个就是使能不免费的opencv,嵌入式的兄弟们应该经常见到ENABLE,这里就是把一些专利的不免费的算法启用,我们不用来商用,人家不会告我们的,放心好了。
这个就是刚刚扩展包的路径,我们不是把他放进opencv-4.7.0里面了吗,就把路径选好,这里注意:一定要一直选到modules 这个文件夹!!!!!
这个解释一下,world就是全世界的意思,勾选这个,编译出来的库都会被集成为一个库,你不选的话就会生成很多独立的库,看你自己的喜好,我比较喜欢分开,这样项目移植比较好高,而且运行效率会更快,没有其他的冗余。 这几个弄好之后就多来几遍configure,直到界面变白:
这个时候关键的来了,这里如果你选择generate完全是ok的,之后的操作去看别的博客都是能配好,都能用,但是有些模块如果你用上了会直接报错,因为有些东西他并没有下载,我们把下面的框给向上拖:
会有这样一段警告,这是告诉我们有些数据下载失败,详情可以去看CMakeDownloadLog.txt,学过cmake的兄弟应该就很懂,没学过的也不要紧张,说白点就是打开那个你自己一开始新建的那个文件夹,我这里就是opencv-weindows文件夹,把那里面的那个这个txt文件打开:
打开一看,全是密密麻麻的字符,大家不要被吓到了,无从下手,好多博客讲这个的时候看的都有点费劲,这里我教大家咋看,你只要去找出现这个#try 1这个就行,每次都找这个,然后它上面对应的就是:
这句话的意思就是你从这个https这个下载链接下载这个文件,然后改成这个对应文件夹下的这个文件的名字覆盖掉,比如说这个 压缩包,我们把这个http这个复制一下,然后用迅雷下载,
下好之后,这样:
我这里已经把它放在这个路径下了,可以很清楚看到一个是0kb,就是下载失败的,然后我们把下载好的这个名字改成那个0kb的压缩包,然后替换掉就可以了。这里注意一个点,如果有习惯跟我一样的,喜欢把文件的扩展名显示出来的,比如说main.cpp,不显示就是main 类型是cpp文件,显示就是名称就叫main.cpp,一定要注意文件的后缀名字,比如:
这有一个也是要手动替换的,我们发现迅雷也下载不了,这个时候就需要挂梯子了,把那个http的链接在 浏览器打开,
可以看到打开之后是一些cmake的语法,这里我们就需要另存为,然后保存:
有小伙伴看到这个红圈圈的了,这里是一个要注意的点,CMakeDownloadLog.txt里面要的是.cmake后缀的文件,即是cmake类型文件,而这里系统默认是txt文件了,所以把文件扩展名打开显示的道友,一定要注意文件后缀,没打开的道友也要自己观察哦,细节决定一切,说不定看完我的文章你变的更细节了,你女神就因为你注重细节和你在一起了,hhh 。
当然,有些小伙伴看到这说,哎呀,我没有梯子啊,咋办呀。没关系,我已经下载了好了一份,到时候会跟已经编译好的库都给放一起的,有梯子想动手和没梯子想动手的小伙伴都可以尝试这个流程,当然有不想动手的,文章末尾的链接直接下载好使用就好了,但我还是希望大家动动手,因为我这绝对是到现在为止最详细的教程,之后我也会在B站录制视频演示流程。
接着往下,等我们把文件都替换好了之后,点击configure,完成之后,看看还有没有提示你要阅读这个CMakeDownload.txt查看细节,有的话继续重复步骤下就好了。(每个opencv版本的文件都不一样,不是通用的,如果看到我这篇博客的道友们用的是4.8.0或者更老的版本,就只能自己手动下了,但是流程是一样的,这是我配置了不下10次总结出来的,跨平台的opencv我也配置好多次了,因为vscode的代码看起来更舒服,而且MSVC跨平台没有g++好)。
当txt文件configure完成之后成这个样子了,就算真正意义上的configure成功了,建议多configure几次,可能一次之后还是会有提示一些其他的,你就接着configure就完事了,没提示你要下载就说明文件齐全了,另外两个警告不用管,一个是跟python相关的,我们不用python,还有一个是CMP0148,这个是cmake新版本之后出的警告,感兴趣的可以去cmake官网或者GitHub上的cmake仓库看文档。
当上面的过程确定成功了,就可以开始generate了,generate done之后
点图上这个圈圈,然后vs2022就会打开:
按照图上点生成,注意上面那个Debug,如果你选Debug就是调试模式,release就是发布模式,所以这里你需要生成两边,注意要选x64。
这是生成时候的截图, 可以看到cpu基本全被用了,这里可能有一个问题,如果是运存8g的电脑,建议弄的时候把QQ,微信那些都给关了,腾出运存空间,因为我见过有8g内存的生成的时候直接卡住了,相当于是说内存爆了,就无法生成,如果说喜欢动手的小伙伴遇到了这个问题,那么我建议重启电脑之后打开这个生成,腾出你最大的运存空间,如果实在不行的话,就直接用我给你搞好的库吧,人生路途总是充满遗憾和不完美的。
两种模式都生成成功之后,可以看到刚刚install文件下生成了许多lib文件:
路径的话就是 opencv-windows\install\x64\vc17\lib,我的是这样,你的对应你的就好了,可以看到很多lib文件,具体lib文件和dll文件的区别建议去网上看看,也挺重要的。如果,在configure的时候你选择了opencv_world, 那么你的lib库应该就只有opencv_world470,opencv_world470d,opencv_img_hash470,opencv_img_hash470d这四个ilb文件。
接下来我们就要让vs2022能找到opencv库,从而进行调用。首先,我们把install文件夹单独拿出来,然后改一个你喜欢的名字,能表示这是opencv库,只要install这一个文件夹,是因为我们把整个项目在install文件夹里生成了,这样所有的库文件都已经重新生成到这里了,包括把源码制作成库,我这里是改成了opencv_Library
紧接着我们需要把库里bin文件夹给放进环境变量里,这个操作我就不多说了,里面装的是lib文件的应用扩展,方便vs自己找到调用库。
是这一个bin不是你一打开就出现的那个bin文件夹。
弄好之后打开我们之前创建的解决方案,然后按照图中打开属性管理器:
存放路径我选择放在opencv库同一级目录:
创建完之后应该是这样:
可以发现多了两个props属性表,而且已经保存了,我们以Debug这个属性表为例:
包含目录就是opencv库头文件的目录就是 opencv_Library\include和
opencv_Library\include\opencv2,这里按照你们的路径写,添加两次,目的就是让编译器预编译时知道opencv库头文件在哪,库目录就是那个装lib文件的文件夹,添加就好。
然后跟着标注走,依赖项这里把你的lib文件给添加进去,注意,要一个个添加,如果是一行,每一个文件末尾要加分号隔开。这里选择集成库的就很简单,添加两个库就好了,没集成的,可以一次性全部添加,自己学习的时候可以这样搞,做项目的时候建议还是单独加你需要的库,一般添加几个核心库,剩下库看你添加了什么头文件就添加啥库,基本名字有类似的。不过这里要注意,Debug的属性表就只添加带d的lib文件到附加依赖项。当然有没有集成库的小伙伴说那么多一个个复制粘贴累死了,没关系,我已经贴心的为你准备好了,txt文档,将文件名称分成了两组方便你添加:
看,就是这个,是不是觉得我很贴心,很细节,正在看文章的女生不要太感动哦。配置好了以后,每次创建新的项目就往项目的属性管理器里面添加这两个属性表就搞定了,只要你之前弄得东西路径都正确
在我们弄完一切之后,我们可以开始写程序了。 这里网上找一段代码,这段代码链接:
https://www.cnblogs.com/gmhappy/p/9472402.html
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
//计算原始图像点位在经过矩阵变换后在目标图像上对应位置
Point2f getTransformPoint(const Point2f originalPoint, const Mat& transformMaxtri);
int main(int argc, char* argv[])
{
Mat image01 = imread("Resources/Parking1.png");
Mat image02 = imread("Resources/Parking2.png");
imshow("拼接图像1", image01);
imshow("拼接图像2", image02);
//灰度图转换
Mat image1, image2;
cvtColor(image01, image1, COLOR_BGR2GRAY);
cvtColor(image02, image2, COLOR_BGR2GRAY);
//提取特征点
PtrsiftDetector = SIFT::create(800); // 海塞矩阵阈值
vector keyPoint1, keyPoint2;
Mat imageDesc1, imageDesc2;
siftDetector->detectAndCompute(image1, Mat(), keyPoint1, imageDesc1, false);
siftDetector->detectAndCompute(image2, Mat(), keyPoint2, imageDesc2, false);
//获得匹配特征点,并提取最优配对
FlannBasedMatcher matcher;
vector matchePoints;
matcher.match(imageDesc1, imageDesc2, matchePoints, Mat());
sort(matchePoints.begin(), matchePoints.end()); //特征点排序
//获取排在前N个的最优匹配特征点
vector imagePoints1, imagePoints2;
for (int i = 0; i < 10; i++)
{
imagePoints1.push_back(keyPoint1[matchePoints[i].queryIdx].pt);
imagePoints2.push_back(keyPoint2[matchePoints[i].trainIdx].pt);
}
//获取图像1到图像2的投影映射矩阵,尺寸为3*3
Mat homo = findHomography(imagePoints1, imagePoints2, RANSAC);
Mat adjustMat = (Mat_(3, 3) << 1.0, 0, image01.cols, 0, 1.0, 0, 0, 0, 1.0);
Mat adjustHomo = adjustMat * homo;
//获取最强配对点在原始图像和矩阵变换后图像上的对应位置,用于图像拼接点的定位
Point2f originalLinkPoint, targetLinkPoint, basedImagePoint;
originalLinkPoint = keyPoint1[matchePoints[0].queryIdx].pt;
targetLinkPoint = getTransformPoint(originalLinkPoint, adjustHomo);
basedImagePoint = keyPoint2[matchePoints[0].trainIdx].pt;
//图像配准
Mat imageTransform1;
warpPerspective(image01, imageTransform1, adjustMat * homo, Size(image02.cols + image01.cols + 10, image02.rows));
//在最强匹配点的位置处衔接,最强匹配点左侧是图1,右侧是图2,这样直接替换图像衔接不好,光线有突变
Mat ROIMat = image02(Rect(Point(basedImagePoint.x, 0), Point(image02.cols, image02.rows)));
ROIMat.copyTo(Mat(imageTransform1, Rect(targetLinkPoint.x, 0, image02.cols - basedImagePoint.x + 1, image02.rows)));
namedWindow("拼接结果", 0);
imshow("拼接结果", imageTransform1);
waitKey();
return 0;
}
//计算原始图像点位在经过矩阵变换后在目标图像上对应位置
Point2f getTransformPoint(const Point2f originalPoint, const Mat& transformMaxtri)
{
Mat originelP, targetP;
originelP = (Mat_(3, 1) << originalPoint.x, originalPoint.y, 1.0);
targetP = transformMaxtri * originelP;
float x = targetP.at(0, 0) / targetP.at(2, 0);
float y = targetP.at(1, 0) / targetP.at(2, 0);
return Point2f(x, y);
}
直接复制,然后记得把image1和image02的读取路径弄一下,图片直接可以从上面的链接找到,下面是演示图:
可以看到程序很好的跑出来了,所以我们的配置就到此结束啦。
链接:https://pan.baidu.com/s/1UNKUQktdEi0jOc2JH0wy1g?pwd=0329
提取码:0329
复制这段内容后打开百度网盘手机App,操作更方便哦