目录
附录
- 下载的cmake-gui版本是3.22.1,cmake版本的下载很简单,在官网上下载就可以,只要是3以上版本的都可以,没有太多要求。
- opencv_contrib下载,在https://github.com/search?q=opencv 上下载就可以。这个是扩展库的文件。
首先设置路径:
第一次点击configure:,会出现以下界面,自动识别VS版本,默认是x64,不需要改动。第一次时间可能较长,也会出现缺少ffmpeg等文件的错误:
这种错误是由网络原因引起的未下载成功问题,需要到newbulid文件夹中找到CMakeDownloadLog.txt文件,根据文件中的错误提示下载缺失文件,具体可见此博客,我下载时data、ffmpeg、ippicv、wechat_qrcode、xfeatures2d出错了,网上有很多方法下载,我是直接在https://github.com/opencv/opencv_3rdparty 上下载,一定是这个模块。你可以根据CMakeDownloadLog.txt文件的提示下载相同的版本,或者自己选择下载哪个版本(只要你下载版本的MD5是匹配的就是可以的),MD5的修改见 此博客 。这个过程比较繁琐,需要将未成功下载文件全部下载,需要耐心看CMakeDownloadLog.txt文件,温馨提示:最好每configure后就查看一下CMakeDownloadLog.txt,我会将我失败的缺失文件放在附录中(如ffmpeg可能存在版本不同的问题),等到configure不出现此类错误时,CMakeDownloadLog.txt文件的正确输出见下图。
除了此类错误,还会有关python的错误,经过上网查找及实践可以忽略这个错误,不用管就可以了。
接下来需要勾选以下选项nonfree(使用SURF算法的版权);还需要设置extra_module路径(一定要找到modules文件夹,否则保存,且不要复制路径,直接通过选项卡选择)。
设置完之后进行——generate(成功后显示generating done.),可以检查CMakeDownloadLog.txt文件是否有错误提示,争取之后编译时不重复编译。编译完成后直接Open Project.(完成项目的个数与你缺失文件是否成功下载以及是否在cmake中勾选其他选项有关(CUDA等)),我生成了好多次,成功的是181个,失败的时候数目较少。
补充:有的博客说将(world)选项勾上,勾上的目的是为了将所有生成的库的lib和dlib文件放在一个文件里,诸如图2这种形式,这样在项目配置时——链接器输入时只需要添加一个文件就可以了,但是一旦出现错误很难看出在生成哪个lib时出错,如果会出现很多错误,不建议将此勾上;反之,会生成很多lib文件图3,添加时较麻烦(有简单的添加方法),但可以清楚的知道哪个lib文件生成错误。
图2
图3
接下来进行对新工程生成解决方案,我借鉴了以下博客:博客1,博客2,第一次生成的时候很慢,由于电脑性能的问题,差不多将近1个小时,成功了一百出头个,失败了很多,而且错误显示有没有成功生成的lib和dlib文件。接下来描述一下我如何解决的,大家避免入坑:
- 第一次批生成解决方案后,如果想要重新尝试的一定要——清理解决方案,否则你的文件占用内存会越来越大,而且出错数会越来越多(经过许多次的尝试)的血泪教训。
- 如果出现错误较少的话,方法:找到错误文件,对错误文件进行修改后单独进行——重新生成解决方案(不要忘记清理解决方案),见下图右,否则生成整个太浪费时间了。
- 但是如果出现错误较多的话,重新生成解决方案也不能解决问题,这时如果你非常有耐心,可以逐个查debug,主要是可能存在的文件在下载的过程中出现问题(我出现的就是某个cpp文件 注释变成代码了 ,我是通过error找到源文件,发现有错误,一开始走了很多弯路以为是宏的问题,后来在github上找到对应该文件的源码,发现是在下载的过程中/* */ 变成了代码,如果大家有此类问题,一定要耐下心去找一下源码)。
- 我建议的是不要批生成,在debug和release下分别生成解决方案,在debug下为例示范,这样生成方便查出错误,在All_Bulid全部生成成功时(忽略的可以不管,是我们没有用到的JAVA等),但不能有错误,否则之后Install(ALL_Build下方)时就会出问题!
- 在单独生成的过程中,请大家一定要保证C盘的空间至少有15G,重点强调!!!!!(否则会出现大量的堆内存不够的error,直接卡出程序,bug多到你无法处理),重要的事情说三遍!!!!,C盘空间要足!!!!!!
- 如果这些错误您都已经解决了,可能会在release ALL_Build时时遇到有关:“Cmake:MSB8066自定义生成退出”,我当时是找到了出错源文件,在网上查找资料,但有关MSB8066的资料太少了,好长时间卡在这里,我尝试了很多次打开工程、重新对该文件进行生成、清理等过程;偶然的一次尝试,这个错误消除了,官方是说要查找:D:\opencv_latest\opencv\newbulid\CMakeFiles 下的 CMakeOutput.log 文件。这个错误我是通过多次尝试生成与清理错误文件完成的。
- 如果debug和release下均成功install,说明在编译环节已经完成,可以在一下路径中查看是否有lid和dlib文件;
D:\opencv_latest\opencv\newbulid\install\x64\vc16\lib
注意:在编译过程会出现此类警告:warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失,此类warning不需要考虑,我花费了大量时间处理此类warning,不仅浪费时间反而产生更多的error,不过可以不显示此类warning。
如果您进行到这一步,就说明距离成功不远了,但不能掉以轻心。参考这篇博客 这篇博客设置环境变量与配置,在此只说明我自己遇到的问题:
- 我们是只在Debugx64中新建了属性表,所以在设置附加依赖项时,一定只添加 (d.lib),否则在测试源码时无法正确读入(imread 图片),参见此博客。如果您遇到在测试源码时遇到:Windows下OpenCV库运行出错, 加载opencv_highgui_gtk453_64.dll失败,或者 Error: Assertion failed (!_src.empty()) in cv::cvtColor 错误,一定要重新装载附加依赖项,在debug中只放置d.lib文件。您可以在Project1 属性页中设置 Release 下的附加依赖项(只装载.lib文件)。
注意:提取.lib 和d.lib文件的方法 :
直接复制到附加依赖项中(debug:d.lib||||||||||||||||||||||||||release:.lib)
测试文件1:
//修改图像路径
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
//#include <opencv2/>
using namespace std;
using namespace cv;
int main()
{
cv::Mat imageL = cv::imread("origin_1.jpg");
cv::Mat imageR = cv::imread("origin_2.jpg");
/*imshow("1", imageL);
imshow("2", imageR);
waitKey();
return 0;*/
//提取特征点方法
//SIFT
cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create();
//ORB
//cv::Ptr<cv::ORB> orb = cv::ORB::create();
//SURF
//cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create();
//特征点
std::vector<cv::KeyPoint> keyPointL, keyPointR;
//单独提取特征点
sift->detect(imageL, keyPointL);
sift->detect(imageR, keyPointR);
//画特征点
cv::Mat keyPointImageL;
cv::Mat keyPointImageR;
drawKeypoints(imageL, keyPointL, keyPointImageL, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(imageR, keyPointR, keyPointImageR, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//显示窗口
cv::namedWindow("KeyPoints of imageL");
cv::namedWindow("KeyPoints of imageR");
//显示特征点
cv::imshow("KeyPoints of imageL", keyPointImageL);
cv::imshow("KeyPoints of imageR", keyPointImageR);
//特征点匹配
cv::Mat despL, despR;
//提取特征点并计算特征描述子
sift->detectAndCompute(imageL, cv::Mat(), keyPointL, despL);
sift->detectAndCompute(imageR, cv::Mat(), keyPointR, despR);
//Struct for DMatch: query descriptor index, train descriptor index, train image index and distance between descriptors.
//int queryIdx –>是测试图像的特征点描述符( descriptor )的下标,同时也是描述符对应特征点(keypoint)的下标。
//int trainIdx –> 是样本图像的特征点描述符的下标,同样也是相应的特征点的下标。
//int imgIdx –>当样本是多张图像的话有用。
//float distance –>代表这一对匹配的特征点描述符(本质是向量)的欧氏距离,数值越小也就说明两个特征点越相像。
std::vector<cv::DMatch> matches;
//如果采用 flannBased 方法 那么 desp通过orb的到的类型不同需要先转换类型
if (despL.type() != CV_32F || despR.type() != CV_32F)
{
despL.convertTo(despL, CV_32F);
despR.convertTo(despR, CV_32F);
}
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased");
matcher->match(despL, despR, matches);
//计算特征点距离的最大值
double maxDist = 0;
for (int i = 0; i < despL.rows; i++)
{
double dist = matches[i].distance;
if (dist > maxDist)
maxDist = dist;
}
//挑选好的匹配点
std::vector< cv::DMatch > good_matches;
for (int i = 0; i < despL.rows; i++)
{
if (matches[i].distance < 0.5 * maxDist)
{
good_matches.push_back(matches[i]);
}
}
cv::Mat imageOutput;
cv::drawMatches(imageL, keyPointL, imageR, keyPointR, good_matches, imageOutput);
cv::namedWindow("picture of matching");
cv::imshow("picture of matching", imageOutput);
cv::waitKey(0);
return 0;
}
测试文件2:
//修改图像路径
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
using namespace cv::ximgproc;
int main(int argc, char** argv)
{
//在工程目录下放一张名字为"01.jpg"的图片
Mat image = imread("01.jpg", IMREAD_GRAYSCALE);
imshow("Input", image);
if (image.empty())
{
return -1;
}
Ptr<LineSegmentDetector> lsd = createLineSegmentDetector();
vector<Vec4f> lines_lsd;
int length_threshold = 10;
float distance_threshold = 1.41421356f;
double canny_th1 = 50.0;
double canny_th2 = 50.0;
int canny_aperture_size = 3;
bool do_merge = false;
Ptr<FastLineDetector> fld = createFastLineDetector(length_threshold,
distance_threshold, canny_th1, canny_th2, canny_aperture_size,
do_merge);
vector<Vec4f> lines_fld;
for (int run_count = 0; run_count < 10; run_count++)
{
lines_lsd.clear();
int64 start_lsd = getTickCount();
lsd->detect(image, lines_lsd);
// Detect the lines with LSD
double freq = getTickFrequency();
double duration_ms_lsd = double(getTickCount() - start_lsd) * 1000 / freq;
}
// Show found lines with LSD
Mat line_image_lsd(image);
lsd->drawSegments(line_image_lsd, lines_lsd);
imshow("LSD result", line_image_lsd);
waitKey(0);
return 0;
}
附录:
强调版本为4.5.4(网盘自取:链接:https://pan.baidu.com/s/1GVgJgznYB_htcMOxDZVeIg
提取码:2002)