Point Cloud Library (PCL) 1.14.0
Loading...
Searching...
No Matches
texture_mapping.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2010-2011, Willow Garage, Inc.
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of Willow Garage, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *
36 * $Id$
37 *
38 */
39
40#pragma once
41
42#include <pcl/memory.h>
43#include <pcl/pcl_macros.h>
44#include <pcl/surface/reconstruction.h>
45#include <pcl/common/transforms.h>
46#include <pcl/TextureMesh.h>
47#include <pcl/octree/octree_search.h> // for OctreePointCloudSearch
48
49
50namespace pcl
51{
52 namespace texture_mapping
53 {
54
55 /** \brief Structure to store camera pose and focal length.
56 *
57 * One can assign a value to focal_length, to be used along
58 * both camera axes or, optionally, axis-specific values
59 * (focal_length_w and focal_length_h). Optionally, one can
60 * also specify center-of-focus using parameters
61 * center_w and center_h. If the center-of-focus is not
62 * specified, it will be set to the geometric center of
63 * the camera, as defined by the width and height parameters.
64 */
65 struct Camera
66 {
67 Camera () = default;
68 Eigen::Affine3f pose;
69 double focal_length{0.0};
70 double focal_length_w{-1.0}; // optional
71 double focal_length_h{-1.0}; // optinoal
72 double center_w{-1.0}; // optional
73 double center_h{-1.0}; // optional
74 double height{0.0};
75 double width{0.0};
76 std::string texture_file;
77
79 };
80
81 /** \brief Structure that links a uv coordinate to its 3D point and face.
82 */
83 struct UvIndex
84 {
85 UvIndex () = default;
86 int idx_cloud{0}; // Index of the PointXYZ in the camera's cloud
87 int idx_face{0}; // Face corresponding to that projection
88 };
89
90 using CameraVector = std::vector<Camera, Eigen::aligned_allocator<Camera> >;
91
92 }
93
94 /** \brief The texture mapping algorithm
95 * \author Khai Tran, Raphael Favier
96 * \ingroup surface
97 */
98 template<typename PointInT>
100 {
101 public:
102
103 using Ptr = shared_ptr<TextureMapping<PointInT> >;
104 using ConstPtr = shared_ptr<const TextureMapping<PointInT> >;
105
109
111 using OctreePtr = typename Octree::Ptr;
113
116
117 /** \brief Constructor. */
118 TextureMapping () = default;
119
120 /** \brief Destructor. */
121 ~TextureMapping () = default;
122
123 /** \brief Set mesh scale control
124 * \param[in] f
125 */
126 inline void
127 setF (float f)
128 {
129 f_ = f;
130 }
131
132 /** \brief Set vector field
133 * \param[in] x data point x
134 * \param[in] y data point y
135 * \param[in] z data point z
136 */
137 inline void
138 setVectorField (float x, float y, float z)
139 {
140 vector_field_ = Eigen::Vector3f (x, y, z);
141 // normalize vector field
142 vector_field_ /= std::sqrt (vector_field_.dot (vector_field_));
143 }
144
145 /** \brief Set texture files
146 * \param[in] tex_files list of texture files
147 */
148 inline void
149 setTextureFiles (std::vector<std::string> tex_files)
150 {
151 tex_files_ = tex_files;
152 }
153
154 /** \brief Set texture materials
155 * \param[in] tex_material texture material
156 */
157 inline void
159 {
160 tex_material_ = tex_material;
161 }
162
163 /** \brief Map texture to a mesh synthesis algorithm
164 * \param[in] tex_mesh texture mesh
165 */
166 void
168
169 /** \brief Map texture to a mesh UV mapping
170 * \param[in] tex_mesh texture mesh
171 */
172 void
174
175 /** \brief Map textures acquired from a set of cameras onto a mesh.
176 * \details With UV mapping, the mesh must be divided into NbCamera + 1 sub-meshes.
177 * Each sub-mesh corresponding to the faces visible by one camera. The last submesh containing all non-visible faces
178 * \param[in] tex_mesh texture mesh
179 * \param[in] cams cameras used for UV mapping
180 */
181 void
184
185 /** \brief computes UV coordinates of point, observed by one particular camera
186 * \param[in] pt XYZ point to project on camera plane
187 * \param[in] cam the camera used for projection
188 * \param[out] UV_coordinates the resulting uv coordinates. Set to (-1.0,-1.0) if the point is not visible by the camera
189 * \returns false if the point is not visible by the camera
190 */
191 inline bool
192 getPointUVCoordinates (const PointInT &pt, const Camera &cam, Eigen::Vector2f &UV_coordinates)
193 {
194 // if the point is in front of the camera
195 if (pt.z > 0)
196 {
197 // compute image center and dimension
198 double sizeX = cam.width;
199 double sizeY = cam.height;
200 double cx, cy;
201 if (cam.center_w > 0)
202 cx = cam.center_w;
203 else
204 cx = (sizeX) / 2.0;
205 if (cam.center_h > 0)
206 cy = cam.center_h;
207 else
208 cy = (sizeY) / 2.0;
209
210 double focal_x, focal_y;
211 if (cam.focal_length_w > 0)
212 focal_x = cam.focal_length_w;
213 else
214 focal_x = cam.focal_length;
215 if (cam.focal_length_h>0)
216 focal_y = cam.focal_length_h;
217 else
218 focal_y = cam.focal_length;
219
220 // project point on image frame
221 UV_coordinates[0] = static_cast<float> ((focal_x * (pt.x / pt.z) + cx) / sizeX); //horizontal
222 UV_coordinates[1] = 1.0f - static_cast<float> (((focal_y * (pt.y / pt.z) + cy) / sizeY)); //vertical
223
224 // point is visible!
225 if (UV_coordinates[0] >= 0.0 && UV_coordinates[0] <= 1.0 && UV_coordinates[1] >= 0.0 && UV_coordinates[1]
226 <= 1.0)
227 return (true);
228 }
229
230 // point is NOT visible by the camera
231 UV_coordinates[0] = -1.0;
232 UV_coordinates[1] = -1.0;
233 return (false);
234 }
235
236 /** \brief Check if a point is occluded using raycasting on octree.
237 * \param[in] pt XYZ from which the ray will start (toward the camera)
238 * \param[in] octree the octree used for raycasting. It must be initialized with a cloud transformed into the camera's frame
239 * \returns true if the point is occluded.
240 */
241 inline bool
242 isPointOccluded (const PointInT &pt, const OctreePtr octree);
243
244 /** \brief Remove occluded points from a point cloud
245 * \param[in] input_cloud the cloud on which to perform occlusion detection
246 * \param[out] filtered_cloud resulting cloud, containing only visible points
247 * \param[in] octree_voxel_size octree resolution (in meters)
248 * \param[out] visible_indices will contain indices of visible points
249 * \param[out] occluded_indices will contain indices of occluded points
250 */
251 void
252 removeOccludedPoints (const PointCloudPtr &input_cloud,
253 PointCloudPtr &filtered_cloud, const double octree_voxel_size,
254 pcl::Indices &visible_indices, pcl::Indices &occluded_indices);
255
256 /** \brief Remove occluded points from a textureMesh
257 * \param[in] tex_mesh input mesh, on witch to perform occlusion detection
258 * \param[out] cleaned_mesh resulting mesh, containing only visible points
259 * \param[in] octree_voxel_size octree resolution (in meters)
260 */
261 void
262 removeOccludedPoints (const pcl::TextureMesh &tex_mesh, pcl::TextureMesh &cleaned_mesh, const double octree_voxel_size);
263
264
265 /** \brief Remove occluded points from a textureMesh
266 * \param[in] tex_mesh input mesh, on witch to perform occlusion detection
267 * \param[out] filtered_cloud resulting cloud, containing only visible points
268 * \param[in] octree_voxel_size octree resolution (in meters)
269 */
270 void
271 removeOccludedPoints (const pcl::TextureMesh &tex_mesh, PointCloudPtr &filtered_cloud, const double octree_voxel_size);
272
273
274 /** \brief Segment faces by camera visibility. Point-based segmentation.
275 * \details With N camera, faces will be arranged into N+1 groups: 1 for each camera, plus 1 for faces not visible from any camera.
276 * \param[in] tex_mesh input mesh that needs sorting. Must contain only 1 sub-mesh.
277 * \param[in] sorted_mesh resulting mesh, will contain nbCamera + 1 sub-mesh.
278 * \param[in] cameras vector containing the cameras used for texture mapping.
279 * \param[in] octree_voxel_size octree resolution (in meters)
280 * \param[out] visible_pts cloud containing only visible points
281 */
282 int
284 pcl::TextureMesh &sorted_mesh,
286 const double octree_voxel_size, PointCloud &visible_pts);
287
288 /** \brief Colors a point cloud, depending on its occlusions.
289 * \details If showNbOcclusions is set to True, each point is colored depending on the number of points occluding it.
290 * Else, each point is given a different a 0 value is not occluded, 1 if occluded.
291 * By default, the number of occlusions is bounded to 4.
292 * \param[in] input_cloud input cloud on which occlusions will be computed.
293 * \param[out] colored_cloud resulting colored cloud showing the number of occlusions per point.
294 * \param[in] octree_voxel_size octree resolution (in meters).
295 * \param[in] show_nb_occlusions If false, color information will only represent.
296 * \param[in] max_occlusions Limit the number of occlusions per point.
297 */
298 void
299 showOcclusions (const PointCloudPtr &input_cloud,
301 const double octree_voxel_size,
302 const bool show_nb_occlusions = true,
303 const int max_occlusions = 4);
304
305 /** \brief Colors the point cloud of a Mesh, depending on its occlusions.
306 * \details If showNbOcclusions is set to True, each point is colored depending on the number of points occluding it.
307 * Else, each point is given a different a 0 value is not occluded, 1 if occluded.
308 * By default, the number of occlusions is bounded to 4.
309 * \param[in] tex_mesh input mesh on which occlusions will be computed.
310 * \param[out] colored_cloud resulting colored cloud showing the number of occlusions per point.
311 * \param[in] octree_voxel_size octree resolution (in meters).
312 * \param[in] show_nb_occlusions If false, color information will only represent.
313 * \param[in] max_occlusions Limit the number of occlusions per point.
314 */
315 void
318 double octree_voxel_size,
319 bool show_nb_occlusions = true,
320 int max_occlusions = 4);
321
322 /** \brief Segment and texture faces by camera visibility. Face-based segmentation.
323 * \details With N camera, faces will be arranged into N+1 groups: 1 for each camera, plus 1 for faces not visible from any camera.
324 * The mesh will also contain uv coordinates for each face
325 * \param mesh input mesh that needs sorting. Should contain only 1 sub-mesh.
326 * \param[in] cameras vector containing the cameras used for texture mapping.
327 */
328 void
331
332 protected:
333 /** \brief mesh scale control. */
334 float f_{0.0f};
335
336 /** \brief vector field */
337 Eigen::Vector3f vector_field_;
338
339 /** \brief list of texture files */
340 std::vector<std::string> tex_files_;
341
342 /** \brief list of texture materials */
344
345 /** \brief Map texture to a face
346 * \param[in] p1 the first point
347 * \param[in] p2 the second point
348 * \param[in] p3 the third point
349 */
350 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
351 mapTexture2Face (const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p3);
352
353 /** \brief Returns the circumcenter of a triangle and the circle's radius.
354 * \details see https://en.wikipedia.org/wiki/Circumcenter for formulas.
355 * \param[in] p1 first point of the triangle.
356 * \param[in] p2 second point of the triangle.
357 * \param[in] p3 third point of the triangle.
358 * \param[out] circumcenter resulting circumcenter
359 * \param[out] radius the radius of the circumscribed circle.
360 */
361 inline void
362 getTriangleCircumcenterAndSize (const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius);
363
364
365 /** \brief Returns the centroid of a triangle and the corresponding circumscribed circle's radius.
366 * \details yield a tighter circle than getTriangleCircumcenterAndSize.
367 * \param[in] p1 first point of the triangle.
368 * \param[in] p2 second point of the triangle.
369 * \param[in] p3 third point of the triangle.
370 * \param[out] circumcenter resulting circumcenter
371 * \param[out] radius the radius of the circumscribed circle.
372 */
373 inline void
374 getTriangleCircumcscribedCircleCentroid ( const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius);
375
376
377 /** \brief computes UV coordinates of point, observed by one particular camera
378 * \param[in] pt XYZ point to project on camera plane
379 * \param[in] cam the camera used for projection
380 * \param[out] UV_coordinates the resulting UV coordinates. Set to (-1.0,-1.0) if the point is not visible by the camera
381 * \returns false if the point is not visible by the camera
382 */
383 inline bool
384 getPointUVCoordinates (const PointInT &pt, const Camera &cam, pcl::PointXY &UV_coordinates);
385
386 /** \brief Returns true if all the vertices of one face are projected on the camera's image plane.
387 * \param[in] camera camera on which to project the face.
388 * \param[in] p1 first point of the face.
389 * \param[in] p2 second point of the face.
390 * \param[in] p3 third point of the face.
391 * \param[out] proj1 UV coordinates corresponding to p1.
392 * \param[out] proj2 UV coordinates corresponding to p2.
393 * \param[out] proj3 UV coordinates corresponding to p3.
394 */
395 inline bool
396 isFaceProjected (const Camera &camera,
397 const PointInT &p1, const PointInT &p2, const PointInT &p3,
398 pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3);
399
400 /** \brief Returns True if a point lays within a triangle
401 * \details see http://www.blackpawn.com/texts/pointinpoly/default.html
402 * \param[in] p1 first point of the triangle.
403 * \param[in] p2 second point of the triangle.
404 * \param[in] p3 third point of the triangle.
405 * \param[in] pt the query point.
406 */
407 inline bool
408 checkPointInsideTriangle (const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt);
409
410 /** \brief Class get name method. */
411 std::string
413 {
414 return ("TextureMapping");
415 }
416
417 public:
419 };
420}
shared_ptr< PointCloud< PointInT > > Ptr
shared_ptr< const PointCloud< PointInT > > ConstPtr
The texture mapping algorithm.
void setF(float f)
Set mesh scale control.
bool getPointUVCoordinates(const PointInT &pt, const Camera &cam, Eigen::Vector2f &UV_coordinates)
computes UV coordinates of point, observed by one particular camera
void mapTexture2MeshUV(pcl::TextureMesh &tex_mesh)
Map texture to a mesh UV mapping.
TexMaterial tex_material_
list of texture materials
void mapTexture2Mesh(pcl::TextureMesh &tex_mesh)
Map texture to a mesh synthesis algorithm.
shared_ptr< const TextureMapping< PointInT > > ConstPtr
void getTriangleCircumcscribedCircleCentroid(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius)
Returns the centroid of a triangle and the corresponding circumscribed circle's radius.
TextureMapping()=default
Constructor.
~TextureMapping()=default
Destructor.
typename PointCloud::Ptr PointCloudPtr
std::string getClassName() const
Class get name method.
typename Octree::Ptr OctreePtr
void setTextureFiles(std::vector< std::string > tex_files)
Set texture files.
float f_
mesh scale control.
bool isPointOccluded(const PointInT &pt, const OctreePtr octree)
Check if a point is occluded using raycasting on octree.
void setVectorField(float x, float y, float z)
Set vector field.
bool checkPointInsideTriangle(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt)
Returns True if a point lays within a triangle.
bool isFaceProjected(const Camera &camera, const PointInT &p1, const PointInT &p2, const PointInT &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3)
Returns true if all the vertices of one face are projected on the camera's image plane.
void removeOccludedPoints(const PointCloudPtr &input_cloud, PointCloudPtr &filtered_cloud, const double octree_voxel_size, pcl::Indices &visible_indices, pcl::Indices &occluded_indices)
Remove occluded points from a point cloud.
std::vector< std::string > tex_files_
list of texture files
typename Octree::ConstPtr OctreeConstPtr
std::vector< Eigen::Vector2f, Eigen::aligned_allocator< Eigen::Vector2f > > mapTexture2Face(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p3)
Map texture to a face.
Eigen::Vector3f vector_field_
vector field
int sortFacesByCamera(pcl::TextureMesh &tex_mesh, pcl::TextureMesh &sorted_mesh, const pcl::texture_mapping::CameraVector &cameras, const double octree_voxel_size, PointCloud &visible_pts)
Segment faces by camera visibility.
void getTriangleCircumcenterAndSize(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius)
Returns the circumcenter of a triangle and the circle's radius.
void showOcclusions(const PointCloudPtr &input_cloud, pcl::PointCloud< pcl::PointXYZI >::Ptr &colored_cloud, const double octree_voxel_size, const bool show_nb_occlusions=true, const int max_occlusions=4)
Colors a point cloud, depending on its occlusions.
typename PointCloud::ConstPtr PointCloudConstPtr
void mapMultipleTexturesToMeshUV(pcl::TextureMesh &tex_mesh, pcl::texture_mapping::CameraVector &cams)
Map textures acquired from a set of cameras onto a mesh.
shared_ptr< TextureMapping< PointInT > > Ptr
void setTextureMaterials(TexMaterial tex_material)
Set texture materials.
void textureMeshwithMultipleCameras(pcl::TextureMesh &mesh, const pcl::texture_mapping::CameraVector &cameras)
Segment and texture faces by camera visibility.
Octree pointcloud search class
shared_ptr< const OctreePointCloudSearch< PointT, LeafContainerT, BranchContainerT > > ConstPtr
shared_ptr< OctreePointCloudSearch< PointT, LeafContainerT, BranchContainerT > > Ptr
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition memory.h:63
Defines functions, macros and traits for allocating and using memory.
std::vector< Camera, Eigen::aligned_allocator< Camera > > CameraVector
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition types.h:133
Defines all the PCL and non-PCL macros used.
A 2D point structure representing Euclidean xy coordinates.
Structure to store camera pose and focal length.
Structure that links a uv coordinate to its 3D point and face.