Point Cloud Library (PCL)  1.9.1-dev
edge.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2012-, Open Perception, 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 the copyright holder(s) 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  */
37 
38 #pragma once
39 
40 #include <pcl/2d/convolution.h>
41 #include <pcl/2d/kernel.h>
42 #include <pcl/pcl_base.h>
43 #include <pcl/pcl_macros.h>
44 
45 namespace pcl {
46 
47 template <typename PointInT, typename PointOutT>
48 class Edge {
49 private:
51  using PointCloudInPtr = typename PointCloudIn::Ptr;
52 
53  PointCloudInPtr input_;
54  pcl::Convolution<PointInT> convolution_;
55  kernel<PointInT> kernel_;
56 
57  /** \brief This function performs edge tracing for Canny Edge detector.
58  *
59  * \param[in] rowOffset row offset for direction in which the edge is to be traced
60  * \param[in] colOffset column offset for direction in which the edge is to be traced
61  * \param[in] row row location of the edge point
62  * \param[in] col column location of the edge point
63  * \param[out] maxima point cloud containing the edge information in the magnitude
64  * channel
65  */
66  inline void
67  cannyTraceEdge(int rowOffset,
68  int colOffset,
69  int row,
70  int col,
72 
73  /** \brief This function discretizes the edge directions in steps of 22.5 degrees.
74  * \param thet point cloud containing the edge information in the direction channel
75  */
76  void
77  discretizeAngles(pcl::PointCloud<PointOutT>& thet);
78 
79  /** \brief This function suppresses the edges which don't form a local maximum
80  * in the edge direction.
81  * \param[in] edges point cloud containing all the edges
82  * \param[out] maxima point cloud containing the non-max suppressed edges
83  * \param[in] tLow
84  */
85  void
86  suppressNonMaxima(const pcl::PointCloud<PointXYZIEdge>& edges,
88  float tLow);
89 
90 public:
91  using Ptr = boost::shared_ptr<Edge<PointInT, PointOutT>>;
92  using ConstPtr = boost::shared_ptr<const Edge<PointInT, PointOutT>>;
93 
94  enum OUTPUT_TYPE {
102  };
103 
113  };
114 
115 private:
116  OUTPUT_TYPE output_type_;
117  DETECTOR_KERNEL_TYPE detector_kernel_type_;
118  bool non_maximal_suppression_;
119  bool hysteresis_thresholding_;
120 
121  float hysteresis_threshold_low_;
122  float hysteresis_threshold_high_;
123  float non_max_suppression_radius_x_;
124  float non_max_suppression_radius_y_;
125 
126 public:
128  : output_type_(OUTPUT_X)
129  , detector_kernel_type_(SOBEL)
130  , non_maximal_suppression_(false)
131  , hysteresis_thresholding_(false)
132  , hysteresis_threshold_low_(20)
133  , hysteresis_threshold_high_(80)
134  , non_max_suppression_radius_x_(3)
135  , non_max_suppression_radius_y_(3)
136  {}
137 
138  /** \brief Set the output type.
139  * \param[in] output_type the output type
140  */
141  void
143  {
144  output_type_ = output_type;
145  }
146 
147  void
148  setHysteresisThresholdLow(float threshold)
149  {
150  hysteresis_threshold_low_ = threshold;
151  }
152 
153  void
154  setHysteresisThresholdHigh(float threshold)
155  {
156  hysteresis_threshold_high_ = threshold;
157  }
158 
159  /**
160  * \param[in] input_x
161  * \param[in] input_y
162  * \param[out] output
163  */
164  void
166  const pcl::PointCloud<PointInT>& input_y,
168 
169  /** Perform Canny edge detection with two separated input images for horizontal and
170  * vertical derivatives.
171  *
172  * All edges of magnitude above t_high are always classified as edges. All edges
173  * below t_low are discarded. Edge values between t_low and t_high are classified
174  * as edges only if they are connected to edges having magnitude > t_high and are
175  * located in a direction perpendicular to that strong edge.
176  *
177  * \param[in] input_x Input point cloud passed by reference for the first derivative
178  * in the horizontal direction
179  * \param[in] input_y Input point cloud passed by reference for the first derivative
180  * in the vertical direction
181  * \param[out] output Output point cloud passed by reference
182  */
183  void
184  canny(const pcl::PointCloud<PointInT>& input_x,
185  const pcl::PointCloud<PointInT>& input_y,
187 
188  /** \brief This is a convenience function which performs edge detection based on
189  * the variable detector_kernel_type_
190  * \param[out] output
191  */
192  void
194 
195  /** \brief All edges of magnitude above t_high are always classified as edges.
196  * All edges below t_low are discarded.
197  * Edge values between t_low and t_high are classified as edges only if they are
198  * connected to edges having magnitude > t_high and are located in a direction
199  * perpendicular to that strong edge.
200  * \param[out] output Output point cloud passed by reference
201  */
202  void
204 
205  /** \brief Uses the Sobel kernel for edge detection.
206  * This function does NOT include a smoothing step.
207  * The image should be smoothed before using this function to reduce noise.
208  * \param[out] output Output point cloud passed by reference
209  */
210  void
212 
213  /** \brief Uses the Prewitt kernel for edge detection.
214  * This function does NOT include a smoothing step.
215  * The image should be smoothed before using this function to reduce noise.
216  * \param[out] output Output point cloud passed by reference
217  */
218  void
220 
221  /** \brief Uses the Roberts kernel for edge detection.
222  * This function does NOT include a smoothing step.
223  * The image should be smoothed before using this function to reduce noise.
224  * \param[out] output Output point cloud passed by reference
225  */
226  void
228 
229  /** \brief Uses the LoG kernel for edge detection.
230  * Zero crossings of the Laplacian operator applied on an image indicate edges.
231  * Gaussian kernel is used to smoothen the image prior to the Laplacian.
232  * This is because Laplacian uses the second order derivative of the image and hence,
233  * is very sensitive to noise. The implementation is not two-step but rather applies
234  * the LoG kernel directly.
235  *
236  * \param[in] kernel_sigma variance of the LoG kernel used.
237  * \param[in] kernel_size a LoG kernel of dimensions kernel_size x kernel_size is
238  * used.
239  * \param[out] output Output point cloud passed by reference.
240  */
241  void
242  detectEdgeLoG(const float kernel_sigma,
243  const float kernel_size,
245 
246  /** \brief Computes the image derivatives in X direction using the kernel
247  * kernel::derivativeYCentralKernel. This function does NOT include a smoothing step.
248  * The image should be smoothed before using this function to reduce noise.
249  * \param[out] output Output point cloud passed by reference
250  */
251  void
253 
254  /** \brief Computes the image derivatives in Y direction using the kernel
255  * kernel::derivativeYCentralKernel. This function does NOT include a smoothing step.
256  * The image should be smoothed before using this function to reduce noise.
257  * \param[out] output Output point cloud passed by reference
258  */
259  void
261 
262  /** \brief Computes the image derivatives in X direction using the kernel
263  * kernel::derivativeYForwardKernel. This function does NOT include a smoothing step.
264  * The image should be smoothed before using this function to reduce noise.
265  * \param[out] output Output point cloud passed by reference
266  */
267  void
269 
270  /** \brief Computes the image derivatives in Y direction using the kernel
271  * kernel::derivativeYForwardKernel. This function does NOT include a smoothing step.
272  * The image should be smoothed before using this function to reduce noise.
273  * \param[out] output Output point cloud passed by reference
274  */
275  void
277 
278  /** \brief Computes the image derivatives in X direction using the kernel
279  * kernel::derivativeXBackwardKernel. This function does NOT include a smoothing step.
280  * The image should be smoothed before using this function to reduce noise.
281  * \param output Output point cloud passed by reference
282  */
283  void
285 
286  /** \brief Computes the image derivatives in Y direction using the kernel
287  * kernel::derivativeYBackwardKernel. This function does NOT include a smoothing step.
288  * The image should be smoothed before using this function to reduce noise.
289  * \param[out] output Output point cloud passed by reference
290  */
291  void
293 
294  /** \brief Override function to implement the pcl::Filter interface */
295  void
297  {}
298 
299  /** \brief Set the input point cloud pointer
300  * \param[in] input pointer to input point cloud
301  */
302  void
303  setInputCloud(PointCloudInPtr input)
304  {
305  input_ = input;
306  }
307 
309 };
310 
311 } // namespace pcl
312 
313 #include <pcl/2d/impl/edge.hpp>
DETECTOR_KERNEL_TYPE
Definition: edge.h:104
void computeDerivativeYBackward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in Y direction using the kernel kernel::derivativeYBackwardKernel.
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
boost::shared_ptr< const Edge< PointInT, PointOutT > > ConstPtr
Definition: edge.h:92
void setOutputType(OUTPUT_TYPE output_type)
Set the output type.
Definition: edge.h:142
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition: pcl_macros.h:345
void setHysteresisThresholdHigh(float threshold)
Definition: edge.h:154
Definition: edge.h:48
void applyFilter(pcl::PointCloud< PointOutT > &)
Override function to implement the pcl::Filter interface.
Definition: edge.h:296
OUTPUT_TYPE
Definition: edge.h:94
void sobelMagnitudeDirection(const pcl::PointCloud< PointInT > &input_x, const pcl::PointCloud< PointInT > &input_y, pcl::PointCloud< PointOutT > &output)
Definition: edge.hpp:85
void setInputCloud(PointCloudInPtr input)
Set the input point cloud pointer.
Definition: edge.h:303
void computeDerivativeXBackward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in X direction using the kernel kernel::derivativeXBackwardKernel.
void computeDerivativeXForward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in X direction using the kernel kernel::derivativeYForwardKernel.
void computeDerivativeYForward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in Y direction using the kernel kernel::derivativeYForwardKernel.
void detectEdgePrewitt(pcl::PointCloud< PointOutT > &output)
Uses the Prewitt kernel for edge detection.
Definition: edge.hpp:127
void setHysteresisThresholdLow(float threshold)
Definition: edge.h:148
boost::shared_ptr< PointCloud< PointInT > > Ptr
Definition: point_cloud.h:444
void detectEdge(pcl::PointCloud< PointOutT > &output)
This is a convenience function which performs edge detection based on the variable detector_kernel_ty...
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...
Definition: edge.hpp:383
void detectEdgeSobel(pcl::PointCloud< PointOutT > &output)
Uses the Sobel kernel for edge detection.
Definition: edge.hpp:47
void detectEdgeLoG(const float kernel_sigma, const float kernel_size, pcl::PointCloud< PointOutT > &output)
Uses the LoG kernel for edge detection.
Definition: edge.hpp:458
void computeDerivativeYCentral(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in Y direction using the kernel kernel::derivativeYCentralKernel.
void computeDerivativeXCentral(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in X direction using the kernel kernel::derivativeYCentralKernel.
boost::shared_ptr< Edge< PointInT, PointOutT > > Ptr
Definition: edge.h:91
Defines all the PCL and non-PCL macros used.
void detectEdgeCanny(pcl::PointCloud< PointOutT > &output)
All edges of magnitude above t_high are always classified as edges.
Definition: edge.hpp:318
void detectEdgeRoberts(pcl::PointCloud< PointOutT > &output)
Uses the Roberts kernel for edge detection.
Definition: edge.hpp:166
Edge()
Definition: edge.h:127