一、楔子:叹世道多艰难,晓人间无两全
总所周知,
V
S
VS
VS是世界上最强大的
I
D
E
IDE
IDE没有之一,不允许反驳。但是好用归好用,
V
S
VS
VS庞大的体型以及运行时略显臃肿的速度都劝退好大一部分人。总之这个这个编译器是真的好用,但是,他的体型让我望而却步,这几天有一个需要用到
o
p
e
n
C
V
openCV
openCV的一段程序,于是我满心欢喜的打开baidu.com
,准备一步一步跟着他走,我本意是想摆脱
V
S
VS
VS,只用到命令行的编译就能完成程序的编译,并且能够成功运行。这是我最原始的想法。无奈网上全部都是微软信仰者,全部都推荐使用
V
S
VS
VS,我就纳闷了,难道就没有人使用
V
S
C
o
d
e
VS\quad Code
VSCode开发,平时直接一行clang++ a.cpp -o a.exe
完成编译,多么痛快!!看来今天是不行了,完全找不到,一点思路都没有。最有帮助的还是这个人的回答:
好吧,即然没有相关的教程,我就不去自己瞎折腾了,我还是老老实实的使用 V S VS VS吧,具体的配置请参考这篇博文,写的十分的详细。十分走心,好啦,今天的博客就写到这里了。
再见!
如果到这里就结束了,那这个肯定不是我写的blog了。
二、曲折:料潇洒走一回,惜一切都成空
“命运总是颠沛流离, 命运总是曲折离奇” ——李克勤
一句话道出真谛。我折腾了半天,终于在 V S VS VS中配置好了 O p e n C V OpenCV OpenCV的相关的配置,而且用的很爽。其实也没有那么爽了,在此期间我又遇到一个问题,也是找遍全网没找到答案。很迷。这个问题稍后再说。
问题不会这么轻易的就完了,我原来的写的代码在 V S VS VS的环境之下,编译根本跑不出结果!!!原来使用 c l a n g + + clang++ clang++编译的时候贼 h a p p y happy happy, 运行的时候也一点不含糊。现在到了终极无敌编译器之后我还是不会用。。折腾了半天,还是没能弄好,最后我妥协了。我还是决定不用 V S VS VS安装 O p e n C V OpenCV OpenCV 。
三、突破:山穷水尽时,柳暗花明处
我抓起自己的小脑瓜子一想,脑中浮现一个念头——不就是需要包含的头文件需要指定一个路径,还有一个库目录需要指定路径。最后还有一个链接的库需要进行链接么?无非就是使用 V S VS VS之后,以上我考虑的这些问题搜能被傻瓜式解决。那么为什么我就不能自己手动指定这些内容呢??
一想到这里,我轻轻将自己头发向后一捋顺。将搜索词从安装opencv on Windows
⟹
\Longrightarrow
⟹clang指定库目录路径
。然后我就发现了宝藏,厉害了,这不就是我想要的么!??先留着,自己先试一试,拿出以下代码,试了一下
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat image = imread("P70507-091122.jpg");
imshow("image", image);
waitKey(33);
return 0;
}
在命令行下输入以下的编译语句:
clang++ demo.cpp -o demo.exe -I D:/opencv/build/include/ -L D:/opencv/build/x64/vc15/lib/
我来说明一下,以上的命令中的
-I
后面的内容是我们的 O p e n C V OpenCV OpenCV的解压目录的 i n c l u d e include include文件夹,是 i n c l u d e include include的缩写;此外对于-L
后面的表示 O p e n C V OpenCV OpenCV的 L i b Lib Lib库的目录
然后满心欢喜又期待的等着出现编译成功的提示:结果出现了以下的???
demo-9ed11b.o : warning LNK4217: 本地定义的符号 __std_terminate 在函数 "int `public: __cdecl cv::String::~String(void)'::`1'::dtor$2" (?dtor$2@?0???1String@cv@@QEAA@XZ@4HA) 中导入
demo-9ed11b.o : warning LNK4217: 本地定义的符号 _CxxThrowException 在函数 "public: void __cdecl std::ios_base::clear(int,bool)" (?clear@ios_base@std@@QEAAXH_N@Z) 中导入
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "class cv::Mat __cdecl cv::imread(class cv::String const &,int)" (?imread@cv@@YA?AVMat@1@AEBVString@1@H@Z),该符号在函数 main 中被引用
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "void __cdecl cv::imshow(class cv::String const &,class cv::_InputArray const &)" (?imshow@cv@@YAXAEBVString@1@AEBV_InputArray@1@@Z),该符号在函数 main 中被引用
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "int __cdecl cv::waitKey(int)" (?waitKey@cv@@YAHH@Z),该符号在函数 main 中被引用
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "private: char * __cdecl cv::String::allocate(unsigned __int64)" (?allocate@String@cv@@AEAAPEAD_K@Z),该符号在函数 "public: __cdecl cv::String::String(char const *)" (??0String@cv@@QEAA@PEBD@Z) 中被引用
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "private: void __cdecl cv::String::deallocate(void)" (?deallocate@String@cv@@AEAAXXZ),该符号在函数 "public: __cdecl cv::String::~String(void)" (??1String@cv@@QEAA@XZ) 中被引用
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "void __cdecl cv::fastFree(void *)" (?fastFree@cv@@YAXPEAX@Z),该符号在函数 "public: __cdecl cv::Mat::~Mat(void)" (??1Mat@cv@@QEAA@XZ) 中被引用
demo-9ed11b.o : error LNK2019: 无法解析的外部符号 "public: void __cdecl cv::Mat::deallocate(void)" (?deallocate@Mat@cv@@QEAAXXZ),该符号在函数 "public: void __cdecl cv::Mat::release(void)" (?release@Mat@cv@@QEAAXXZ) 中被引用
demo.exe : fatal error LNK1120: 7 个无法解析的外部命令
clang++.exe: error: linker command failed with exit code 1120 (use -v to see invocation)
看以上的提示,就是 c l a n g + + clang++ clang++没有链接成功。于是我们想到在 V S VS VS中配置的时候还有一个链接的操作,这样一来,我们接着浏览器搜索,又发现了宝藏!!直接在前面添加需要链接的库 o p e n c v w o r l d 341 d . l i b opencv_world341d.lib opencvworld341d.lib和 o p e n c v w o r l d 341. l i b opencv_world341.lib opencvworld341.lib就完成。
完整的代码如下:
#pragma comment(lib, "opencv_world341d.lib")
#pragma comment(lib, "opencv_world341.lib")
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat image = imread("P70507-091122.jpg");
imshow("image", image);
waitKey(33);
return 0;
}
看到没有!!编译通过!!!
运行一下,结果很满意!!!
四、升级:晓尘埃落定,笑看云起时
我又接着尝试了一下,看能不能完成视频的播放什么的,于是乎写出如下的代码:
#pragma comment(lib, "opencv_world341d.lib")
#pragma comment(lib, "opencv_world341.lib")
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
CvCapture * g_capture;
int g_slider_pos = 0;
void on_drag(int pos)
{
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
g_slider_pos = pos;
}
int main()
{
g_capture = cvCreateFileCapture("vtest.avi");
cvNamedWindow("video");
IplImage* frame;
int frames = cvGetCaptureProperty(g_capture, CV_CAP_PROP_FRAME_COUNT);
if (frames > 0)
{
cvCreateTrackbar("position", "video", &g_slider_pos, frames, on_drag);
}
while (true)
{
frame = cvQueryFrame(g_capture);
if (!frame)
{
break;
}
cvShowImage("video", frame);
if (cvWaitKey(33) == 27)
{
break;
}
cvSetTrackbarPos("position", "video", g_slider_pos);
g_slider_pos += 1;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("video");
return 0;
}
丝滑!!
五、后记:走出半生,归来少年
大家可能在编码的时候出现这样的问题。经过我的调查与研究——这个错误的原因主要是因为堆栈释放出错的问题!对于C++这种程序员掌握一切的语言,内存什么的还是需要好好的释放。这种情况要么是内存没释放,要么是内存释放多次,在我这里是因为我申请了一个windows空间没但是最后并没有释放的原因。详细见一下代码:
原始的代码:
cv::namedWindow("image");
...
cv::polylines(image, points_fitted, false, cv::Scalar(0, 255, 255), 1, 8, 0);
cv::imshow("image", image);
cv::waitKey(10);
return 0;
修改后的代码:
cv::polylines(image, points_fitted, false, cv::Scalar(0, 255, 255), 1, 8, 0);
cv::imshow("image", image);
cv::waitKey(10);
cv::destroyWindow("image");
return 0;