updated mesh reading (texture support)
This commit is contained in:
parent
625c35a9f9
commit
e472d45d99
@ -99,9 +99,10 @@ namespace cv
|
||||
CV_EXPORTS Mat readCloud (const String& file, OutputArray colors = noArray(), OutputArray normals = noArray());
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read mesh. Only ply format is supported now
|
||||
/// Reads mesh. Only ply format is supported now. The function tries to read texture from png-file,
|
||||
/// and in case of faulure, just leaves the texture field empty.
|
||||
|
||||
CV_EXPORTS Mesh readMesh (const String& file);
|
||||
CV_EXPORTS Mesh readMesh(const String& file);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Read/write poses and trajectories
|
||||
|
@ -122,6 +122,7 @@
|
||||
#include <vtkPLYReader.h>
|
||||
#include <vtkOBJReader.h>
|
||||
#include <vtkSTLReader.h>
|
||||
#include <vtkPNGReader.h>
|
||||
#include <vtkOBJExporter.h>
|
||||
#include <vtkVRMLExporter.h>
|
||||
#include <vtkTensorGlyph.h>
|
||||
|
@ -57,80 +57,56 @@ cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, c
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cv::viz::Mesh3d
|
||||
|
||||
namespace cv { namespace viz { namespace
|
||||
{
|
||||
struct MeshUtils
|
||||
{
|
||||
static Mesh loadMesh(const String &file)
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
|
||||
reader->SetFileName(file.c_str());
|
||||
reader->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyData> poly_data = reader->GetOutput();
|
||||
CV_Assert("File does not exist or file format is not supported." && poly_data);
|
||||
|
||||
vtkSmartPointer<vtkPoints> mesh_points = poly_data->GetPoints();
|
||||
vtkIdType nr_points = mesh_points->GetNumberOfPoints();
|
||||
|
||||
mesh.cloud.create(1, nr_points, CV_32FC3);
|
||||
|
||||
Vec3f *mesh_cloud = mesh.cloud.ptr<Vec3f>();
|
||||
for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
|
||||
{
|
||||
Vec3d point;
|
||||
mesh_points->GetPoint(i, point.val);
|
||||
mesh_cloud[i] = point;
|
||||
}
|
||||
|
||||
// Then the color information, if any
|
||||
vtkUnsignedCharArray* poly_colors = 0;
|
||||
if (poly_data->GetPointData())
|
||||
poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars());
|
||||
|
||||
if (poly_colors && (poly_colors->GetNumberOfComponents() == 3))
|
||||
{
|
||||
mesh.colors.create(1, nr_points, CV_8UC3);
|
||||
Vec3b *mesh_colors = mesh.colors.ptr<cv::Vec3b>();
|
||||
|
||||
for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
|
||||
{
|
||||
Vec3b point_color;
|
||||
poly_colors->GetTupleValue(i, point_color.val);
|
||||
|
||||
std::swap(point_color[0], point_color[2]); // RGB -> BGR
|
||||
mesh_colors[i] = point_color;
|
||||
}
|
||||
}
|
||||
else
|
||||
mesh.colors.release();
|
||||
|
||||
// Now handle the polygons
|
||||
vtkIdType* cell_points;
|
||||
vtkIdType nr_cell_points;
|
||||
vtkCellArray * mesh_polygons = poly_data->GetPolys();
|
||||
mesh_polygons->InitTraversal();
|
||||
|
||||
mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1);
|
||||
|
||||
int* polygons = mesh.polygons.ptr<int>();
|
||||
while (mesh_polygons->GetNextCell(nr_cell_points, cell_points))
|
||||
{
|
||||
*polygons++ = nr_cell_points;
|
||||
for (int i = 0; i < nr_cell_points; ++i)
|
||||
*polygons++ = static_cast<int>(cell_points[i]);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
cv::viz::Mesh cv::viz::Mesh::load(const String& file)
|
||||
{
|
||||
return MeshUtils::loadMesh(file);
|
||||
vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
|
||||
reader->SetFileName(file.c_str());
|
||||
reader->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyData> polydata = reader->GetOutput();
|
||||
CV_Assert("File does not exist or file format is not supported." && polydata);
|
||||
|
||||
Mesh mesh;
|
||||
vtkSmartPointer<vtkCloudMatSink> sink = vtkSmartPointer<vtkCloudMatSink>::New();
|
||||
sink->SetOutput(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
|
||||
sink->SetInputConnection(reader->GetOutputPort());
|
||||
sink->Write();
|
||||
|
||||
// Now handle the polygons
|
||||
|
||||
vtkSmartPointer<vtkCellArray> polygons = polydata->GetPolys();
|
||||
mesh.polygons.create(1, polygons->GetSize(), CV_32SC1);
|
||||
int* poly_ptr = mesh.polygons.ptr<int>();
|
||||
|
||||
polygons->InitTraversal();
|
||||
vtkIdType nr_cell_points, *cell_points;
|
||||
while (polygons->GetNextCell(nr_cell_points, cell_points))
|
||||
{
|
||||
*poly_ptr++ = nr_cell_points;
|
||||
for (vtkIdType i = 0; i < nr_cell_points; ++i)
|
||||
*poly_ptr++ = (int)cell_points[i];
|
||||
}
|
||||
|
||||
String::size_type pos = file.find_last_of('.');
|
||||
String png = (pos == String::npos) ? file : file.substr(0, pos+1) + "png";
|
||||
|
||||
vtkSmartPointer<vtkPNGReader> png_reader = vtkSmartPointer<vtkPNGReader>::New();
|
||||
|
||||
if (png_reader->CanReadFile(png.c_str()))
|
||||
{
|
||||
png_reader->SetFileName(png.c_str());
|
||||
png_reader->Update();
|
||||
vtkSmartPointer<vtkImageData> imagedata = png_reader->GetOutput();
|
||||
|
||||
Size sz(imagedata->GetDimensions()[0], imagedata->GetDimensions()[1]);
|
||||
int channels = imagedata->GetNumberOfScalarComponents();
|
||||
CV_Assert(imagedata->GetScalarType() == VTK_UNSIGNED_CHAR);
|
||||
|
||||
void *ptr = imagedata->GetScalarPointer(0,0,0);
|
||||
Mat(sz, CV_8UC(channels), ptr).copyTo(mesh.texture);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -52,11 +52,12 @@ namespace cv { namespace viz
|
||||
cv::viz::vtkCloudMatSink::vtkCloudMatSink() {}
|
||||
cv::viz::vtkCloudMatSink::~vtkCloudMatSink() {}
|
||||
|
||||
void cv::viz::vtkCloudMatSink::SetOutput(OutputArray _cloud, OutputArray _colors, OutputArray _normals)
|
||||
void cv::viz::vtkCloudMatSink::SetOutput(OutputArray _cloud, OutputArray _colors, OutputArray _normals, OutputArray _tcoords)
|
||||
{
|
||||
cloud = _cloud;
|
||||
colors = _colors;
|
||||
normals = _normals;
|
||||
tcoords = _tcoords;
|
||||
}
|
||||
|
||||
void cv::viz::vtkCloudMatSink::WriteData()
|
||||
@ -120,12 +121,32 @@ void cv::viz::vtkCloudMatSink::WriteData()
|
||||
Mat buffer(cloud.size(), CV_64FC(channels));
|
||||
Vec3d *cptr = buffer.ptr<Vec3d>();
|
||||
for(size_t i = 0; i < buffer.total(); ++i)
|
||||
*cptr++ = Vec3d(scalars_data->GetTuple(i));
|
||||
*cptr++ = Vec3d(normals_data->GetTuple(i));
|
||||
|
||||
buffer.convertTo(normals, vtktype == VTK_FLOAT ? CV_32F : CV_64F);
|
||||
}
|
||||
else
|
||||
normals.release();
|
||||
|
||||
vtkSmartPointer<vtkDataArray> coords_data = input->GetPointData() ? input->GetPointData()->GetTCoords() : 0;
|
||||
|
||||
if (tcoords.needed() && coords_data)
|
||||
{
|
||||
int vtktype = coords_data->GetDataType();
|
||||
|
||||
CV_Assert(vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE);
|
||||
CV_Assert(cloud.total() == (size_t)coords_data->GetNumberOfTuples());
|
||||
|
||||
Mat buffer(cloud.size(), CV_64FC2);
|
||||
Vec2d *cptr = buffer.ptr<Vec2d>();
|
||||
for(size_t i = 0; i < buffer.total(); ++i)
|
||||
*cptr++ = Vec2d(coords_data->GetTuple(i));
|
||||
|
||||
buffer.convertTo(tcoords, vtktype == VTK_FLOAT ? CV_32F : CV_64F);
|
||||
|
||||
}
|
||||
else
|
||||
tcoords.release();
|
||||
}
|
||||
|
||||
void cv::viz::vtkCloudMatSink::PrintSelf(ostream& os, vtkIndent indent)
|
||||
|
@ -59,7 +59,7 @@ namespace cv
|
||||
vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter)
|
||||
void PrintSelf(ostream& os, vtkIndent indent);
|
||||
|
||||
void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray());
|
||||
void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray());
|
||||
|
||||
protected:
|
||||
vtkCloudMatSink();
|
||||
@ -67,7 +67,7 @@ namespace cv
|
||||
|
||||
void WriteData();
|
||||
|
||||
_OutputArray cloud, colors, normals;
|
||||
_OutputArray cloud, colors, normals, tcoords;
|
||||
|
||||
private:
|
||||
vtkCloudMatSink(const vtkCloudMatSink&); // Not implemented.
|
||||
|
Loading…
x
Reference in New Issue
Block a user