Visual Hull是基于轮廓信息的三维重建,输入是序列图像以及对应序列图像的相机投影矩阵P。如果换成自己想要的序列图像,
相应的P矩阵也需要更换,因为P矩阵是相机标定后得到的。现在感觉自己作标定遇到了些许困难,不知是只作一次标定,还是
需要标定板也旋转一周,根据图像数量的多少旋转相应的角度,标定一周?我看过github上码主的视频,用的是激光标定板旋转一周作的标定,但是针对小物体,标定板也相对更小,镜头的焦距也相应变小,此时感觉这个办法就不是很通用了。不过可以放心的是,不论用什么办法标定,只要拿到每张图像对应的P矩阵,就能完成物体的三维重建。
开发环境:windows8.1,vs2010,opencv2.4.9,vtk;
完整代码我是在github上找到的,以松鼠模型为例子,代码原本有些错误,改了改之后,可以成功运行。
啥也不多说,直接贴代码吧。
// trySquirral.cpp : 定义控制台应用程序的入口点。
//
// Squirral.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <vtkSmartPointer.h>
#include <vtkStructuredPoints.h>
#include <vtkPointData.h>
#include <vtkPLYWriter.h>
#include <vtkFloatArray.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkImageCast.h>
#include <vtkImageShiftScale.h>
#include <vtkMetaImageReader.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkMarchingCubes.h>
#include <vtkCleanPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkAutoInit.h>
#include <vtkImageCanvasSource2D.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
using namespace cv;
const int IMG_WIDTH = 1280;
const int IMG_HEIGHT = 960;
const int VOXEL_DIM = 128;
const int VOXEL_SIZE = VOXEL_DIM*VOXEL_DIM*VOXEL_DIM;
const int VOXEL_SLICE = VOXEL_DIM*VOXEL_DIM;
const int OUTSIDE = 0;
struct voxel {
float xpos;
float ypos;
float zpos;
float res;
float value;
};
struct coord {
int x;
int y;
};
struct startParams {
float startX;
float startY;
float startZ;
float voxelWidth;
float voxelHeight;
float voxelDepth;
};
struct camera {
cv::Mat Image;
cv::Mat P;
cv::Mat K;
cv::Mat R;
cv::Mat t;
cv::Mat Silhouette;
};
void exportModel(char *filename,