Point Cloud Library (PCL)  1.14.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_{false};
120  bool hysteresis_thresholding_{false};
121 
122  float hysteresis_threshold_low_{20.0f};
123  float hysteresis_threshold_high_{80.0f};
124  float non_max_suppression_radius_x_{3.0f};
125  float non_max_suppression_radius_y_{3.0f};
126 
127 public:
128  Edge() : output_type_(OUTPUT_X), detector_kernel_type_(SOBEL) {}
129 
130  /** \brief Set the output type.
131  * \param[in] output_type the output type
132  */
133  void
135  {
136  output_type_ = output_type;
137  }
138 
139  void
140  setHysteresisThresholdLow(float threshold)
141  {
142  hysteresis_threshold_low_ = threshold;
143  }
144 
145  void
146  setHysteresisThresholdHigh(float threshold)
147  {
148  hysteresis_threshold_high_ = threshold;
149  }
150 
151  /**
152  * \param[in] input_x
153  * \param[in] input_y
154  * \param[out] output
155  */
156  void
158  const pcl::PointCloud<PointInT>& input_y,
160 
161  /** Perform Canny edge detection with two separated input images for horizontal and
162  * vertical derivatives.
163  *
164  * All edges of magnitude above t_high are always classified as edges. All edges
165  * below t_low are discarded. Edge values between t_low and t_high are classified
166  * as edges only if they are connected to edges having magnitude > t_high and are
167  * located in a direction perpendicular to that strong edge.
168  *
169  * \param[in] input_x Input point cloud passed by reference for the first derivative
170  * in the horizontal direction
171  * \param[in] input_y Input point cloud passed by reference for the first derivative
172  * in the vertical direction
173  * \param[out] output Output point cloud passed by reference
174  */
175  void
176  canny(const pcl::PointCloud<PointInT>& input_x,
177  const pcl::PointCloud<PointInT>& input_y,
179 
180  /** \brief This is a convenience function which performs edge detection based on
181  * the variable detector_kernel_type_
182  * \param[out] output
183  */
184  void
186 
187  /** \brief All edges of magnitude above t_high are always classified as edges.
188  * All edges below t_low are discarded.
189  * Edge values between t_low and t_high are classified as edges only if they are
190  * connected to edges having magnitude > t_high and are located in a direction
191  * perpendicular to that strong edge.
192  * \param[out] output Output point cloud passed by reference
193  */
194  void
196 
197  /** \brief Uses the Sobel kernel for edge detection.
198  * This function does NOT include a smoothing step.
199  * The image should be smoothed before using this function to reduce noise.
200  * \param[out] output Output point cloud passed by reference
201  */
202  void
204 
205  /** \brief Uses the Prewitt 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 Roberts 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 LoG kernel for edge detection.
222  * Zero crossings of the Laplacian operator applied on an image indicate edges.
223  * Gaussian kernel is used to smoothen the image prior to the Laplacian.
224  * This is because Laplacian uses the second order derivative of the image and hence,
225  * is very sensitive to noise. The implementation is not two-step but rather applies
226  * the LoG kernel directly.
227  *
228  * \param[in] kernel_sigma variance of the LoG kernel used.
229  * \param[in] kernel_size a LoG kernel of dimensions kernel_size x kernel_size is
230  * used.
231  * \param[out] output Output point cloud passed by reference.
232  */
233  void
234  detectEdgeLoG(const float kernel_sigma,
235  const float kernel_size,
237 
238  /** \brief Computes the image derivatives in X direction using the kernel
239  * kernel::derivativeYCentralKernel. This function does NOT include a smoothing step.
240  * The image should be smoothed before using this function to reduce noise.
241  * \param[out] output Output point cloud passed by reference
242  */
243  void
245 
246  /** \brief Computes the image derivatives in Y 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 X direction using the kernel
255  * kernel::derivativeYForwardKernel. 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 Y 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 X direction using the kernel
271  * kernel::derivativeXBackwardKernel. This function does NOT include a smoothing step.
272  * The image should be smoothed before using this function to reduce noise.
273  * \param output Output point cloud passed by reference
274  */
275  void
277 
278  /** \brief Computes the image derivatives in Y direction using the kernel
279  * kernel::derivativeYBackwardKernel. This function does NOT include a smoothing step.
280  * The image should be smoothed before using this function to reduce noise.
281  * \param[out] output Output point cloud passed by reference
282  */
283  void
285 
286  /** \brief Override function to implement the pcl::Filter interface */
287  void
289  {}
290 
291  /** \brief Set the input point cloud pointer
292  * \param[in] input pointer to input point cloud
293  */
294  void
295  setInputCloud(PointCloudInPtr input)
296  {
297  input_ = input;
298  }
299 
301 };
302 
303 } // namespace pcl
304 
305 #include <pcl/2d/impl/edge.hpp>
Definition: edge.h:49
void setHysteresisThresholdHigh(float threshold)
Definition: edge.h:146
void setOutputType(OUTPUT_TYPE output_type)
Set the output type.
Definition: edge.h:134
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:288
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:140
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:295
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.