Point Cloud Library (PCL) 1.13.0
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 {
68 center_w (-1), center_h (-1), height (), width () {}
69 Eigen::Affine3f pose;
71 double focal_length_w; // optional
72 double focal_length_h; // optinoal
73 double center_w; // optional
74 double center_h; // optional
75 double height;
76 double width;
77 std::string texture_file;
78
80 };
81
82 /** \brief Structure that links a uv coordinate to its 3D point and face.
83 */
84 struct UvIndex
85 {
86 UvIndex () : idx_cloud (), idx_face () {}
87 int idx_cloud; // Index of the PointXYZ in the camera's cloud
88 int idx_face; // Face corresponding to that projection
89 };
90
91 using CameraVector = std::vector<Camera, Eigen::aligned_allocator<Camera> >;
92
93 }
94
95 /** \brief The texture mapping algorithm
96 * \author Khai Tran, Raphael Favier
97 * \ingroup surface
98 */
99 template<typename PointInT>
101 {
102 public:
103
104 using Ptr = shared_ptr<TextureMapping<PointInT> >;
105 using ConstPtr = shared_ptr<const TextureMapping<PointInT> >;
106
110
112 using OctreePtr = typename Octree::Ptr;
114
117
118 /** \brief Constructor. */
120 f_ ()
121 {
122 }
123
124 /** \brief Destructor. */
125 ~TextureMapping () = default;
126
127 /** \brief Set mesh scale control
128 * \param[in] f
129 */
130 inline void
131 setF (float f)
132 {
133 f_ = f;
134 }
135
136 /** \brief Set vector field
137 * \param[in] x data point x
138 * \param[in] y data point y
139 * \param[in] z data point z
140 */
141 inline void
142 setVectorField (float x, float y, float z)
143 {
144 vector_field_ = Eigen::Vector3f (x, y, z);
145 // normalize vector field
146 vector_field_ /= std::sqrt (vector_field_.dot (vector_field_));
147 }
148
149 /** \brief Set texture files
150 * \param[in] tex_files list of texture files
151 */
152 inline void
153 setTextureFiles (std::vector<std::string> tex_files)
154 {
155 tex_files_ = tex_files;
156 }
157
158 /** \brief Set texture materials
159 * \param[in] tex_material texture material
160 */
161 inline void
163 {
164 tex_material_ = tex_material;
165 }
166
167 /** \brief Map texture to a mesh synthesis algorithm
168 * \param[in] tex_mesh texture mesh
169 */
170 void
172
173 /** \brief Map texture to a mesh UV mapping
174 * \param[in] tex_mesh texture mesh
175 */
176 void
178
179 /** \brief Map textures acquired from a set of cameras onto a mesh.
180 * \details With UV mapping, the mesh must be divided into NbCamera + 1 sub-meshes.
181 * Each sub-mesh corresponding to the faces visible by one camera. The last submesh containing all non-visible faces
182 * \param[in] tex_mesh texture mesh
183 * \param[in] cams cameras used for UV mapping
184 */
185 void
188
189 /** \brief computes UV coordinates of point, observed by one particular camera
190 * \param[in] pt XYZ point to project on camera plane
191 * \param[in] cam the camera used for projection
192 * \param[out] UV_coordinates the resulting uv coordinates. Set to (-1.0,-1.0) if the point is not visible by the camera
193 * \returns false if the point is not visible by the camera
194 */
195 inline bool
196 getPointUVCoordinates (const PointInT &pt, const Camera &cam, Eigen::Vector2f &UV_coordinates)
197 {
198 // if the point is in front of the camera
199 if (pt.z > 0)
200 {
201 // compute image center and dimension
202 double sizeX = cam.width;
203 double sizeY = cam.height;
204 double cx, cy;
205 if (cam.center_w > 0)
206 cx = cam.center_w;
207 else
208 cx = (sizeX) / 2.0;
209 if (cam.center_h > 0)
210 cy = cam.center_h;
211 else
212 cy = (sizeY) / 2.0;
213
214 double focal_x, focal_y;
215 if (cam.focal_length_w > 0)
216 focal_x = cam.focal_length_w;
217 else
218 focal_x = cam.focal_length;
219 if (cam.focal_length_h>0)
220 focal_y = cam.focal_length_h;
221 else
222 focal_y = cam.focal_length;
223
224 // project point on image frame
225 UV_coordinates[0] = static_cast<float> ((focal_x * (pt.x / pt.z) + cx) / sizeX); //horizontal
226 UV_coordinates[1] = 1.0f - static_cast<float> (((focal_y * (pt.y / pt.z) + cy) / sizeY)); //vertical
227
228 // point is visible!
229 if (UV_coordinates[0] >= 0.0 && UV_coordinates[0] <= 1.0 && UV_coordinates[1] >= 0.0 && UV_coordinates[1]
230 <= 1.0)
231 return (true);
232 }
233
234 // point is NOT visible by the camera
235 UV_coordinates[0] = -1.0;
236 UV_coordinates[1] = -1.0;
237 return (false);
238 }
239
240 /** \brief Check if a point is occluded using raycasting on octree.
241 * \param[in] pt XYZ from which the ray will start (toward the camera)
242 * \param[in] octree the octree used for raycasting. It must be initialized with a cloud transformed into the camera's frame
243 * \returns true if the point is occluded.
244 */
245 inline bool
246 isPointOccluded (const PointInT &pt, const OctreePtr octree);
247
248 /** \brief Remove occluded points from a point cloud
249 * \param[in] input_cloud the cloud on which to perform occlusion detection
250 * \param[out] filtered_cloud resulting cloud, containing only visible points
251 * \param[in] octree_voxel_size octree resolution (in meters)
252 * \param[out] visible_indices will contain indices of visible points
253 * \param[out] occluded_indices will contain indices of occluded points
254 */
255 void
256 removeOccludedPoints (const PointCloudPtr &input_cloud,
257 PointCloudPtr &filtered_cloud, const double octree_voxel_size,
258 pcl::Indices &visible_indices, pcl::Indices &occluded_indices);
259
260 /** \brief Remove occluded points from a textureMesh
261 * \param[in] tex_mesh input mesh, on witch to perform occlusion detection
262 * \param[out] cleaned_mesh resulting mesh, containing only visible points
263 * \param[in] octree_voxel_size octree resolution (in meters)
264 */
265 void
266 removeOccludedPoints (const pcl::TextureMesh &tex_mesh, pcl::TextureMesh &cleaned_mesh, const double octree_voxel_size);
267
268
269 /** \brief Remove occluded points from a textureMesh
270 * \param[in] tex_mesh input mesh, on witch to perform occlusion detection
271 * \param[out] filtered_cloud resulting cloud, containing only visible points
272 * \param[in] octree_voxel_size octree resolution (in meters)
273 */
274 void
275 removeOccludedPoints (const pcl::TextureMesh &tex_mesh, PointCloudPtr &filtered_cloud, const double octree_voxel_size);
276
277
278 /** \brief Segment faces by camera visibility. Point-based segmentation.
279 * \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.
280 * \param[in] tex_mesh input mesh that needs sorting. Must contain only 1 sub-mesh.
281 * \param[in] sorted_mesh resulting mesh, will contain nbCamera + 1 sub-mesh.
282 * \param[in] cameras vector containing the cameras used for texture mapping.
283 * \param[in] octree_voxel_size octree resolution (in meters)
284 * \param[out] visible_pts cloud containing only visible points
285 */
286 int
288 pcl::TextureMesh &sorted_mesh,
290 const double octree_voxel_size, PointCloud &visible_pts);
291
292 /** \brief Colors a point cloud, depending on its occlusions.
293 * \details If showNbOcclusions is set to True, each point is colored depending on the number of points occluding it.
294 * Else, each point is given a different a 0 value is not occluded, 1 if occluded.
295 * By default, the number of occlusions is bounded to 4.
296 * \param[in] input_cloud input cloud on which occlusions will be computed.
297 * \param[out] colored_cloud resulting colored cloud showing the number of occlusions per point.
298 * \param[in] octree_voxel_size octree resolution (in meters).
299 * \param[in] show_nb_occlusions If false, color information will only represent.
300 * \param[in] max_occlusions Limit the number of occlusions per point.
301 */
302 void
303 showOcclusions (const PointCloudPtr &input_cloud,
305 const double octree_voxel_size,
306 const bool show_nb_occlusions = true,
307 const int max_occlusions = 4);
308
309 /** \brief Colors the point cloud of a Mesh, depending on its occlusions.
310 * \details If showNbOcclusions is set to True, each point is colored depending on the number of points occluding it.
311 * Else, each point is given a different a 0 value is not occluded, 1 if occluded.
312 * By default, the number of occlusions is bounded to 4.
313 * \param[in] tex_mesh input mesh on which occlusions will be computed.
314 * \param[out] colored_cloud resulting colored cloud showing the number of occlusions per point.
315 * \param[in] octree_voxel_size octree resolution (in meters).
316 * \param[in] show_nb_occlusions If false, color information will only represent.
317 * \param[in] max_occlusions Limit the number of occlusions per point.
318 */
319 void
322 double octree_voxel_size,
323 bool show_nb_occlusions = true,
324 int max_occlusions = 4);
325
326 /** \brief Segment and texture faces by camera visibility. Face-based segmentation.
327 * \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.
328 * The mesh will also contain uv coordinates for each face
329 * \param mesh input mesh that needs sorting. Should contain only 1 sub-mesh.
330 * \param[in] cameras vector containing the cameras used for texture mapping.
331 */
332 void
335
336 protected:
337 /** \brief mesh scale control. */
338 float f_;
339
340 /** \brief vector field */
341 Eigen::Vector3f vector_field_;
342
343 /** \brief list of texture files */
344 std::vector<std::string> tex_files_;
345
346 /** \brief list of texture materials */
348
349 /** \brief Map texture to a face
350 * \param[in] p1 the first point
351 * \param[in] p2 the second point
352 * \param[in] p3 the third point
353 */
354 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
355 mapTexture2Face (const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p3);
356
357 /** \brief Returns the circumcenter of a triangle and the circle's radius.
358 * \details see http://en.wikipedia.org/wiki/Circumcenter for formulas.
359 * \param[in] p1 first point of the triangle.
360 * \param[in] p2 second point of the triangle.
361 * \param[in] p3 third point of the triangle.
362 * \param[out] circumcenter resulting circumcenter
363 * \param[out] radius the radius of the circumscribed circle.
364 */
365 inline void
366 getTriangleCircumcenterAndSize (const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius);
367
368
369 /** \brief Returns the centroid of a triangle and the corresponding circumscribed circle's radius.
370 * \details yield a tighter circle than getTriangleCircumcenterAndSize.
371 * \param[in] p1 first point of the triangle.
372 * \param[in] p2 second point of the triangle.
373 * \param[in] p3 third point of the triangle.
374 * \param[out] circumcenter resulting circumcenter
375 * \param[out] radius the radius of the circumscribed circle.
376 */
377 inline void
378 getTriangleCircumcscribedCircleCentroid ( const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius);
379
380
381 /** \brief computes UV coordinates of point, observed by one particular camera
382 * \param[in] pt XYZ point to project on camera plane
383 * \param[in] cam the camera used for projection
384 * \param[out] UV_coordinates the resulting UV coordinates. Set to (-1.0,-1.0) if the point is not visible by the camera
385 * \returns false if the point is not visible by the camera
386 */
387 inline bool
388 getPointUVCoordinates (const PointInT &pt, const Camera &cam, pcl::PointXY &UV_coordinates);
389
390 /** \brief Returns true if all the vertices of one face are projected on the camera's image plane.
391 * \param[in] camera camera on which to project the face.
392 * \param[in] p1 first point of the face.
393 * \param[in] p2 second point of the face.
394 * \param[in] p3 third point of the face.
395 * \param[out] proj1 UV coordinates corresponding to p1.
396 * \param[out] proj2 UV coordinates corresponding to p2.
397 * \param[out] proj3 UV coordinates corresponding to p3.
398 */
399 inline bool
400 isFaceProjected (const Camera &camera,
401 const PointInT &p1, const PointInT &p2, const PointInT &p3,
402 pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3);
403
404 /** \brief Returns True if a point lays within a triangle
405 * \details see http://www.blackpawn.com/texts/pointinpoly/default.html
406 * \param[in] p1 first point of the triangle.
407 * \param[in] p2 second point of the triangle.
408 * \param[in] p3 third point of the triangle.
409 * \param[in] pt the querry point.
410 */
411 inline bool
412 checkPointInsideTriangle (const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt);
413
414 /** \brief Class get name method. */
415 std::string
417 {
418 return ("TextureMapping");
419 }
420
421 public:
423 };
424}
shared_ptr< PointCloud< PointInT > > Ptr
Definition: point_cloud.h:413
shared_ptr< const PointCloud< PointInT > > ConstPtr
Definition: point_cloud.h:414
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
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.
TextureMapping()
Constructor.
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
Definition: octree_search.h:58
shared_ptr< const OctreePointCloudSearch< PointT, LeafContainerT, BranchContainerT > > ConstPtr
Definition: octree_search.h:72
shared_ptr< OctreePointCloudSearch< PointT, LeafContainerT, BranchContainerT > > Ptr
Definition: octree_search.h:70
#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.