38#ifndef PCL_FEATURES_IMPL_ORGANIZED_EDGE_DETECTION_H_
39#define PCL_FEATURES_IMPL_ORGANIZED_EDGE_DETECTION_H_
41#include <pcl/2d/edge.h>
42#include <pcl/features/organized_edge_detection.h>
51template<
typename Po
intT,
typename Po
intLT>
void
55 invalid_pt.
label =
static_cast<unsigned>(0);
66template<
typename Po
intT,
typename Po
intLT>
void
69 const auto invalid_label =
static_cast<unsigned>(0);
71 for (std::size_t idx = 0; idx <
input_->size (); idx++)
73 if (labels[idx].label != invalid_label)
77 if ((labels[idx].label >> edge_type) & 1)
78 label_indices[edge_type].indices.push_back (idx);
85template<
typename Po
intT,
typename Po
intLT>
void
91 const int num_of_ngbr = 8;
101 for (
int row = 1; row < static_cast<int>(
input_->height) - 1; row++)
103 for (
int col = 1; col < static_cast<int>(
input_->width) - 1; col++)
105 int curr_idx = row*
static_cast<int>(
input_->width) + col;
106 if (!std::isfinite ((*
input_)[curr_idx].z))
109 float curr_depth = std::abs ((*
input_)[curr_idx].z);
112 std::vector<float> nghr_dist;
113 nghr_dist.resize (8);
114 bool found_invalid_neighbor =
false;
115 for (
int d_idx = 0; d_idx < num_of_ngbr; d_idx++)
117 int nghr_idx = curr_idx + directions[d_idx].
d_index;
118 assert (nghr_idx >= 0 &&
static_cast<std::size_t
>(nghr_idx) <
input_->size ());
119 if (!std::isfinite ((*
input_)[nghr_idx].z))
121 found_invalid_neighbor =
true;
124 nghr_dist[d_idx] = curr_depth - std::abs ((*
input_)[nghr_idx].z);
127 if (!found_invalid_neighbor)
130 std::vector<float>::const_iterator min_itr, max_itr;
131 std::tie (min_itr, max_itr) = std::minmax_element (nghr_dist.cbegin (), nghr_dist.cend ());
132 float nghr_dist_min = *min_itr;
133 float nghr_dist_max = *max_itr;
134 float dist_dominant = std::abs (nghr_dist_min) > std::abs (nghr_dist_max) ? nghr_dist_min : nghr_dist_max;
138 if (dist_dominant > 0.f)
157 int num_of_invalid_pt = 0;
158 for (
const auto &direction : directions)
160 int nghr_idx = curr_idx + direction.d_index;
161 assert (nghr_idx >= 0 &&
static_cast<std::size_t
>(nghr_idx) <
input_->size ());
162 if (!std::isfinite ((*
input_)[nghr_idx].z))
171 assert (num_of_invalid_pt > 0);
172 float f_dx =
static_cast<float> (dx) /
static_cast<float> (num_of_invalid_pt);
173 float f_dy =
static_cast<float> (dy) /
static_cast<float> (num_of_invalid_pt);
176 float corr_depth = std::numeric_limits<float>::quiet_NaN ();
179 int s_row = row +
static_cast<int> (std::floor (f_dy*
static_cast<float> (s_idx)));
180 int s_col = col +
static_cast<int> (std::floor (f_dx*
static_cast<float> (s_idx)));
182 if (s_row < 0 || s_row >=
static_cast<int>(
input_->height) || s_col < 0 || s_col >=
static_cast<int>(
input_->width))
185 if (std::isfinite ((*
input_)[s_row*
static_cast<int>(
input_->width)+s_col].z))
187 corr_depth = std::abs ((*
input_)[s_row*
static_cast<int>(
input_->width)+s_col].z);
192 if (!std::isnan (corr_depth))
195 float dist = curr_depth - corr_depth;
225template<
typename Po
intT,
typename Po
intLT>
void
229 invalid_pt.
label =
static_cast<unsigned>(0);
241template<
typename Po
intT,
typename Po
intLT>
void
251 for (std::size_t i = 0; i <
input_->size (); ++i)
252 (*gray)[i].intensity =
static_cast<float>(((*input_)[i].r + (*input_)[i].g + (*input_)[i].b) / 3);
261 for (std::uint32_t row=0; row<labels.
height; row++)
263 for (std::uint32_t col=0; col<labels.
width; col++)
265 if (img_edge_rgb (col, row).magnitude == 255.f)
273template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
277 invalid_pt.
label =
static_cast<unsigned>(0);
289template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
304 for (std::uint32_t row=0; row<
normals_->height; row++)
306 for (std::uint32_t col=0; col<
normals_->width; col++)
308 nx (col, row).intensity = (*normals_)[row*
normals_->width + col].normal_x;
309 ny (col, row).intensity = (*normals_)[row*
normals_->width + col].normal_y;
317 edge.
canny (nx, ny, img_edge);
319 for (std::uint32_t row=0; row<labels.
height; row++)
321 for (std::uint32_t col=0; col<labels.
width; col++)
323 if (img_edge (col, row).magnitude == 255.f)
331template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
335 invalid_pt.
label =
static_cast<unsigned>(0);
347#define PCL_INSTANTIATE_OrganizedEdgeBase(T,LT) template class PCL_EXPORTS pcl::OrganizedEdgeBase<T,LT>;
348#define PCL_INSTANTIATE_OrganizedEdgeFromRGB(T,LT) template class PCL_EXPORTS pcl::OrganizedEdgeFromRGB<T,LT>;
349#define PCL_INSTANTIATE_OrganizedEdgeFromNormals(T,NT,LT) template class PCL_EXPORTS pcl::OrganizedEdgeFromNormals<T,NT,LT>;
350#define PCL_INSTANTIATE_OrganizedEdgeFromRGBNormals(T,NT,LT) template class PCL_EXPORTS pcl::OrganizedEdgeFromRGBNormals<T,NT,LT>;
void setHysteresisThresholdHigh(float threshold)
void canny(const pcl::PointCloud< PointInT > &input_x, const pcl::PointCloud< PointInT > &input_y, pcl::PointCloud< PointOutT > &output)
Perform Canny edge detection with two separated input images for horizontal and vertical derivatives.
void detectEdgeCanny(pcl::PointCloud< PointOutT > &output)
All edges of magnitude above t_high are always classified as edges.
void setHysteresisThresholdLow(float threshold)
void setInputCloud(PointCloudInPtr input)
Set the input point cloud pointer.
static const int num_of_edgetype_
float th_depth_discon_
The tolerance in meters for the relative difference in depth values between neighboring points (The d...
int detecting_edge_types_
The bit encoded value that represents edge types to detect.
@ EDGELABEL_HIGH_CURVATURE
void assignLabelIndices(pcl::PointCloud< PointLT > &labels, std::vector< pcl::PointIndices > &label_indices) const
Assign point indices for each edge label.
void extractEdges(pcl::PointCloud< PointLT > &labels) const
Perform the 3D edge detection (edges from depth discontinuities) and assign point indices for each ed...
void compute(pcl::PointCloud< PointLT > &labels, std::vector< pcl::PointIndices > &label_indices) const
Perform the 3D edge detection (edges from depth discontinuities).
int max_search_neighbors_
The max search distance for deciding occluding and occluded edges.
void compute(pcl::PointCloud< PointLT > &labels, std::vector< pcl::PointIndices > &label_indices) const
Perform the 3D edge detection (edges from depth discontinuities and high curvature regions) and assig...
PointCloudNConstPtr normals_
A pointer to the input normals.
float th_hc_canny_high_
The high threshold value for high curvature Canny edge detection (default: 1.1).
void extractEdges(pcl::PointCloud< PointLT > &labels) const
Perform the 3D edge detection (edges from depth discontinuities and high curvature regions).
float th_hc_canny_low_
The low threshold value for high curvature Canny edge detection (default: 0.4).
void extractEdges(pcl::PointCloud< PointLT > &labels) const
Perform the 3D edge detection (edges from depth discontinuities and RGB Canny edge).
float th_rgb_canny_high_
The high threshold value for RGB Canny edge detection (default: 100.0).
float th_rgb_canny_low_
The low threshold value for RGB Canny edge detection (default: 40.0).
void compute(pcl::PointCloud< PointLT > &labels, std::vector< pcl::PointIndices > &label_indices) const
Perform the 3D edge detection (edges from depth discontinuities and RGB Canny edge) and assign point ...
void compute(pcl::PointCloud< PointLT > &labels, std::vector< pcl::PointIndices > &label_indices) const
Perform the 3D edge detection (edges from depth discontinuities, RGB Canny edge, and high curvature r...
PointCloudConstPtr input_
The input point cloud dataset.
PointCloud represents the base class in PCL for storing collections of 3D points.
void resize(std::size_t count)
Resizes the container to contain count elements.
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::uint32_t height
The point cloud height (if organized as an image-structure).
shared_ptr< PointCloud< PointT > > Ptr