zoukankan      html  css  js  c++  java
  • 基于OpenCV的三维数据点的曲面重构_MySurefaceReconstruction

    在Opencv中有个Viz模块,可以显示三维物体,还可以实现三维动画,本来是很好的东东,但是里面的函数、类的说明太过简单,始终不得要领。不过其中一个扩展功能非常好,就是你可以在vtk中设计自己的模型类,在Opencv中的Viz3d窗口中显示。

    在这里我用vtk中的vtkSurfaceReconstructionFilter类,这是一个对空间点拟合曲面的函数,重新封装了该函数,创建了自己的类:MySurfaceReconstruction,该类可以直接在Viz中的Viz3d窗口中显示。

    本程序中所需要的头文件如下:

    #ifndef INITIAL_OPENGL
    #define INITIAL_OPENGL
    #include <vtkAutoInit.h>
    VTK_MODULE_INIT(vtkRenderingOpenGL)
    VTK_MODULE_INIT(vtkInteractionStyle)
    #endif
    
    #include <iostream>
    #include <opencv2/opencv.hpp>
    #include <opencv2/viz/vizcore.hpp>
    #include <opencv2/viz/viz3d.hpp>
    #include <opencv2/viz/widget_accessor.hpp>
    using namespace cv;
    using namespace std;
    
    #include "vtkPolyDataMapper.h"
    #include "vtkActor.h"
    #include "vtkSmartPointer.h"
    #include "vtkProperty.h"
    #include "vtkPoints.h"
    #include "vtkCellArray.h"
    #include "vtkSurfaceReconstructionFilter.h"
    #include "vtkContourFilter.h"

    下面是该类的代码:

    class MySurfaceReconstruction:public viz::Widget3D
    {
    public:
        MySurfaceReconstruction(const Mat&src, const viz::Color color = viz::Color::white());
    
    };
    MySurfaceReconstruction::MySurfaceReconstruction(const Mat &src, const viz::Color color)
    {
    
        vtkSmartPointer<vtkPoints>m_Points=vtkSmartPointer<vtkPoints>::New();
        vtkSmartPointer<vtkCellArray>vertices=vtkSmartPointer<vtkCellArray>::New();
        int numOfpixs=0;
        for(int i=0;i<src.rows;i++)
        {
            for(int j=0;j<src.cols;j++)
            {
                double x=j,y=i;
                double z=src.at<double>(i,j);
                m_Points->InsertPoint(numOfpixs,x,y,z);  //_加入点信息
                vertices->InsertNextCell(numOfpixs);     //_加入细胞顶点信息----用于渲染点集
                vertices->InsertCellPoint(numOfpixs);
                numOfpixs ++;
            }
        }
    
        vtkSmartPointer<vtkPolyData>points=vtkSmartPointer<vtkPolyData>::New();
        points->SetPoints(m_Points);
        vtkSmartPointer<vtkSurfaceReconstructionFilter>surf=vtkSmartPointer<vtkSurfaceReconstructionFilter>::New();
        surf->SetInputData(points);
    
        vtkSmartPointer<vtkContourFilter>contour=vtkSmartPointer<vtkContourFilter>::New();
        contour->SetInputConnection(surf->GetOutputPort());
        contour->SetValue(0,0.0);
    
        vtkSmartPointer<vtkPolyDataMapper>pointMapper=vtkSmartPointer<vtkPolyDataMapper>::New();
        pointMapper->SetInputConnection(contour->GetOutputPort());
        vtkSmartPointer<vtkActor>actor=vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(pointMapper);
        // Store this actor in the widget in order that visualizer can access it
        viz::WidgetAccessor::setProp(*this, actor);
        // Set the color of the widget. This has to be called after WidgetAccessor.
        setColor(color);
    
    }

    为了方便测试,自定义了一个高斯分布函数:

    //*9. 获取二维高斯卷积核
    Mat Gaussian_kernel(int kernel_size, double sigma)
    {
        int c = (kernel_size) / 2;
        Mat kernel(kernel_size, kernel_size, CV_64FC1);
        double s = 2 * sigma*sigma;
        for (int i = 0; i < kernel_size; i++)
        {
            for (int j = 0; j < kernel_size; j++)
            {
                double x = j - c;
                double y=i - c;
                kernel.ptr<double>(i)[j] = exp(-(x*x+y*y)/s) ;
            }
        }
        Scalar sumOfKernel= cv::sum(kernel);//求kernel的所有像素值之和
        kernel /=sumOfKernel[0];//归一化,避免卷积过程中增大总能量
        return kernel;
    }

     下面是测试程序,通过上面的高斯函数创建一个高斯分布二维矩阵mat,作为MySurfaceReconstruction类的初始输入,MySurfaceReconstruction可以将mat转化成Widget3d类物体,并通过Viz3d显示。


    int
    main() { /// Create a window viz::Viz3d myWindow("Creating Widgets"); /// Create a triangle widget cv::Mat mat=Gaussian_kernel(15,1); mat *=10; MySurfaceReconstruction tw(mat, viz::Color::red()); /// Show widget in the visualizer window myWindow.showWidget("my surface", tw); /// Start event loop myWindow.spin(); return 0; }

     下面是运行结果:

  • 相关阅读:
    安装64位Oracle 10g超详细教程
    Linux同平台Oracle数据库整体物理迁移
    Oracle 删除重复数据只留一条
    linux下通过脚本实现自动重启程序的方法
    Linux查看系统开机时间
    Linux下oracle数据库启动和关闭操作
    curl: (6) Couldn’t resolve host ‘www.ttlsa.com’
    linux 怎么查找oracle11g的安装目录
    Linux系统管理员:不要害怕升级内核
    The Binder Architecture
  • 原文地址:https://www.cnblogs.com/phoenixdsg/p/8439285.html
Copyright © 2011-2022 走看看