26 std::vector<bool>& visited,
27 int64_t x, int64_t y, std::size_t thres)
29 typedef std::list<int64_t> PixelQueue;
30 typedef std::set<int64_t> PixelBag;
32 int64_t w = dm->width();
33 int64_t h = dm->height();
34 int64_t idx = y * w + x;
35 int64_t max_idx = w * h;
36 int64_t
const MAX_ST = -1;
41 queue.push_front(idx);
42 collected.insert(idx);
49 while (!queue.empty())
52 int64_t cur = queue.back();
57 n[0] = (cur < w ? MAX_ST : cur - w);
58 n[1] = (cur < max_idx - w ? cur + w : MAX_ST);
59 n[2] = (cur % w > 0 ? cur - 1 : MAX_ST);
60 n[3] = (cur % w < w - 1 ? cur + 1 : MAX_ST);
63 for (
int i = 0; i < 4; ++i)
64 if (n[i] != MAX_ST && dm->at(n[i], 0) == 0.0f)
68 for (
int i = 0; i < 4; ++i)
69 if (n[i] != MAX_ST && collected.find(n[i]) == collected.end())
71 queue.push_front(n[i]);
72 collected.insert(n[i]);
79 for (PixelBag::iterator i = collected.begin(); i != collected.end(); i++)
82 if (collected.size() < thres)
83 ret->at(*i, 0) = 0.0f;
94 int64_t
const width = ret->width();
95 int64_t
const height = ret->height();
96 std::vector<bool> visited;
97 visited.resize(width * height,
false);
100 for (int64_t y = 0; y < height; ++y)
101 for (int64_t x = 0; x < width; ++x, ++i)
103 if (dm->at(i, 0) == 0.0f)
118 if (dm ==
nullptr || cm ==
nullptr)
119 throw std::invalid_argument(
"Null depth or confidence map");
121 if (dm->width() != cm->width() || dm->height() != cm->height())
122 throw std::invalid_argument(
"Image dimensions do not match");
124 int64_t cnt = dm->get_pixel_amount();
125 for (int64_t i = 0; i < cnt; ++i)
126 if (cm->at(i, 0) <= 0.0f)
143 ((
float)x + 0.5f, (
float)y + 0.5f, 1.0f);
144 return invproj[0] * depth / v.
norm();
154 ((
float)x + 0.5f, (
float)y + 0.5f, 1.0f);
163 std::size_t i,
int* tverts)
165 int64_t
const width = vidx.
width();
169 for (int64_t j = 0; j < 3; ++j)
171 int64_t iidx = i + (tverts[j] % 2) + width * (tverts[j] / 2);
172 int64_t x = iidx % width;
173 int64_t y = iidx / width;
177 vidx.
at(iidx) = verts.size();
178 float depth = dm->
at(iidx, 0);
179 verts.push_back(
pixel_3dpos(x, y, depth, invproj));
181 faces.push_back(vidx.
at(iidx));
193 if (depths[i2] < depths[i1])
201 if (depths[i_max] - depths[i_min] > widths[i_min] * dd_factor)
214 throw std::invalid_argument(
"Null depthmap given");
216 int64_t
const width = dm->width();
217 int64_t
const height = dm->height();
228 for (int64_t y = 0; y < height - 1; ++y, ++i)
230 for (int64_t x = 0; x < width - 1; ++x, ++i)
233 float depths[4] = { dm->at(i, 0), dm->at(i + 1, 0),
234 dm->at(i + width, 0), dm->at(i + width + 1, 0) };
239 for (
int j = 0; j < 4; ++j)
240 if (depths[j] > 0.0f)
252 { 0, 2, 1 }, { 0, 3, 1 }, { 0, 2, 3 }, { 1, 2, 3 }
256 int tri[2] = { 0, 0 };
260 case 7: tri[0] = 1;
break;
261 case 11: tri[0] = 2;
break;
262 case 13: tri[0] = 3;
break;
263 case 14: tri[0] = 4;
break;
267 float ddiff1 = std::abs(depths[0] - depths[3]);
268 float ddiff2 = std::abs(depths[1] - depths[2]);
270 { tri[0] = 2; tri[1] = 3; }
272 { tri[0] = 1; tri[1] = 4; }
279 if (dd_factor > 0.0f)
283 for (
int j = 0; j < 4; ++j)
285 if (depths[j] == 0.0f)
292 for (
int j = 0; j < 2 && tri[j] != 0; ++j)
294 int* tv = tris[tri[j] - 1];
295 #define DM_DD_ARGS widths, depths, dd_factor
303 for (
int j = 0; j < 2; ++j)
305 if (tri[j] == 0)
continue;
306 #define DM_MAKE_TRI_ARGS mesh.get(), vidx, dm.get(), invproj, i
327 throw std::invalid_argument(
"Null depthmap given");
329 int64_t
const width = dm->width();
330 int64_t
const height = dm->height();
332 if (ci !=
nullptr && (ci->width() != width || ci->height() != height))
333 throw std::invalid_argument(
"Color image dimension mismatch");
346 colors.resize(verts.size());
349 for (int64_t i = 0; i < num_pixel; ++i)
354 math::Vec4f color(ci->at(i, 0), 0.0f, 0.0f, 255.0f);
355 if (ci->channels() >= 3)
357 color[1] = ci->at(i, 1);
358 color[2] = ci->at(i, 2);
362 color[1] = color[2] = color[0];
364 colors[vids[i]] = color / 255.0f;
368 if (vertex_ids !=
nullptr)
382 throw std::invalid_argument(
"Null depthmap given");
383 if (cam.
flen == 0.0f)
384 throw std::invalid_argument(
"Invalid camera given");
396 mesh->recalc_normals(
false,
true);
410 (v3 - v2).normalized(), (v1 - v3).normalized() };
411 float min_angle = angle_threshold;
412 for (
int i = 0; i < 3; ++i)
413 min_angle = std::min(min_angle, std::acos(e[i].dot(-e[(i + 1) % 3])));
416 return min_angle < angle_threshold;
423 throw std::invalid_argument(
"Null mesh given");
425 int64_t w = grid.
width();
426 int64_t h = grid.
height();
431 for (int64_t y = 0; y < h - 1; ++y)
432 for (int64_t x = 0; x < w - 1; ++x)
434 int64_t i = y * w + x;
436 unsigned int vid[4] = { grid[i], grid[i + 1],
437 grid[i + w], grid[i + w + 1] };
442 for (
int j = 0; j < 4; ++j)
443 if (vid[j] !=
static_cast<unsigned int>(-1))
455 int tri[2] = { 0, 0 };
459 case 7: tri[0] = 1;
break;
460 case 11: tri[0] = 2;
break;
461 case 13: tri[0] = 3;
break;
462 case 14: tri[0] = 4;
break;
466 if ((verts[vid[0]] - verts[vid[3]]).square_norm() <
467 (verts[vid[1]] - verts[vid[2]]).square_norm())
468 { tri[0] = 2; tri[1] = 3; }
470 { tri[0] = 1; tri[1] = 4; }
477 for (
int j = 0; j < 2; ++j)
481#define VERT(id) verts[vid[id]]
482#define DEPTHDISC(a,b,c) dm_is_depth_disc(VERT(a), VERT(b), VERT(c))
483#define ADDTRI(a,c,b) faces.push_back(vid[a]); faces.push_back(vid[b]); faces.push_back(vid[c])
500 throw std::invalid_argument(
"Null mesh given");
503 throw std::invalid_argument(
"Invalid amount of iterations");
511 confs.resize(verts.size(), 1.0f);
514 std::vector<std::size_t> vidx;
517 for (std::size_t i = 0; i < mesh_info.
size(); ++i)
519 if (mesh_info[i].vclass == MeshInfo::VERTEX_CLASS_BORDER)
524 for (
int current = 0; current < iterations; ++current)
527 float conf = (float)current / (
float)iterations;
531 for (std::size_t i = 0; i < vidx.size(); ++i)
532 confs[vidx[i]] = conf;
535 std::vector<std::size_t> cvidx;
537 for (std::size_t i = 0; i < cvidx.size(); ++i)
540 for (std::size_t j = 0; j < info.
verts.size(); ++j)
541 if (confs[info.
verts[j]] == 1.0f)
542 vidx.push_back(info.
verts[j]);
553 throw std::invalid_argument(
"Null mesh given");
556 throw std::invalid_argument(
"Invalid amount of iterations");
562 std::vector<bool> delete_list;
563 delete_list.resize(faces.size(),
false);
566 for (
int iter = 0; iter < iterations; ++iter)
569 for (std::size_t i = 0; i < mesh_info.
size(); ++i)
572 if (info.
vclass == MeshInfo::VERTEX_CLASS_BORDER)
573 for (std::size_t j = 0; j < info.
faces.size(); ++j)
574 for (
int k = 0; k < 3; ++k)
576 unsigned int fidx = info.
faces[j] * 3 + k;
578 delete_list[fidx] =
true;
Matrix class for arbitrary dimensions and types.
Vector class for arbitrary dimensions and types.
T norm(void) const
Computes the norm (length) of the vector.
Vector< T, N > normalized(void) const
Returns a normalized copy of self.
int64_t height(void) const
Returns the height of the image.
int64_t width(void) const
Returns the width of the image.
Multi-channel image class of arbitrary but homogenous data type.
std::shared_ptr< Image< T > > Ptr
std::shared_ptr< Image< T > const > ConstPtr
T const & at(int64_t index) const
Linear indexing of image data.
std::vector< math::Vec3f > VertexList
VertexList const & get_vertices(void) const
Returns the mesh vertices.
std::vector< float > ConfidenceList
std::vector< math::Vec4f > ColorList
std::size_t size(void) const
Triangle mesh representation.
std::shared_ptr< TriangleMesh > Ptr
std::vector< VertexID > FaceList
FaceList const & get_faces(void) const
Returns the triangle indices.
int64_t get_pixel_amount(void) const
Returns the amount of pixels in the image (w * h).
void fill(T const &value)
Fills the data with a constant value.
#define DEPTHDISC(a, b, c)
#define MVE_IMAGE_NAMESPACE_END
#define MVE_NAMESPACE_BEGIN
#define MVE_IMAGE_NAMESPACE_BEGIN
#define MVE_NAMESPACE_END
#define MVE_GEOM_NAMESPACE_END
#define MVE_GEOM_NAMESPACE_BEGIN
void vector_clean(std::vector< bool > const &delete_list, std::vector< T > *vector)
Erases all elements from 'vector' that are marked with 'true' in 'delete_list'.
void dm_make_triangle(TriangleMesh *mesh, mve::Image< unsigned int > &vidx, FloatImage const *dm, math::Matrix3f const &invproj, std::size_t i, int *tverts)
void rangegrid_triangulate(Image< unsigned int > const &grid, TriangleMesh::Ptr mesh)
Algorithm to triangulate range grids.
void mesh_transform(mve::TriangleMesh::Ptr mesh, math::Matrix3f const &rot)
Transforms the vertices and normals of the mesh using the specified rotation matrix.
math::Vec3f pixel_3dpos(int64_t x, int64_t y, float depth, math::Matrix3f const &invproj)
Function that calculates the pixel 3D position in camera coordinates for pixel (x,...
TriangleMesh::Ptr depthmap_triangulate(FloatImage::ConstPtr dm, math::Matrix3f const &invproj, float dd_factor, mve::Image< unsigned int > *vids)
Algorithm to triangulate depth maps.
void depthmap_mesh_confidences(TriangleMesh::Ptr mesh, int iterations)
Algorithm to assign per-vertex confidence values to vertices of a triangulated depth map.
bool dm_is_depth_disc(math::Vec3f const &v1, math::Vec3f const &v2, math::Vec3f const &v3)
bool dm_is_depthdisc(float *widths, float *depths, float dd_factor, int i1, int i2)
float pixel_footprint(int64_t x, int64_t y, float depth, math::Matrix3f const &invproj)
Function that calculates the pixel footprint (pixel width) in 3D coordinates for pixel (x,...
void depthmap_mesh_peeling(TriangleMesh::Ptr mesh, int iterations)
Algorithm that peels away triangles at the mesh bounary of a triangulated depth map.
void depthmap_confidence_clean(FloatImage::Ptr dm, FloatImage::ConstPtr cm)
Removes the backplane according to the confidence map IN-PLACE.
FloatImage::Ptr depthmap_cleanup(FloatImage::ConstPtr dm, int64_t thres)
Algorithm to clean small confident islands in the depth maps.
void depthmap_cleanup_grow(FloatImage::ConstPtr dm, FloatImage::Ptr ret, std::vector< bool > &visited, int64_t x, int64_t y, std::size_t thres)
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.
Per-view camera information with various helper functions.
void fill_inverse_calibration(float *mat, float width, float height) const
Stores 3x3 inverse calibration (or inverse projection) matrix.
void fill_cam_to_world(float *mat) const
Stores camera to world 4x4 matrix in array pointed to by mat.
Per-vertex classification and adjacency information.