1. 程式人生 > >OpenCv在win下靜態庫的編譯和使用,以及部分無法解析外部符號的錯誤解決

OpenCv在win下靜態庫的編譯和使用,以及部分無法解析外部符號的錯誤解決

這裡演示的是opencv3.4版本的編譯和使用過程。

1、靜態庫編譯

CMake進行配置,編譯時我選擇build目錄為build-static。

image

其中需要設定

選擇安裝目錄,設定   “CMAKE_INSTALL_PREFIX”  為   /build-static/install   (這裡是自動選擇的,可自行更改)

編譯靜態庫,取消勾選 “BUILD_SHARED_LIBS”

另外,可以選擇勾選 BUILD_opencv_world, 好處是工程新增依賴項只有一個,壞處是這個lib會非常大。(我這裡選擇了編譯生成opencv_world).

配置完成,在vs中編譯專案 install 即可。我的生成結果(包括debug和release的2個庫)如下:

image  image

image

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檔案。

image

這個錯誤是因為我們在編譯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等,同樣注意檔案列提示。

image

   opencv專案編譯生成的相關的靜態庫都已經全部加入,但是仍然不能通過。說明還有其他庫沒有新增進來。可以看到,這些未解析的符號,都是來自於cap_vfw.obj檔案,那麼我們進一步需要加入win32下的一個庫,也就是新增下一行

#pragma comment( lib, "vfw32.lib" )

新增之後,編譯正常。

Tips: 如果出現其他符號未解析,都是缺少依賴庫的原因,可以根據錯誤提示找到需要新增的庫並加入就行。