一、楔子:嘆世道多艱難,曉人間無兩全
總所周知,是世界上最強大的沒有之一,不允許反駁。但是好用歸好用,龐大的體型以及運行時略顯臃腫的速度都勸退好大一部分人。總之這個這個編譯器是真的好用,但是哦昂他的體型讓我望而卻步,這幾天有一個需要用到的一段程序,於是我滿心歡喜的打開baidu.com
,準備一步一步跟着他走,我本意是想擺脫,只用到命令行的編譯就能完成程序的編譯,並且能夠成功運行。這是我最原始的想法。無奈網上全部都是微軟信仰者,全部都推薦使用,我就納悶了,難道就沒有人使用開發,平時直接一行clang++ a.cpp -o a.exe
完成編譯,多麼痛快!!看來今天是不行了,完全找不到,一點思路都沒有。最有幫助的還是這個人的回答:
好吧,即然沒有相關的教程,我就不去自己瞎折騰了,我還是老老實實的使用吧,具體的配置請參考這篇博文,寫的十分的詳細。十分走心,好啦,今天的博客就寫到這裏了。
再見!
如果到這裏就結束了,那這個肯定不是我寫的blog了。
二、曲折:料瀟灑走一回,惜一切都成空
“命運總是顛沛流離, 命運總是曲折離奇” ——李克勤
一句話道出真諦。我折騰了半天,終於在中配置好了的相關的配置,而且用的很爽。其實也沒有那麼爽了,在此期間我又遇到一個問題,也是找遍全網沒找到答案。很迷。這個問題稍後再說。
問題不會這麼輕易的就完了,我原來的寫的代碼在的環境之下,編譯根本跑不出結果!!!原來使用編譯的時候賊, 運行的時候也一點不含糊。現在到了終極無敵編譯器之後我還是不會用。。折騰了半天,還是沒能弄好,最後我妥協了。我還是決定不用安裝 。
三、突破:山窮水盡時,柳暗花明處
我抓起自己的小腦瓜子一想,腦中浮現一個念頭——不就是需要包含的頭文件需要指定一個路徑,還有一個庫目錄需要指定路徑。最後還有一個鏈接的庫需要進行鏈接麼?無非就是使用之後,以上我考慮的這些問題搜能被傻瓜式解決。那麼爲什麼我就不能自己手動指定這些內容呢??
一想到這裏,我輕輕將自己頭髮向後一捋順。將搜索詞從安裝opencv on Windows
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
後面的內容是我們的的解壓目錄的文件夾,是的縮寫;此外對於-L
後面的表示的庫的目錄
然後滿心歡喜又期待的等着出現編譯成功的提示:結果出現了以下的???
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)
看以上的提示,就是沒有鏈接成功。於是我們想到在中配置的時候還有一個鏈接的操作,這樣一來,我們接着瀏覽器搜索,又發現了寶藏!!直接在前面添加需要鏈接的庫和就完成。
完整的代碼如下:
#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;
}
絲滑!!