39#ifndef PCL_VISUALIZATION_IMAGE_VISUALIZER_HPP_
40#define PCL_VISUALIZATION_IMAGE_VISUALIZER_HPP_
42#include <vtkVersion.h>
43#include <vtkContextActor.h>
44#include <vtkContextScene.h>
45#include <vtkImageData.h>
46#include <vtkImageFlip.h>
47#include <vtkPointData.h>
48#include <vtkImageViewer.h>
50#include <pcl/visualization/common/common.h>
51#include <pcl/search/organized.h>
54template <
typename T>
void
57 boost::shared_array<unsigned char> &data)
60 for (
const auto& point: cloud)
69template <
typename T>
void
74 if (data_size_ < cloud.width * cloud.height)
76 data_size_ = cloud.width * cloud.height * 3;
77 data_.
reset (
new unsigned char[data_size_]);
80 convertRGBCloudToUChar (cloud, data_);
82 return (addRGBImage (data_.get (), cloud.width, cloud.height,
layer_id,
opacity));
86template <
typename T>
void
96template <
typename T>
bool
100 double r,
double g,
double b,
104 if (!image->isOrganized ())
108 LayerMap::iterator
am_it = std::find_if (layer_map_.begin (), layer_map_.end (), LayerComparator (
layer_id));
109 if (
am_it == layer_map_.end ())
111 PCL_DEBUG (
"[pcl::visualization::ImageViewer::addMask] No layer with ID'=%s' found. Creating new one...\n",
layer_id.c_str ());
118 std::vector<float>
xy;
120 for (std::size_t i = 0; i <
mask.
size (); ++i)
126 xy.push_back (
static_cast<float> (image->height) -
p_projected.y);
130 points->setColors (
static_cast<unsigned char> (r*255.0),
131 static_cast<unsigned char> (g*255.0),
132 static_cast<unsigned char> (b*255.0));
135 am_it->actor->GetScene ()->AddItem (points);
140template <
typename T>
bool
150template <
typename T>
bool
154 double r,
double g,
double b,
158 if (!image->isOrganized ())
162 LayerMap::iterator
am_it = std::find_if (layer_map_.begin (), layer_map_.end (), LayerComparator (
layer_id));
163 if (
am_it == layer_map_.end ())
165 PCL_DEBUG (
"[pcl::visualization::ImageViewer::addPlanarPolygon] No layer with ID'=%s' found. Creating new one...\n",
layer_id.c_str ());
172 std::vector<float>
xy;
174 for (std::size_t i = 0; i <
polygon.getContour ().size (); ++i)
187 poly->setColors (
static_cast<unsigned char> (r * 255.0),
188 static_cast<unsigned char> (g * 255.0),
189 static_cast<unsigned char> (b * 255.0));
192 am_it->actor->GetScene ()->AddItem (
poly);
198template <
typename T>
bool
208template <
typename T>
bool
213 double r,
double g,
double b,
217 if (!image->isOrganized ())
221 LayerMap::iterator
am_it = std::find_if (layer_map_.begin (), layer_map_.end (), LayerComparator (
layer_id));
222 if (
am_it == layer_map_.end ())
224 PCL_DEBUG (
"[pcl::visualization::ImageViewer::addRectangle] No layer with ID'=%s' found. Creating new one...\n",
layer_id.c_str ());
242 std::vector<pcl::PointXY>
pp_2d (8);
256 for (
const auto &point :
pp_2d)
267 rect->setColors (
static_cast<unsigned char> (255.0 * r),
268 static_cast<unsigned char> (255.0 * g),
269 static_cast<unsigned char> (255.0 * b));
272 am_it->actor->GetScene ()->AddItem (
rect);
278template <
typename T>
bool
289template <
typename T>
bool
293 double r,
double g,
double b,
297 if (!image->isOrganized ())
301 LayerMap::iterator
am_it = std::find_if (layer_map_.begin (), layer_map_.end (), LayerComparator (
layer_id));
302 if (
am_it == layer_map_.end ())
304 PCL_DEBUG (
"[pcl::visualization::ImageViewer::addRectangle] No layer with ID'=%s' found. Creating new one...\n",
layer_id.c_str ());
312 for (std::size_t i = 0; i <
mask.
size (); ++i)
319 for (
const auto &point :
pp_2d)
330 rect->setColors (
static_cast<unsigned char> (255.0 * r),
331 static_cast<unsigned char> (255.0 * g),
332 static_cast<unsigned char> (255.0 * b));
335 am_it->actor->GetScene ()->AddItem (
rect);
341template <
typename T>
bool
351template <
typename Po
intT>
bool
359 if (correspondences.empty ())
361 PCL_DEBUG (
"[pcl::visualization::ImageViewer::addCorrespondences] An empty set of correspondences given! Nothing to display.\n");
366 LayerMap::iterator
am_it = std::find_if (layer_map_.begin (), layer_map_.end (), LayerComparator (
layer_id));
367 if (
am_it == layer_map_.end ())
369 PCL_DEBUG (
"[pcl::visualization::ImageViewer::addCorrespondences] No layer with ID='%s' found. Creating new one...\n",
layer_id.c_str ());
383 data_.
reset (
new unsigned char[data_size_]);
393 for (std::size_t k = 0; k <
source_img.width; ++k)
409 for (std::size_t k = 0; k <
target_img.width; ++k)
423 void* data =
const_cast<void*
> (
reinterpret_cast<const void*
> (data_.get ()));
428 image->GetPointData ()->GetScalars ()->SetVoidArray (data, data_size_, 1);
431 interactor_style_->adjustCamera (image, ren_);
433 image_viewer_->SetSize (image->GetDimensions ()[0], image->GetDimensions ()[1]);
436 for (std::size_t i = 0; i < correspondences.size (); i +=
nth)
440 unsigned char u_r =
static_cast<unsigned char> (255.0 * r);
441 unsigned char u_g =
static_cast<unsigned char> (255.0 * g);
442 unsigned char u_b =
static_cast<unsigned char> (255.0 * b);
452 float query_y = getSize ()[1] - correspondences[i].index_query /
source_img.width;
453 float match_y = getSize ()[1] - correspondences[i].index_match /
target_img.width;
461 am_it->actor->GetScene ()->AddItem (
line);
Iterator class for point clouds with or without given indices.
std::size_t size() const
Size of the range the iterator is going through.
shared_ptr< const PointCloud< PointT > > ConstPtr
OrganizedNeighbor is a class for optimized nearest neigbhor search in organized point clouds.
void setInputCloud(const PointCloudConstPtr &cloud, const IndicesConstPtr &indices=IndicesConstPtr()) override
Provide a pointer to the input data set, if user has focal length he must set it before calling this.
bool projectPoint(const PointT &p, pcl::PointXY &q) const
projects a point into the image
bool addMask(const typename pcl::PointCloud< T >::ConstPtr &image, const pcl::PointCloud< T > &mask, double r, double g, double b, const std::string &layer_id="image_mask", double opacity=0.5)
Add a generic 2D mask to an image.
bool addRectangle(const pcl::PointXY &min_pt, const pcl::PointXY &max_pt, const std::string &layer_id="rectangles", double opacity=1.0)
Add a 2D box and color its edges with a given color.
void showRGBImage(const unsigned char *data, unsigned width, unsigned height, const std::string &layer_id="rgb_image", double opacity=1.0)
Show a 2D RGB image on screen.
bool addPlanarPolygon(const typename pcl::PointCloud< T >::ConstPtr &image, const pcl::PlanarPolygon< T > &polygon, double r, double g, double b, const std::string &layer_id="planar_polygon", double opacity=1.0)
Add a generic 2D planar polygon to an image.
bool showCorrespondences(const pcl::PointCloud< PointT > &source_img, const pcl::PointCloud< PointT > &target_img, const pcl::Correspondences &correspondences, int nth=1, const std::string &layer_id="correspondences")
Add the specified correspondences to the display.
void convertRGBCloudToUChar(const pcl::PointCloud< T > &cloud, boost::shared_array< unsigned char > &data)
Convert the RGB information in a PointCloud<T> to an unsigned char array.
void addRGBImage(const unsigned char *data, unsigned width, unsigned height, const std::string &layer_id="rgb_image", double opacity=1.0, bool autoresize=true)
Add an RGB 2D image layer, but do not render it (use spin/spinOnce to update).
PCL_EXPORTS void getRandomColors(double &r, double &g, double &b, double min=0.2, double max=2.8)
Get (good) random values for R/G/B.
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
A 2D point structure representing Euclidean xy coordinates.