|
| 1 | +/* |
| 2 | + * Copyright (C) 2015, Simon Fuhrmann |
| 3 | + * TU Darmstadt - Graphics, Capture and Massively Parallel Computing |
| 4 | + * All rights reserved. |
| 5 | + * |
| 6 | + * This software may be modified and distributed under the terms |
| 7 | + * of the BSD 3-Clause license. See the LICENSE.txt file for details. |
| 8 | + */ |
| 9 | + |
| 10 | +#include <iostream> |
| 11 | +#include <stdexcept> |
| 12 | +#include <algorithm> |
| 13 | +#include <vector> |
| 14 | +#include <string> |
| 15 | +#include <cstring> |
| 16 | +#include <cerrno> |
| 17 | +#include <cstdlib> |
| 18 | + |
| 19 | +#include "core/depthmap.h" |
| 20 | +#include "core/mesh_info.h" |
| 21 | +#include "core/mesh_io.h" |
| 22 | +#include "core/mesh_io_ply.h" |
| 23 | +#include "core/mesh_tools.h" |
| 24 | +#include "core/scene.h" |
| 25 | +#include "core/view.h" |
| 26 | + |
| 27 | + |
| 28 | +struct AppSettings |
| 29 | +{ |
| 30 | + std::string scenedir; |
| 31 | + std::string outmesh; |
| 32 | + std::string dmname = "depth-L0"; |
| 33 | + std::string imagename = "undistorted"; |
| 34 | + std::string mask; |
| 35 | + std::string aabb; |
| 36 | + bool with_normals = true; |
| 37 | + bool with_scale = true; |
| 38 | + bool with_conf = true; |
| 39 | + bool poisson_normals = false; |
| 40 | + float min_valid_fraction = 0.0f; |
| 41 | + float scale_factor = 2.5f; /* "Radius" of MVS patch (usually 5x5). */ |
| 42 | + std::vector<int> ids; |
| 43 | + int view_id = -1; |
| 44 | + float dd_factor = 5.0f; |
| 45 | + int scale = 0; |
| 46 | +}; |
| 47 | + |
| 48 | +int |
| 49 | +main (int argc, char** argv) |
| 50 | +{ |
| 51 | + |
| 52 | + if(argc<4){ |
| 53 | + std::cout<<"usage: scendir outmeshdir(.ply) scale"<<std::endl; |
| 54 | + return -1; |
| 55 | + } |
| 56 | + |
| 57 | + AppSettings conf; |
| 58 | + |
| 59 | + // 场景文件夹 |
| 60 | + conf.scenedir = argv[1]; |
| 61 | + // 输出网格文件 |
| 62 | + conf.outmesh= argv[2]; |
| 63 | + // 获取图像尺度 |
| 64 | + std::stringstream stream(argv[3]); |
| 65 | + stream>>conf.scale; |
| 66 | + |
| 67 | + conf.dmname = std::string("depth-L") + argv[3]; |
| 68 | + conf.imagename = (conf.scale == 0) |
| 69 | + ? "undistorted" |
| 70 | + : std::string("undist-L") + argv[3]; |
| 71 | + |
| 72 | + std::cout << "Using depthmap \"" << conf.dmname |
| 73 | + << "\" and color image \"" << conf.imagename << "\"" << std::endl; |
| 74 | + |
| 75 | + /* Prepare output mesh. */ |
| 76 | + core::TriangleMesh::Ptr pset(core::TriangleMesh::create()); |
| 77 | + core::TriangleMesh::VertexList& verts(pset->get_vertices()); |
| 78 | + core::TriangleMesh::NormalList& vnorm(pset->get_vertex_normals()); |
| 79 | + core::TriangleMesh::ColorList& vcolor(pset->get_vertex_colors()); |
| 80 | + core::TriangleMesh::ValueList& vvalues(pset->get_vertex_values()); // scale |
| 81 | + core::TriangleMesh::ConfidenceList& vconfs(pset->get_vertex_confidences()); |
| 82 | + |
| 83 | + /* Load scene. */ |
| 84 | + core::Scene::Ptr scene = core::Scene::create(conf.scenedir); |
| 85 | + |
| 86 | + /* Iterate over views and get points. */ |
| 87 | + core::Scene::ViewList& views(scene->get_views()); |
| 88 | + |
| 89 | + for (std::size_t i = 0; i < views.size(); ++i) { |
| 90 | + core::View::Ptr view = views[i]; |
| 91 | + if (view == nullptr) |
| 92 | + continue; |
| 93 | + |
| 94 | + std::size_t view_id = view->get_id(); |
| 95 | + |
| 96 | + // 保证存在相机参数 |
| 97 | + core::CameraInfo const& cam = view->get_camera(); |
| 98 | + if (cam.flen == 0.0f) |
| 99 | + continue; |
| 100 | + |
| 101 | + core::FloatImage::Ptr dm = view->get_float_image(conf.dmname); |
| 102 | + if (dm == nullptr) |
| 103 | + continue; |
| 104 | + |
| 105 | + // color image |
| 106 | + core::ByteImage::Ptr ci; |
| 107 | + if (!conf.imagename.empty()) |
| 108 | + ci = view->get_byte_image(conf.imagename); |
| 109 | + |
| 110 | + std::cout << "Processing view \"" << view->get_name() |
| 111 | + << "\"" << (ci != nullptr ? " (with colors)" : "") |
| 112 | + << "..." << std::endl; |
| 113 | + |
| 114 | + /* Triangulate depth map. */ |
| 115 | + core::TriangleMesh::Ptr mesh; |
| 116 | + mesh = core::geom::depthmap_triangulate(dm, ci, cam); |
| 117 | + |
| 118 | + core::TriangleMesh::VertexList const& corerts(mesh->get_vertices()); |
| 119 | + core::TriangleMesh::NormalList const& mnorms(mesh->get_vertex_normals()); |
| 120 | + core::TriangleMesh::ColorList const& mvcol(mesh->get_vertex_colors()); |
| 121 | + core::TriangleMesh::ConfidenceList& mconfs(mesh->get_vertex_confidences()); |
| 122 | + |
| 123 | + if (conf.with_normals) |
| 124 | + mesh->ensure_normals(); |
| 125 | + |
| 126 | + /* If confidence is requested, compute it. */ |
| 127 | + if (conf.with_conf) { |
| 128 | + /* Per-vertex confidence down-weighting boundaries. */ |
| 129 | + core::geom::depthmap_mesh_confidences(mesh, 4); |
| 130 | + } |
| 131 | + |
| 132 | + /* If scale is requested, compute it. */ |
| 133 | + std::vector<float> mvscale; |
| 134 | + if (conf.with_scale) { |
| 135 | + mvscale.resize(corerts.size(), 0.0f); |
| 136 | + core::MeshInfo mesh_info(mesh); |
| 137 | + // 遍历每一个顶点的信息 |
| 138 | + for (std::size_t j = 0; j < mesh_info.size(); ++j) { |
| 139 | + // 获取每一个顶点的信息 |
| 140 | + core::MeshInfo::VertexInfo const& vinf = mesh_info[j]; |
| 141 | + // 顶点到所有邻域的距离的平均值,类似于求顶点的分辨率 |
| 142 | + for (std::size_t k = 0; k < vinf.verts.size(); ++k) |
| 143 | + mvscale[j] += (corerts[j] - corerts[vinf.verts[k]]).norm(); |
| 144 | + mvscale[j] /= static_cast<float>(vinf.verts.size()); |
| 145 | + mvscale[j] *= conf.scale_factor; |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + // 将所有视角的三维点云集中到一起 |
| 150 | + // 顶点坐标 |
| 151 | + verts.insert(verts.end(), corerts.begin(), corerts.end()); |
| 152 | + // 顶点颜色 |
| 153 | + if (!mvcol.empty()) |
| 154 | + vcolor.insert(vcolor.end(), mvcol.begin(), mvcol.end()); |
| 155 | + //顶点法向量 |
| 156 | + if (conf.with_normals) |
| 157 | + vnorm.insert(vnorm.end(), mnorms.begin(), mnorms.end()); |
| 158 | + |
| 159 | + // 顶点尺度(分辨率) |
| 160 | + if (conf.with_scale) |
| 161 | + vvalues.insert(vvalues.end(), mvscale.begin(), mvscale.end()); |
| 162 | + |
| 163 | + // 顶点置信度 |
| 164 | + if (conf.with_conf) |
| 165 | + vconfs.insert(vconfs.end(), mconfs.begin(), mconfs.end()); |
| 166 | + |
| 167 | + dm.reset(); |
| 168 | + ci.reset(); |
| 169 | + view->cache_cleanup(); |
| 170 | + } |
| 171 | + |
| 172 | + /* Write mesh to disc. */ |
| 173 | + std::cout << "Writing final point set (" << verts.size() << " points)..." << std::endl; |
| 174 | + assert(util::string::right(arg.outmesh, 4) == ".ply"); |
| 175 | + { |
| 176 | + core::geom::SavePLYOptions opts; |
| 177 | + opts.write_vertex_normals = conf.with_normals; |
| 178 | + opts.write_vertex_values = conf.with_scale; |
| 179 | + opts.write_vertex_confidences = conf.with_conf; |
| 180 | + core::geom::save_ply_mesh(pset, conf.outmesh, opts); |
| 181 | + } |
| 182 | + |
| 183 | + |
| 184 | + return EXIT_SUCCESS; |
| 185 | +} |
0 commit comments