1. 程式人生 > >OpenCV_Viz——OpenCV中Viz的模組編譯的無法解析的外部符號BUG

OpenCV_Viz——OpenCV中Viz的模組編譯的無法解析的外部符號BUG

寫在前面

由於實驗室需要,需要重新編譯醫學影象第三方庫全家桶。這裡就需要編譯OpenCV,而編譯後檢視編譯的庫檔案中缺少一個opencv_viz2413d.lib檔案(沒錯,這裡可以看出我使用的OpenCV是opencv-2.4.13.6版本)。所以需要額外重新編譯這個庫。首先就會遇到一個問題:預設的OpenCV編譯模組中是沒有Viz的。經過我之前成功編譯的CMAKE配置檔案仔細對比,發現需要以來VTK庫。後面會詳細敘述。先羅列一下我的環境資訊:

  • OpenCV:2.4.13.6
  • VTK:8.1.1
  • CMAKE:3.11.2
  • VS:VS2015_x64

此外,由於已經成功編譯了,這個部落格也不是一個教程,所以圖相對缺乏,下面補一些其它相關類似的部落格,可供參考:

我沒說清楚的,或者大家存疑的地方可以參考以上一些部落格,都是中文的,應該會有些幫助。

OpenCV_viz

要編譯這個模組,需要依賴VTK庫,所以需要在CMAKE中(提前勾選Grouped與Advanced,就在Search旁邊),如下所示: 在這裡插入圖片描述

先勾選WITH_VTK,之後,點選Configure,就會出現VTK_DIR,然後需要選擇之前編譯好的VTK庫的路徑。其實這裡是要找VTKConfig.cmake檔案存在的路徑。這裡的VTKConfig.cmake是編譯通過後的,install的VTK的庫,而不是直接CMAKE configure產生的VTK編譯檔案。

使用Everything軟體能很方便的找到所需要的檔案(這個我是怕我以後忘了,多說一句)。

這樣配置好以後,點選Configure,然後Generate,Open Project,就會開啟對應的OpenCV工程,可以編譯。

編譯OpenCV工程

編譯工程時其他庫沒有什麼問題,出問題的是opencv_viz庫,然後由於opencv_viz庫出問題,導致其測試的庫:opencv_test_viz也有問題。但總的說,就是opencv_viz庫有問題。具體的問題與下面的類似:

1>     Creating library D:/opencv-build2/lib/Release/opencv_viz2413.lib and object D:/opencv-build2/lib/Release/opencv_viz2413.exp
1>vizcore.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class vtkOBJReader * __cdecl vtkOBJReader::New(void)" (
[email protected]
@@[email protected]) referenced in function "public: static class vtkSmartPointer<class vtkOBJReader> __cdecl vtkSmartPointer<class vtkOBJReader>::New(void)" ([email protected][email protected]@@@@[email protected]) 1>vizcore.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class vtkOBJReader * __cdecl vtkOBJReader::SafeDownCast(class vtkObjectBase *)" ([email protected]@@[email protected]@@@Z) referenced in function "class cv::Mat __cdecl cv::viz::readCloud(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class cv::_OutputArray const &,class cv::_OutputArray const &)" ([email protected]@[email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]) 1>vizcore.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class vtkSTLReader * __cdecl vtkSTLReader::SafeDownCast(class vtkObjectBase *)" ([email protected]@@[email protected]@@@Z) referenced in function "class cv::Mat __cdecl cv::viz::readCloud(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class cv::_OutputArray const &,class cv::_OutputArray const &)" ([email protected]@[email protected]@[email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]) 1>vizcore.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class vtkSTLReader * __cdecl vtkSTLReader::New(void)" ([email protected]@@[email protected]) referenced in function "public: static class vtkSmartPointer<class vtkSTLReader> __cdecl vtkSmartPointer<class vtkSTLReader>::New(void)" ([email protected][email protected]@@@@[email protected]) 1>D:\opencv-build2\bin\Release\opencv_viz2413.dll : fatal error LNK1120: 4 unresolved externals

總之就是無法解析的外部符號的LNK2019錯誤。這種問題目前我遇到的一般是lib庫包含有問題。但根據錯誤資訊,只能隱約知道是vtkOBJReader與vtkSTLReader兩個有問題。在電腦上搜索了一下,發現都有對應的標頭檔案。但是缺少對於的lib庫。

由於VTK編譯應該不會有問題,所以這裡可能是在VTK其他庫中使用到了這兩個標頭檔案。

所以下面就是我寫這篇部落格的重點。如何根據錯誤資訊找到缺少對應的lib庫檔案。我目前的經驗是:

根據原始檔程式碼結構來查詢。

比如這裡的VTK,查詢vtkOBJReader.h與vtkSTLReader.h兩個標頭檔案,發現都在VTK-8.1.1\IO\Geometry檔案中,那就找找看有沒有跟IO 與 Geometry相關的lib。可以使用萬用字元幫助查詢。結果就找到了vtkIOGeometry.lib.這個庫。然後檢視opencv_viz這個專案的屬性,發現沒有這個庫。新增,嘗試重新編譯這個專案,結果通過。所以這個BUG就解決了。

寫在後面

我一直很頭疼,不知道如何根據VS提供的錯誤資訊找到錯誤的解決方法。這算是一種經驗的積累吧。雖然定位錯誤的方法以猜居多。如果讀者看到了我這種不成熟的方法,希望能多多批評指正。謝謝大家。