OpenCv在win下靜態庫的編譯和使用,以及部分無法解析外部符號的錯誤解決
這裡演示的是opencv3.4版本的編譯和使用過程。
1、靜態庫編譯
CMake進行配置,編譯時我選擇build目錄為build-static。
其中需要設定
選擇安裝目錄,設定 “CMAKE_INSTALL_PREFIX” 為 /build-static/install (這裡是自動選擇的,可自行更改)
編譯靜態庫,取消勾選 “BUILD_SHARED_LIBS”
另外,可以選擇勾選 BUILD_opencv_world, 好處是工程新增依賴項只有一個,壞處是這個lib會非常大。(我這裡選擇了編譯生成opencv_world).
配置完成,在vs中編譯專案 install 即可。我的生成結果(包括debug和release的2個庫)如下:
2、靜態庫使用
新建一個專案,我這裡為了顯示明顯,lib依賴庫的匯入採用在原始檔中編寫 #pragma comment( lib, "***" ) 的形式,也可以在專案屬性依賴項中新增(如果之前編譯opencv沒有選擇opencv_world,這裡就需要加入工程中需要的lib,專案龐大時,需要新增其他模組的lib, opencv2版本就是這樣)。這裡的專案是Release版,所以後面的lib都是不帶d的,注意區分。
#include <opencv2/opencv.hpp> #pragma comment(lib,"IlmImf.lib") #pragma comment(lib,"ippicvmt.lib") #pragma comment(lib,"ippiw.lib") #pragma comment(lib,"ittnotify.lib") #pragma comment(lib,"libjasper.lib") #pragma comment(lib,"libjpeg.lib") #pragma comment(lib,"libpng.lib") #pragma comment(lib,"libtiff.lib") #pragma comment(lib,"libwebp.lib") #pragma comment(lib,"zlib.lib") #pragma comment(lib,"opencv_world340.lib") using namespace cv; using namespace std; int main() { Mat img = imread("1.jpg"); imshow("test", img); Mat gray; cvtColor(img, gray, cv::COLOR_BGR2GRAY); imshow("g", gray); waitKey(0); }
編譯時,可能會提示很多關於cuda的符號無法解析,比如cudaDevice 、cudaEvent、cudaGetError、cudaHost、cudaMemory、cudaStream、cudaRegister等等。下圖是部分錯誤截圖,在檔案列中可以看到對應的obj檔案。
這個錯誤是因為我們在編譯opencv時使用了cuda,現在簡單的度圖片顯示的專案載入opencv靜態庫後,還需要加入cuda的靜態庫。(如果opencv未使用cuda,這裡就不會有該錯誤了)
那麼加入下一行,即可解決以上錯誤。
#pragma comment(lib,"C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/x64/cudart_static.lib")
另外如果是讀攝像頭的程式,會出現其他的無法解析符號錯誤,如ICOpen、ICClose、AVIFile、AVIStream等,同樣注意檔案列提示。
opencv專案編譯生成的相關的靜態庫都已經全部加入,但是仍然不能通過。說明還有其他庫沒有新增進來。可以看到,這些未解析的符號,都是來自於cap_vfw.obj檔案,那麼我們進一步需要加入win32下的一個庫,也就是新增下一行
#pragma comment( lib, "vfw32.lib" )
新增之後,編譯正常。
Tips: 如果出現其他符號未解析,都是缺少依賴庫的原因,可以根據錯誤提示找到需要新增的庫並加入就行。