Opencv中3D顯示模塊viz安裝
前言
最近工作需要在VS2105中調用opencv的3D顯示模塊viz,默認情況下,opencv點安裝是不會自動安裝viz模塊的
關於viz模塊,首先要取決於opencv的版本;在opencv4.0之前的版本,對應的opencv_contrib中是沒有viz模塊的,則需要從vtk包中獲取,即先編譯vtk,再編譯opencv;而opencv4.0起,viz模塊被移植進opencv_contrib中了,所以只需要加上opencv_contrib編譯opencv即可
既然需要手動編譯,那麼cmake神器必不可少,個人整體環境如下:
Win10,x64
VS2015
cmake1.13,opencv3.4.4,vtk8.2,opencv4.0,opencv_contrib4.0(戳這裏下載, 提取碼:funk )
安裝cmake
本文使用的cmake是事先編譯好的exe,所以不需要安裝了,有需要從上文連接下載即可;若自己安裝也非常簡單,同一般安裝程序一樣,下一步即可
解壓cmake包,打開bin目錄下的cmake-gui.exe
編譯viz
1)解壓VTK-8.2.0.zip
2)cmake配置
3)Generate(選擇vs2015編譯器)
4)選項配置
A:選中BUILD_SHARED_LIBS(默認)
B:取消BUILD_EXAMPLES(默認),如果深入研究VTK的同學,可以勾選上,學學例子
C:取消BUILD_TESTING(默認)
D:install路徑,默認C:/Program Files/VTK,默認安裝在C盤系統目錄下,當然我們也可以自己設置路徑:(我的在安裝包下VTK,這個可以自己隨意)
D:/program files/Opencv_vtk/VTK-8.2.0/VTK
E:再次generate(全部默認選項,不需要)
5)Configure,完全後就可關閉cmake了
6)打開build/VTK.sln
若Install路徑爲C盤系統,則需要用管理員權限打開,不然後面install時會因爲權限不夠報錯;若存在右鍵沒有管理員打開選項,則用管理員權限打開cmd,進入build目錄,運行VTK.sln
若爲自己設置的路徑,則不需要管理員權限,打開即可
7)選擇Debug或Release,默認爲Debug,根據自己需求,也可兩個分開都編譯出來
8)ALL_BUILD(點擊ALL_BUILD–>>生成,時間有點長)
9)INSTALL(點擊INSTALL–>>僅用於項目–>>僅生成INSTALL)
install後,VTK目錄(自己設置的install目錄,或默認C:/Program Files/VTK)就有了vtk相關頭文件,庫文件
10)Debug編譯出來後,備份庫文件,編譯Release版本;然後整理打包,頭文件相同,但庫文件不同,需要分開
編譯opencv
3.4.4
Opencv的編譯網上一大堆,本人前期博客也總結過,這裏就不詳述;只是再配置選項時,注意選上WITH_VTK
VTK_DIR:若安裝在C盤,cmake會自動找到;如自己設置路徑需要手動指定到自己install VTK的位置(D:/program files/Opencv_vtk/VTK-8.2.0/VTK/Release/lib/cmake/vtk-8.2)
然後打開OpenCV.sln,編譯ALL_BUILD,INSTALL
最後在build/install下就會看到我們想要的文件(檢查include下是否有viz就可以了)
4.0.0
這個就更簡單了,只需在配置選項時,指定contrib包的路徑即可(OPENCV_EXTRA_MOUDULES_PATH)
同上
VS2015測試
1)配置
這個網上也很多了,說白了就是告訴工程,需要加載的庫:頭文件在哪?,lib文件需要哪些?,dll文件在哪?
2)顯示3D手
下列代碼只是測試用,並不最優;需要注意的是多次調用showWidget(“id”, Line1)時,需要用不同的id,否則會覆蓋;當然viz裏面還有很多方法,這裏就不一一舉例
void Show3DPoint(std::vector<std::pair<std::string, std::vector<cv::Point3f>>> handFrame3DPoint
, float scale, float lineW, float circleR)
{
//初始化
cv::viz::Viz3d window("window");
//顯示座標系
window.showWidget("Coordinate", cv::viz::WCoordinateSystem());
for (int n = 0; n < handFrame3DPoint.size(); n++)
{
std::vector<cv::Point3f> line1, line2, line3, line4, line5;
cv::String hand(cv::format("%d", n));
for (int p = 0; p < handFrame3DPoint[n].second.size(); p++)
{
cv::String pt(cv::format("%d", p));
cv::Point3f point;
point.x = scale*handFrame3DPoint[n].second[p].x;
point.y = scale*handFrame3DPoint[n].second[p].y;
point.z = scale*handFrame3DPoint[n].second[p].z;
cv::Vec3d normal(0,0,1);
cv::viz::WCircle circle(scale*circleR, point, normal);
window.showWidget(hand + pt, circle);
if (p==0)
{
line1.push_back(point);
line2.push_back(point);
line3.push_back(point);
line4.push_back(point);
line5.push_back(point);
}
else if (p < 5)
line1.push_back(point);
else if (p < 9)
line2.push_back(point);
else if (p < 13)
line3.push_back(point);
else if (p < 17)
line4.push_back(point);
else
line5.push_back(point);
}
cv::viz::WPolyLine Line1(line1,cv::viz::Color::red());
Line1.setRenderingProperty(cv::viz::LINE_WIDTH, scale*lineW);
window.showWidget(hand + "line1", Line1);
cv::viz::WPolyLine Line2(line2, cv::viz::Color::yellow());
Line2.setRenderingProperty(cv::viz::LINE_WIDTH, scale*lineW);
window.showWidget(hand + "line2", Line2);
cv::viz::WPolyLine Line3(line3, cv::viz::Color::blue());
Line3.setRenderingProperty(cv::viz::LINE_WIDTH, scale*lineW);
window.showWidget(hand + "line3", Line3);
cv::viz::WPolyLine Line4(line4, cv::viz::Color::orange());
Line4.setRenderingProperty(cv::viz::LINE_WIDTH, scale*lineW);
window.showWidget(hand + "line4", Line4);
cv::viz::WPolyLine Line5(line5, cv::viz::Color::green());
Line5.setRenderingProperty(cv::viz::LINE_WIDTH, scale*lineW);
window.showWidget(hand + "line5", Line5);
}
while (!window.wasStopped())
{
window.spinOnce(1, true);
}
}
3)顯示結果