Point Cloud Library (PCL)  1.13.0-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/memory.h>
43 #include <pcl/pcl_base.h>
44 #include <pcl/pcl_macros.h>
45 
46 namespace pcl {
47 
48 template <typename PointInT, typename PointOutT>
49 class Edge {
50 private:
52  using PointCloudInPtr = typename PointCloudIn::Ptr;
53 
54  PointCloudInPtr input_;
55  pcl::Convolution<PointInT> convolution_;
56  kernel<PointInT> kernel_;
57 
58  /** \brief This function performs edge tracing for Canny Edge detector.
59  *
60  * \param[in] rowOffset row offset for direction in which the edge is to be traced
61  * \param[in] colOffset column offset for direction in which the edge is to be traced
62  * \param[in] row row location of the edge point
63  * \param[in] col column location of the edge point
64  * \param[out] maxima point cloud containing the edge information in the magnitude
65  * channel
66  */
67  inline void
68  cannyTraceEdge(int rowOffset,
69  int colOffset,
70  int row,
71  int col,
73 
74  /** \brief This function discretizes the edge directions in steps of 22.5 degrees.
75  * \param thet point cloud containing the edge information in the direction channel
76  */
77  void
78  discretizeAngles(pcl::PointCloud<PointOutT>& thet);
79 
80  /** \brief This function suppresses the edges which don't form a local maximum
81  * in the edge direction.
82  * \param[in] edges point cloud containing all the edges
83  * \param[out] maxima point cloud containing the non-max suppressed edges
84  * \param[in] tLow
85  */
86  void
87  suppressNonMaxima(const pcl::PointCloud<PointXYZIEdge>& edges,
89  float tLow);
90 
91 public:
92  using Ptr = shared_ptr<Edge<PointInT, PointOutT>>;
93  using ConstPtr = shared_ptr<const Edge<PointInT, PointOutT>>;
94 
95  enum OUTPUT_TYPE {
102  OUTPUT_ALL
103  };
104 
114  };
115 
116 private:
117  OUTPUT_TYPE output_type_;
118  DETECTOR_KERNEL_TYPE detector_kernel_type_;
119  bool non_maximal_suppression_;
120  bool hysteresis_thresholding_;
121 
122  float hysteresis_threshold_low_;
123  float hysteresis_threshold_high_;
124  float non_max_suppression_radius_x_;
125  float non_max_suppression_radius_y_;
126 
127 public:
129  : output_type_(OUTPUT_X)
130  , detector_kernel_type_(SOBEL)
131  , non_maximal_suppression_(false)
132  , hysteresis_thresholding_(false)
133  , hysteresis_threshold_low_(20)
134  , hysteresis_threshold_high_(80)
135  , non_max_suppression_radius_x_(3)
136  , non_max_suppression_radius_y_(3)
137  {}
138 
139  /** \brief Set the output type.
140  * \param[in] output_type the output type
141  */
142  void
144  {
145  output_type_ = output_type;
146  }
147 
148  void
149  setHysteresisThresholdLow(float threshold)
150  {
151  hysteresis_threshold_low_ = threshold;
152  }
153 
154  void
155  setHysteresisThresholdHigh(float threshold)
156  {
157  hysteresis_threshold_high_ = threshold;
158  }
159 
160  /**
161  * \param[in] input_x
162  * \param[in] input_y
163  * \param[out] output
164  */
165  void
167  const pcl::PointCloud<PointInT>& input_y,
169 
170  /** Perform Canny edge detection with two separated input images for horizontal and
171  * vertical derivatives.
172  *
173  * All edges of magnitude above t_high are always classified as edges. All edges
174  * below t_low are discarded. Edge values between t_low and t_high are classified
175  * as edges only if they are connected to edges having magnitude > t_high and are
176  * located in a direction perpendicular to that strong edge.
177  *
178  * \param[in] input_x Input point cloud passed by reference for the first derivative
179  * in the horizontal direction
180  * \param[in] input_y Input point cloud passed by reference for the first derivative
181  * in the vertical direction
182  * \param[out] output Output point cloud passed by reference
183  */
184  void
185  canny(const pcl::PointCloud<PointInT>& input_x,
186  const pcl::PointCloud<PointInT>& input_y,
188 
189  /** \brief This is a convenience function which performs edge detection based on
190  * the variable detector_kernel_type_
191  * \param[out] output
192  */
193  void
195 
196  /** \brief All edges of magnitude above t_high are always classified as edges.
197  * All edges below t_low are discarded.
198  * Edge values between t_low and t_high are classified as edges only if they are
199  * connected to edges having magnitude > t_high and are located in a direction
200  * perpendicular to that strong edge.
201  * \param[out] output Output point cloud passed by reference
202  */
203  void
205 
206  /** \brief Uses the Sobel kernel for edge detection.
207  * This function does NOT include a smoothing step.
208  * The image should be smoothed before using this function to reduce noise.
209  * \param[out] output Output point cloud passed by reference
210  */
211  void
213 
214  /** \brief Uses the Prewitt kernel for edge detection.
215  * This function does NOT include a smoothing step.
216  * The image should be smoothed before using this function to reduce noise.
217  * \param[out] output Output point cloud passed by reference
218  */
219  void
221 
222  /** \brief Uses the Roberts kernel for edge detection.
223  * This function does NOT include a smoothing step.
224  * The image should be smoothed before using this function to reduce noise.
225  * \param[out] output Output point cloud passed by reference
226  */
227  void
229 
230  /** \brief Uses the LoG kernel for edge detection.
231  * Zero crossings of the Laplacian operator applied on an image indicate edges.
232  * Gaussian kernel is used to smoothen the image prior to the Laplacian.
233  * This is because Laplacian uses the second order derivative of the image and hence,
234  * is very sensitive to noise. The implementation is not two-step but rather applies
235  * the LoG kernel directly.
236  *
237  * \param[in] kernel_sigma variance of the LoG kernel used.
238  * \param[in] kernel_size a LoG kernel of dimensions kernel_size x kernel_size is
239  * used.
240  * \param[out] output Output point cloud passed by reference.
241  */
242  void
243  detectEdgeLoG(const float kernel_sigma,
244  const float kernel_size,
246 
247  /** \brief Computes the image derivatives in X direction using the kernel
248  * kernel::derivativeYCentralKernel. This function does NOT include a smoothing step.
249  * The image should be smoothed before using this function to reduce noise.
250  * \param[out] output Output point cloud passed by reference
251  */
252  void
254 
255  /** \brief Computes the image derivatives in Y direction using the kernel
256  * kernel::derivativeYCentralKernel. This function does NOT include a smoothing step.
257  * The image should be smoothed before using this function to reduce noise.
258  * \param[out] output Output point cloud passed by reference
259  */
260  void
262 
263  /** \brief Computes the image derivatives in X direction using the kernel
264  * kernel::derivativeYForwardKernel. This function does NOT include a smoothing step.
265  * The image should be smoothed before using this function to reduce noise.
266  * \param[out] output Output point cloud passed by reference
267  */
268  void
270 
271  /** \brief Computes the image derivatives in Y direction using the kernel
272  * kernel::derivativeYForwardKernel. This function does NOT include a smoothing step.
273  * The image should be smoothed before using this function to reduce noise.
274  * \param[out] output Output point cloud passed by reference
275  */
276  void
278 
279  /** \brief Computes the image derivatives in X direction using the kernel
280  * kernel::derivativeXBackwardKernel. This function does NOT include a smoothing step.
281  * The image should be smoothed before using this function to reduce noise.
282  * \param output Output point cloud passed by reference
283  */
284  void
286 
287  /** \brief Computes the image derivatives in Y direction using the kernel
288  * kernel::derivativeYBackwardKernel. This function does NOT include a smoothing step.
289  * The image should be smoothed before using this function to reduce noise.
290  * \param[out] output Output point cloud passed by reference
291  */
292  void
294 
295  /** \brief Override function to implement the pcl::Filter interface */
296  void
298  {}
299 
300  /** \brief Set the input point cloud pointer
301  * \param[in] input pointer to input point cloud
302  */
303  void
304  setInputCloud(PointCloudInPtr input)
305  {
306  input_ = input;
307  }
308 
310 };
311 
312 } // namespace pcl
313 
314 #include <pcl/2d/impl/edge.hpp>
Definition: edge.h:49
void setHysteresisThresholdHigh(float threshold)
Definition: edge.h:155
void setOutputType(OUTPUT_TYPE output_type)
Set the output type.
Definition: edge.h:143
void computeDerivativeYForward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in Y direction using the kernel kernel::derivativeYForwardKernel.
void detectEdge(pcl::PointCloud< PointOutT > &output)
This is a convenience function which performs edge detection based on the variable detector_kernel_ty...
void applyFilter(pcl::PointCloud< PointOutT > &)
Override function to implement the pcl::Filter interface.
Definition: edge.h:297
void computeDerivativeYBackward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in Y direction using the kernel kernel::derivativeYBackwardKernel.
void detectEdgePrewitt(pcl::PointCloud< PointOutT > &output)
Uses the Prewitt kernel for edge detection.
Definition: edge.hpp:126
void computeDerivativeXForward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in X direction using the kernel kernel::derivativeYForwardKernel.
void detectEdgeLoG(const float kernel_sigma, const float kernel_size, pcl::PointCloud< PointOutT > &output)
Uses the LoG kernel for edge detection.
Definition: edge.hpp:450
Edge()
Definition: edge.h:128
void detectEdgeSobel(pcl::PointCloud< PointOutT > &output)
Uses the Sobel kernel for edge detection.
Definition: edge.hpp:48
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:376
OUTPUT_TYPE
Definition: edge.h:95
@ OUTPUT_MAGNITUDE_DIRECTION
Definition: edge.h:101
@ OUTPUT_X_Y
Definition: edge.h:98
@ OUTPUT_ALL
Definition: edge.h:102
@ OUTPUT_MAGNITUDE
Definition: edge.h:99
@ OUTPUT_X
Definition: edge.h:97
@ OUTPUT_DIRECTION
Definition: edge.h:100
@ OUTPUT_Y
Definition: edge.h:96
void sobelMagnitudeDirection(const pcl::PointCloud< PointInT > &input_x, const pcl::PointCloud< PointInT > &input_y, pcl::PointCloud< PointOutT > &output)
Definition: edge.hpp:85
void detectEdgeRoberts(pcl::PointCloud< PointOutT > &output)
Uses the Roberts kernel for edge detection.
Definition: edge.hpp:164
void computeDerivativeXBackward(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in X direction using the kernel kernel::derivativeXBackwardKernel.
void computeDerivativeXCentral(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in X direction using the kernel kernel::derivativeYCentralKernel.
void detectEdgeCanny(pcl::PointCloud< PointOutT > &output)
All edges of magnitude above t_high are always classified as edges.
Definition: edge.hpp:312
DETECTOR_KERNEL_TYPE
Definition: edge.h:105
@ DERIVATIVE_BACKWARD
Definition: edge.h:113
@ SOBEL
Definition: edge.h:107
@ PREWITT
Definition: edge.h:108
@ DERIVATIVE_FORWARD
Definition: edge.h:112
@ ROBERTS
Definition: edge.h:109
@ DERIVATIVE_CENTRAL
Definition: edge.h:111
@ LOG
Definition: edge.h:110
@ CANNY
Definition: edge.h:106
void computeDerivativeYCentral(pcl::PointCloud< PointOutT > &output)
Computes the image derivatives in Y direction using the kernel kernel::derivativeYCentralKernel.
void setHysteresisThresholdLow(float threshold)
Definition: edge.h:149
shared_ptr< const Edge< PointInT, PointOutT > > ConstPtr
Definition: edge.h:93
shared_ptr< Edge< PointInT, PointOutT > > Ptr
Definition: edge.h:92
void setInputCloud(PointCloudInPtr input)
Set the input point cloud pointer.
Definition: edge.h:304
shared_ptr< PointCloud< PointInT > > Ptr
Definition: point_cloud.h:413
#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.
Defines all the PCL and non-PCL macros used.