【opencv基础】OpenCV使用Viz模块3D可视化显示

code

bunny.ply

/**
 * @file transformations.cpp
 * @brief Visualizing cloud in different positions, coordinate frames, camera frustums
 * @author Ozan Cagri Tonkal
 */
#include <opencv2/viz.hpp>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;

/**
 * @function cvcloud_load
 * @brief load bunny.ply
 */
static Mat cvcloud_load()
{
    size_t num = 188;  // 1889.
    Mat cloud(1, num, CV_32FC3);
    ifstream ifs("../input/bunny.ply");

    string str;
    for(size_t i = 0; i < 12; ++i)
        getline(ifs, str);

    Point3f* data = cloud.ptr<cv::Point3f>();
    float dummy1, dummy2;
    for(size_t i = 0; i < num; ++i)
    {
        ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2;
        std::cout << "i: " << i << "-x: " << data[i].x << "-y: " << data[i].y << "-z: " << data[i].z << std::endl;
    }
    std::cout << "cloud: " << cloud << std::endl;
    cloud *= 5.0f;
    std::cout << "cloud after: " << cloud << std::endl;
    return cloud;
}
/**
 * @function main
 */
int main(int argn, char **argv)
{
    // Create a window
    viz::Viz3d myWindow("Coordinate Frame");
    // Create a cloud widget.
    Mat bunny_cloud = cvcloud_load();
    viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());
    // Visualize widget
    myWindow.showWidget("bunny", cloud_widget);
    // Start event loop.
    myWindow.spin();
    return 0;
}

Remark1:

Mat cloud(1, num, CV_32FC3);

不知道为什么使用CV_64FC3不能正常显示,改为CV_32FC3即可,但是官方文档定义的数据格式中包含有

cloud- Set of points which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4

Remark2:(filepath of bunny.ply after install opencv):

/opt/opencv-3.3.1/samples/cpp/tutorial_code/viz

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_COMPILER "g++")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
list(APPEND CMAKE_CXX_FLAGS "-O3 -DEBUG -ffast-math -Wall -pthread -fopenmp -std=c++11") #-DNDEBUG
project(test_viz3d)
# OpenCV
find_package(OpenCV 3.3.1 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}")
message("OpenCV_LIBS: ${OpenCV_LIBS}")
# VTK
find_package(VTK 5.10 REQUIRED)
include(${VTK_USE_FILE})
message("VTK_USE_FILE: ${VTK_USE_FILE}")
message("VTK_LIBRARIES: ${VTK_LIBRARIES}")
# PROJECT
include_directories(include)
aux_source_directory(src DIR_SRCS)
add_executable(${PROJECT_NAME} ${DIR_SRCS})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} ${VTK_LIBRARIES})
View Code

Remarks3:如何保存图像呢?

博主使用saveScreenshot可以保存截图,png格式可以正常显示图片,jpg格式不能;而且需要在显示的循环外层才可以使用,否则出错;

Segmentation fault (core dumped)

可以使用getScreenshot得到屏幕截图的Mat数据,但是感觉数据不完整;

cv::Mat shot = myWindow.getScreenshot();
std::cout << "shot: " << shot.type() << "size: " << shot.size() << std::endl;

Output:

shot: 16size: [960 x 540]

opencv官方文档中没有找到代码实例。

int main()
{
  double begin(0.0), end(0.0), cost(0.0);
  cv::viz::Viz3d window("Viz3D");
    Mat bunny_cloud = cvcloud_load();
  int cnt = 0;
  while(!window.wasStopped() && cnt<10)
  {
    cnt++;
    begin = (double)cv::getTickCount();
    viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());
    window.showWidget("bunny", cloud_widget);
    end = (double)cv::getTickCount();
    cost = (end-begin)*1000/cv::getTickFrequency();
    std::cout << "showWidget cost(ms): " << cost << std::endl;
    // cv::Mat shot = window.getScreenshot();
    // std::cout << "shot: " << shot.type() << "size: " << shot.size() << std::endl;
    window.spinOnce(1, true);
  }
  window.saveScreenshot("Viz3D_bunny.png");
  return 0;
}
View Code

Remark4:耗时分析

准备数据的运行时间并不长,大概2/3ms左右,但是spin/spinOnce函数的调用耗时很久,大概要40/50ms左右,需要使用openGL实现3D绘图解决耗时较久的问题。

参考

1. OpenCV 3D显示Viz模块

2. OpenCV编译安装viz3d模块_ubuntu

3. Opencv_contrib_viz_sample_transformation;

4. opencv - viz 画出SLAM轨迹;

原文地址:https://www.cnblogs.com/happyamyhope/p/12487096.html