Ocean
LineDetectorHough.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_DETECTOR_LINE_DETECTOR_HOUGH_H
9 #define META_OCEAN_CV_DETECTOR_LINE_DETECTOR_HOUGH_H
10 
12 
13 #include "ocean/base/Frame.h"
14 #include "ocean/base/Singleton.h"
15 #include "ocean/base/Worker.h"
16 
17 #include "ocean/math/FiniteLine2.h"
18 #include "ocean/math/Line2.h"
19 #include "ocean/math/Vector2.h"
20 
21 #include <algorithm>
22 #include <tuple>
23 
24 namespace Ocean
25 {
26 
27 // Forward declaration for test library.
28 namespace Test { namespace TestCV { namespace TestDetector { class TestLineDetectorHough; } } }
29 
30 namespace CV
31 {
32 
33 namespace Detector
34 {
35 
36 /**
37  * This class implements a line detector mainly based on the Hough transformation.
38  * Beware: The origin of the resulting infinite line's coordinate system is located in the center of the frame.
39  * @see InfiniteLine::cornerAlignedLine().
40  * @ingroup cvdetector
41  */
42 class OCEAN_CV_DETECTOR_EXPORT LineDetectorHough
43 {
45 
46  public:
47 
48  /**
49  * This class defines an infinite 2D line.
50  * Beware: The origin of the line's coordinate system is located in the center of the frame.
51  * @see cornerAlignedLine().
52  */
53  class OCEAN_CV_DETECTOR_EXPORT InfiniteLine : public Line2
54  {
55  public:
56 
57  /**
58  * Creates an empty line object.
59  */
60  InfiniteLine() = default;
61 
62  /**
63  * Creates a new line object.
64  * @param normal Line normal, must be valid
65  * @param angle The angle of the line (matching with the normal) in radian, with range [-PI, PI]
66  * @param distance Line distance between to the origin (the center of the frame - not the corner of the frame), with range (-infinity, infinity)
67  * @param strength The strength value, with range (0, infinity)
68  */
69  inline InfiniteLine(const Vector2& normal, const Scalar angle, const Scalar distance, const Scalar strength);
70 
71  /**
72  * Converts this line (with origin defined in the center of the frame) to a line with origin defined in the upper left (or lower left) corner of the frame (depending on the pixel origin of the original frame).
73  * @param width The width of the frame which has been used to detect the line in pixel, with range [3, infinity)
74  * @param height The height of the frame which has been used to detect the line in pixel, with range [3, infinity)
75  * @return The line defined in the coordinate of the frame, with origin at one of the frame's corners
76  * @see cornerAlignedLines().
77  */
78  inline Line2 cornerAlignedLine(const unsigned int width, const unsigned int height) const;
79 
80  /**
81  * Returns the normal of this line.
82  * @return Line normal
83  */
84  inline const Vector2& normal() const;
85 
86  /**
87  * Returns the angle of this line.
88  * @return The line's angle in radian with range [-PI, PI]
89  */
90  inline Scalar angle() const;
91 
92  /**
93  * Returns the distance of this line.
94  * @return The lines's distance to the origin (the center of the frame - not the corner of the frame), with range (-infinity, infinity)
95  * @see cornerAlignedLine().
96  */
97  inline Scalar distance() const;
98 
99  /**
100  * Returns the strength of this line.
101  * @return Line's strength, with range (0, infinity)
102  */
103  inline Scalar strength() const;
104 
105  /**
106  * Returns whether two lines are parallel up to a given angle precision.
107  * @param line The second line to check
108  * @param cosAngle Cosine value of the maximal angle to count as parallel, with range [0, 1]
109  * @return True, if so
110  */
111  bool isParallel(const InfiniteLine& line, const Scalar cosAngle) const;
112 
113  /**
114  * Returns whether two lines are similar up to a given distance and angle precision.
115  * @param line Second line to check
116  * @param distance Maximal distance to count as similar
117  * @param cosAngle Cosine value of the maximal angle to count as similar
118  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
119  * @return True, if so
120  */
121  bool isSimilar(const InfiniteLine& line, const Scalar distance, const Scalar cosAngle, const bool halfOrientationPrecision) const;
122 
123  /**
124  * Returns whether this line object has a lower strength value than the second one.
125  * @param second The second line object
126  * @return True, if so
127  */
128  inline bool operator<(const InfiniteLine& second) const;
129 
130  /**
131  * Converts lines (with origin defined in the center of the frame) to a lines with origin defined in the upper left (or lower left) corner of the frame (depending on the pixel origin of the original frame).
132  * @param lines The lines to be converted, may be nullptr if size is 0
133  * @param size The number of lines to be converted, with range [0, infinity)
134  * @param width The width of the frame which has been used to detect the line in pixel, with range [3, infinity)
135  * @param height The height of the frame which has been used to detect the line in pixel, with range [3, infinity)
136  * @param strengths Optional resulting strength values of the converted lines, one strength value for each line
137  * @return The lines defined in the coordinate of the frame, with origin at one of the frame's corners
138  * @see cornerAlignedLine().
139  */
140  static inline Lines2 cornerAlignedLines(const InfiniteLine* lines, const size_t size, const unsigned int width, const unsigned int height, Scalar* strengths = nullptr);
141 
142  protected:
143 
144  /// Line normal.
145  Vector2 normal_ = Vector2(0, 0);
146 
147  /// Line angle.
148  Scalar angle_ = Scalar(0);
149 
150  /// Line distance.
151  Scalar distance_ = Scalar(0);
152 
153  /// Line strength.
154  Scalar strength_ = Scalar(0);
155  };
156 
157  /**
158  * Definition of a vector holding infinite lines.
159  */
160  typedef std::vector<InfiniteLine> InfiniteLines;
161 
162  /**
163  * Definition of a vector holding infinite lines.
164  */
165  typedef std::vector<InfiniteLines> InfiniteLineGroups;
166 
167  protected:
168 
169  /**
170  * Vote accumulator array.
171  */
172  class OCEAN_CV_DETECTOR_EXPORT Accumulator
173  {
175 
176  public:
177 
178  /**
179  * This class holds angle lookup data.
180  */
182  {
183  public:
184 
185  /**
186  * Creates an empty lookup object.
187  */
188  AngleLookupData() = default;
189 
190  /**
191  * Creates a new lookup object.
192  * @param angleBin The angle bin to be stored
193  * @param weight The weight to be stored
194  */
195  inline AngleLookupData(const unsigned int angleBin, const unsigned int weight);
196 
197  public:
198 
199  /// Bin of the associated angle.
200  unsigned int angleBin_ = (unsigned int)(-1);
201 
202  /// Weight value.
203  unsigned int weight_ = 0u;
204  };
205 
206  /**
207  * This class holds distance lookup data.
208  */
210  {
211  public:
212 
213  /**
214  * Creates an empty lookup object.
215  */
216  DirectionLookupData() = default;
217 
218  /**
219  * Creates a new lookup object.
220  * @param dx Direction for the x-axis
221  * @param dy Direction for the y-axis
222  */
223  inline DirectionLookupData(const int dx, const int dy);
224 
225  public:
226 
227  /// Direction of the normal for the x axis.
228  int directionX_ = 0;
229 
230  /// Direction of the normal for the y axis.
231  int directionY_ = 0;
232  };
233 
234  /**
235  * This class defines a data lookup manager defined as singleton.
236  */
237  class OCEAN_CV_DETECTOR_EXPORT LookupManager : public Singleton<LookupManager>
238  {
239  friend class Singleton<LookupManager>;
240  friend class Accumulator;
241 
242  private:
243 
244  /**
245  * Definition of a pair combining an unsigned integer with a boolean state.
246  */
247  typedef std::pair<unsigned int, bool> MapPair;
248 
249  /**
250  * Definition of a tuple combining angleBins, distanceBins and halfOrientationPrecision.
251  */
252  typedef std::tuple<unsigned int, unsigned int, bool> MapTriple;
253 
254  /**
255  * Definition of a map mapping precision values to angle lookup data.
256  */
257  typedef std::map<MapPair, AngleLookupData*> AngleLookupMap;
258 
259  /**
260  * Definition of a map mapping precision values to direction lookup data.
261  */
262  typedef std::map<MapTriple, DirectionLookupData*> DirectionLookupMap;
263 
264  public:
265 
266  /**
267  * Returns the angle lookup data for 8 bit horizontal and vertical response values.
268  * The value request is done by an 16 bit index composed of the horizontal and vertical response.
269  * @param angleBins Number of angle bins to return the lookup data for
270  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
271  * @return Array holding the lookup data
272  */
273  const AngleLookupData* angleLookupData8BitResponse16BitRequest(const unsigned int angleBins, const bool halfOrientationPrecision);
274 
275  /**
276  * Returns the angle lookup data for 8 bit diagonal (45 and 135 degree) response values.
277  * The value request is done by an 16 bit index composed of the horizontal and vertical response.
278  * @param angleBins Number of angle bins to return the lookup data for
279  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
280  * @return Array holding the lookup data
281  */
282  const AngleLookupData* angleLookupDataDiagonal8BitResponse16BitRequest(const unsigned int angleBins, const bool halfOrientationPrecision);
283 
284  /**
285  * Returns the direction lookup data for an angle request.
286  * The size of the entire lookup buffer depends on the angle precision (on the number of used angle bins).
287  * @param angleBins Number of angle bins to return the lookup data for
288  * @param distanceBins Number of distance bins to return the lookup data for
289  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
290  * @return Array holding the lookup data
291  */
292  const DirectionLookupData* directionLookupData(const unsigned int angleBins, const unsigned int distanceBins, const bool halfOrientationPrecision);
293 
294  private:
295 
296  /**
297  * Destructs a manager.
298  */
300 
301  private:
302 
303  /// Lookup map for angles, horizontal and vertical.
305 
306  /// Lookup map for angles, diagonal.
308 
309  /// Lookup map for directions.
311 
312  /// The manager's look.
314  };
315 
316  public:
317 
318  /**
319  * Creates a new vote element by the given precisions for distance and angle.
320  * The specified number of additional border bins is internally multiplied by two to cover additional top and bottom bins.
321  * @param width The width of the original image in pixel, with range [3, infinity)
322  * @param height The height of the original image in pixel, with range [3, infinity)
323  * @param distanceBins Number of distance bins used for line extraction, must be odd [-maxDistance | 0 | +maxDistance]
324  * @param angleBins Number of difference angle values can be considered, must be even (-90 deg, +90 deg]
325  * @param mirroredAngleBins Number of additional angle bins (at the top and bottom of the core accumulator) to simplify border handling, with range [0, angleBins / 2)
326  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
327  */
328  Accumulator(const unsigned int width, const unsigned int height, const unsigned int distanceBins, const unsigned int angleBins, const unsigned int mirroredAngleBins, const bool halfOrientationPrecision);
329 
330  /**
331  * Adds a new horizontal and vertical edge filter response to accumulate the corresponding vote.
332  * @param x Horizontal filter position, with range [0, width())
333  * @param y Vertical filter position, with range [0, height())
334  * @param responses Two responses values (first horizontal, second vertical in address space) to perform a lookup for
335  * @param angleNeigbors Number of neighbors (in each angle direction - so it is more a less a radius) additionally receiving a less weighted vote, with range [0, angleBins)
336  */
337  void accumulate(const unsigned int x, const unsigned int y, const int8_t* responses, const unsigned int angleNeigbors = 3u);
338 
339  /**
340  * Adds a new diagonal (45 degree and 135 degree) filter edge filter response to accumulate the corresponding vote.
341  * @param x Horizontal filter position, with range [0, width())
342  * @param y Vertical filter position, with range [0, height())
343  * @param responsesDiagonal Two responses values (first 45, second 135 in address space) to perform a lookup for
344  * @param angleNeigbors Number of neighbors (in each angle direction - so it is more a less a radius) additionally receiving a less weighted vote, with range [0, angleBins)
345  */
346  void accumulateDiagonal(const unsigned int x, const unsigned int y, const int8_t* responsesDiagonal, const unsigned int angleNeigbors = 3u);
347 
348  /**
349  * Clears the accumulation buffer.
350  */
351  void clear();
352 
353  /**
354  * Returns the width of the original image in pixel.
355  * @return Original image width, with range [3, infinity)
356  */
357  inline unsigned int width() const;
358 
359  /**
360  * Returns the height of the original image in pixel.
361  * @return Original image height, with range [3, infinity)
362  */
363  inline unsigned int height() const;
364 
365  /**
366  * Returns the distance precision of this accumulator.
367  * @return Number of bins used to represent all distance values
368  */
369  inline unsigned int distanceBins() const;
370 
371  /**
372  * Returns the number of bins this accumulator stores for angle votes (including the additional bins for border operations).
373  * @return Number of bins used to represent all angle values
374  */
375  inline unsigned int angleBins() const;
376 
377  /**
378  * Returns the angle precision of this accumulator.
379  * @return Number of bins used to represent all angle values
380  */
381  inline unsigned int angleBinsCore() const;
382 
383  /**
384  * Returns the additional angle bins of this accumulator.
385  * @return Number of additional angle bins
386  */
387  inline unsigned int mirroredAngleBins() const;
388 
389  /**
390  * Returns the vote buffer stored for this accumulator.
391  * @return Vote buffer
392  */
393  inline const uint32_t* votes() const;
394 
395  /**
396  * Creates the additional mirrored angle bins at the top and bottom of the accumulator frame.
397  * These additional rows simplify the border operations.
398  */
400 
401  /**
402  * Detects peaks inside the accumulator votes.
403  * A vote is accepted as candidate (with following a non-maximum-suppression check) if the following holds: vote >= voteThreshold.
404  * @param lines Resulting lines
405  * @param voteThreshold The threshold of a vote so that a vote is accepted as candidate, with range [1, infinity)
406  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
407  * @param worker Optional worker object to distribute the computation
408  * @param smoothAccumulator True, to apply a smoothing filter (Gaussian) before peaks are detected
409  */
410  void detectPeaks(InfiniteLines& lines, const unsigned int voteThreshold, const bool determineExactPeakMaximum, Worker* worker = nullptr, const bool smoothAccumulator = false);
411 
412  /**
413  * Detects peaks inside a subset of the accumulator votes using a surrounding window to determine the threshold for each pixel individually.
414  * A vote is accepted as candidate (with following a non-maximum-suppression check) if the following holds: vote >= adaptiveVoteThresholdFactor * averagedNeighborVotes.
415  * @param lines Resulting lines
416  * @param adaptiveVoteThresholdFactor The minimal factor between the actual vote and the averaged votes inside the surrounding window area so that a vote is accepted as candidate, with range (0, infinity)
417  * @param windowHalf Half of the size of the window for the adaptive threshold in pixel (window size = 2 * windowHalf + 1), with range [1, infinity)
418  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
419  * @param worker Optional worker object to distribute the computation
420  * @param smoothAccumulator True, to apply a smoothing filter (Gaussian) before peaks are detected
421  */
422  void detectAdaptivePeaks(InfiniteLines& lines, const Scalar adaptiveVoteThresholdFactor, const unsigned int windowHalf, const bool determineExactPeakMaximum, Worker* worker = nullptr, const bool smoothAccumulator = false);
423 
424  /**
425  * Joins two accumulator objects.
426  * The result will be stored in the first accumulator.
427  * @param accumulators Two accumulators to join, must be valid
428  * @param worker Optional worker object to distribute the computation
429  */
430  static void joinTwo(Accumulator* accumulators, Worker* worker = nullptr);
431 
432  /**
433  * Joins four accumulator objects.
434  * The result will be stored in the first accumulator.
435  * @param accumulators Four accumulators to join, must be valid
436  * @param worker Optional worker object to distribute the computation
437  */
438  static void joinFour(Accumulator* accumulators, Worker* worker = nullptr);
439 
440  /**
441  * Joins an arbitrary number of accumulator objects.
442  * The result will be stored in the first accumulator.
443  * @param accumulators the accumulators to join, must be valid
444  * @param number The number of accumulators to join, with range [1, infinity)
445  * @param worker Optional worker object to distribute the computation
446  */
447  static void join(Accumulator* accumulators, const unsigned int number, Worker* worker = nullptr);
448 
449  /**
450  * Returns whether this vote accumulator is valid.
451  * @return True, if so
452  */
453  explicit inline operator bool() const;
454 
455  protected:
456 
457  /**
458  * Detects peaks inside a subset of the accumulator votes.
459  * A vote is accepted as candidate (with following a non-maximum-suppression check) if the following holds: vote >= voteThreshold.
460  * @param voteThreshold The threshold of a vote so that a vote is accepted as candidate, with range [1, infinity)
461  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
462  * @param lock Optional lock if this function is executed distributed within several threads
463  * @param lines The resulting lines
464  * @param firstAngleBin First angle bin to be checked, with range [0, angleBinsCore())
465  * @param numberAngleBins Number of angle bins to be checked, with range [1, angleBinsCore()]
466  */
467  void detectPeaksSubset(const unsigned int voteThreshold, const bool determineExactPeakMaximum, Lock* lock, InfiniteLines* lines, const unsigned int firstAngleBin, const unsigned int numberAngleBins);
468 
469  /**
470  * Detects peaks inside a subset of the accumulator votes using a surrounding window to determine the threshold for each pixel individually.
471  * A vote is accepted as candidate (with following a non-maximum-suppression check) if the following holds: vote >= adaptiveVoteThresholdFactor * averagedNeighborVotes.
472  * @param borderedIntegralAccumulator Buffer of the bordered integral accumulator, must be valid
473  * @param adaptiveVoteThresholdFactor The minimal factor between the actual vote and the averaged votes inside the surrounding window area so that a vote is accepted as candidate, with range (0, infinity)
474  * @param windowHalf Half of the size of the window for the adaptive threshold in pixel (window size = 2 * windowHalf + 1), with range [1, infinity)
475  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
476  * @param lock Optional lock if this function is executed distributed within several threads
477  * @param lines The resulting lines
478  * @param firstAngleBin First angle bin to be checked, with range [0, angleBinsCore())
479  * @param numberAngleBins Number of angle bins to be checked, with range [1, angleBinsCore()]
480  */
481  void detectAdaptivePeaksSubset(const uint32_t* borderedIntegralAccumulator, const Scalar adaptiveVoteThresholdFactor, const unsigned int windowHalf, const bool determineExactPeakMaximum, Lock* lock, InfiniteLines* lines, const unsigned int firstAngleBin, const unsigned int numberAngleBins);
482 
483  /**
484  * Joins a subset of two accumulator objects.
485  * The result will be stored in the first accumulator.
486  * @param accumulators Two accumulators to join
487  * @param firstAngleBin First angle bin to be joined
488  * @param numberAngleBins Number of angle bins to be joined
489  */
490  static void joinTwo(Accumulator* accumulators, const unsigned int firstAngleBin, const unsigned int numberAngleBins);
491 
492  /**
493  * Joins a subset of four accumulator objects.
494  * The result will be stored in the first accumulator.
495  * @param accumulators Four accumulators to join, must be valid
496  * @param firstAngleBin First angle bin to be joined
497  * @param numberAngleBins Number of angle bins to be joined
498  */
499  static void joinFour(Accumulator* accumulators, const unsigned int firstAngleBin, const unsigned int numberAngleBins);
500 
501  /**
502  * Joins a subset of an arbitrary number of accumulator objects.
503  * The result will be stored in the first accumulator.
504  * @param accumulators The accumulators to join, must be valid
505  * @param number The number of accumulators to join, with range [1, infinity)
506  * @param firstAngleBin First angle bin to be joined
507  * @param numberAngleBins Number of angle bins to be joined
508  */
509  static void join(Accumulator* accumulators, const unsigned int number, const unsigned int firstAngleBin, const unsigned int numberAngleBins);
510 
511  protected:
512 
513  /// Array holding the individual votes.
515 
516  /// Maximal line distance in pixel.
517  int accumulatorMaximalDistance_ = 0;
518 
519  /// Half distance bins.
520  int accumulatorDistanceBinsHalf_ = 0;
521 
522  /// Additional angle bins simplifying border operations.
523  unsigned int accumulatorMirroredAngleBins_ = 0u;
524 
525  /// Width of the original image in pixel.
526  const unsigned int accumulatorImageWidth_ = 0u;
527 
528  /// Height of the original image in pixel.
529  const unsigned int accumulatorImageHeight_ = 0u;
530 
531  /// Half width of the original image in pixel.
532  const unsigned int accumulatorImageWidthHalf_ = 0u;
533 
534  /// Half height of the original image in pixel.
535  const unsigned int accumulatorImageHeightHalf_ = 0u;
536 
537  /// True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
538  bool accumulatorHalfOrientationPrecision_ = false;
539 
540  /// Lookup table for angle data, horizontal and vertical.
541  const AngleLookupData* angleLookupTable_ = nullptr;
542 
543  /// Lookup table for angle data, diagonal.
544  const AngleLookupData* angleLookupTableDiagonal_ = nullptr;
545 
546  /// Lookup table for direction data.
547  const DirectionLookupData* directionLookupTable_ = nullptr;
548 
549 #ifdef OCEAN_DEBUG
550  /// State to check whether the mirrored angle bins has been created before line detection
551  bool debugMirroredAngleBinsCreated_ = false;
552 #endif
553  };
554 
555  /**
556  * Definition of a vector holding index sets.
557  */
558  typedef std::vector<IndexSet32> IndexSetVector;
559 
560  public:
561 
562  /**
563  * Definition of different edge detector filters.
564  */
565  enum FilterType : uint32_t
566  {
567  // Invalid filter type.
568  FT_INVALID = 0u,
569  // Scharr filter.
571  // Sobel filter.
572  FT_SOBEL
573  };
574 
575  /**
576  * Definition of usage of different filter responses.
577  */
578  enum FilterResponse : uint32_t
579  {
580  // Invalid filter response.
581  FR_INVALID = 0u,
582  // Horizontal and vertical filter response (0 and 90 degrees).
583  FR_HORIZONTAL_VERTICAL = 1u,
584  // Diagonal filter response (45 and 135 degrees).
585  FR_DIAGONAL = 2u,
586  /// Horizontal, vertical (0 and 90 degrees) and diagonal (45 and 135 degrees).
587  FR_HORIZONTAL_VERTICAL_DIAGONAL = FR_HORIZONTAL_VERTICAL | FR_DIAGONAL
588  };
589 
590  public:
591 
592  /**
593  * Detects lines inside a given frame using a threshold ensuring that detected lines have a specific strength.
594  * Lines are detected by searching for all votes exceeding the given threshold.<br>
595  * All data channels of the frame will be used during the determination.
596  * @param frame The frame in which the lines will be detected, can be any zipped pixel format, all data channels will be used during the line detection, must be valid
597  * @param filterType Filter to be used for edge detection
598  * @param filterResponse Filter responses to be used
599  * @param infiniteLines Resulting infinite lines
600  * @param finiteLines Optional resulting finite lines, if specified
601  * @param optimizeLines True, to apply a fine adjustment of the lines after detection
602  * @param accumulatorThreshold Minimal threshold that an accumulated vote counts as line
603  * @param voteThreshold Minimal threshold a vote must exceed to forward a vote to the accumulator, with range [1, infinity)
604  * @param angleNeigbors Number of neighbors in angle direction receiving an less-weighted vote, with range [0, 11
605  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
606  * @param worker Optional worker object to distribute the computational load
607  * @param anglePrecision Number of detectable line angles, the higher the more precise the angle of the line, with range [1, 36000]
608  * @param distancePrecision Number of detectable distance values, the higher the more precise the distance of the line, use -1 to receive a distance precision of 1 pixel, with range (0, infinity) | [-1]
609  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
610  * @param similarDistance Maximal pixel distance for two lines to count as similar for filtering, 0 for non filtering
611  * @param similarAngle Maximal angle in radian for two lines to count as similar for filtering, 0 for non filtering
612  * @return True, if succeeded
613  */
614  static inline bool detectLines(const Frame& frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines& infiniteLines, FiniteLines2* finiteLines = nullptr, const bool optimizeLines = true, const unsigned int accumulatorThreshold = 100u, const unsigned int voteThreshold = 16u, const unsigned int angleNeigbors = 2u, const bool determineExactPeakMaximum = true, Worker* worker = nullptr, const unsigned int anglePrecision = 360u, const unsigned int distancePrecision = (unsigned int)(-1), const bool halfOrientationPrecision = true, const Scalar similarDistance = Scalar(10), const Scalar similarAngle = Numeric::deg2rad(5));
615 
616  /**
617  * Detects lines inside a given frame using an adaptive threshold in combination with a surrounding window.
618  * Lines are detected by searching for all votes exceeding a threshold relative to the surrounding vote area.<br>
619  * All data channels of the frame will be used during the determination.
620  * @param frame The frame in which the lines will be detected, can be any zipped pixel format, all data channels will be used during the line detection, must be valid
621  * @param filterType Filter to be used for edge detection
622  * @param filterResponse Filter responses to be used
623  * @param infiniteLines Resulting infinite lines
624  * @param finiteLines Optional resulting finite lines, if specified
625  * @param optimizeLines True, to apply a fine adjustment of the lines after detection
626  * @param adaptiveVoteThresholdFactor The minimal factor between the actual vote and the averaged votes inside the surrounding window area so that a vote is accepted as candidate, with range (0, infinity)
627  * @param thresholdWindow Size of the surrounding vote area considering for line detection, with range [5, infinity), must be odd
628  * @param voteThreshold Minimal threshold a vote must exceed to forward a vote to the accumulator
629  * @param angleNeigbors Number of neighbors in angle direction receiving an less-weighted vote
630  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
631  * @param worker Optional worker object to distribute the computational load
632  * @param anglePrecision Number of detectable line angles, the higher the more precise the angle of the line, with range [1, 36000]
633  * @param distancePrecision Number of detectable distance values, the higher the more precise the distance of the line, use -1 to receive a distance precision of 1 pixel, with range (0, infinity) | [-1]
634  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
635  * @param similarDistance Maximal pixel distance for two lines to count as similar for filtering, 0 for non filtering
636  * @param similarAngle Maximal angle in radian for two lines to count as similar for filtering, 0 for non filtering
637  * @return True, if succeeded
638  */
639  static inline bool detectLinesWithAdaptiveThreshold(const Frame& frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines& infiniteLines, FiniteLines2* finiteLines = nullptr, const bool optimizeLines = true, const Scalar adaptiveVoteThresholdFactor = Scalar(8), const unsigned int thresholdWindow = 61u, const unsigned int voteThreshold = 16, const unsigned int angleNeigbors = 2u, const bool determineExactPeakMaximum = true, Worker* worker = nullptr, const unsigned int anglePrecision = 360u, const unsigned int distancePrecision = (unsigned int)(-1), const bool halfOrientationPrecision = true, const Scalar similarDistance = Scalar(10), const Scalar similarAngle = Numeric::deg2rad(5));
640 
641  /**
642  * Filters a set of similar detected lines so that the strongest and unique lines are returned only.
643  * @param lines Detected lines that have to be filtered
644  * @param minDistance Minimal distance between two lines so that they do not count as identical
645  * @param minAngle Minimal angle between two lines so that they do not count as identical
646  * @param filteredLines Resulting subset of the original lines, filtered by the minimal distance and angle
647  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
648  */
649  static void filterLines(const InfiniteLines& lines, const Scalar minDistance, const Scalar minAngle, InfiniteLines& filteredLines, const bool halfOrientationPrecision);
650 
651  /**
652  * Separates given lines in sets of almost parallel lines.
653  * @param lines The given lines to be separated
654  * @param maxAngle The maximal angle between two lines so that they count as parallel, with range [0, PI/2]
655  * @param parallelGroups The resulting groups of lines which are parallel
656  * @param minimalSetSize The minimal size of a group of parallel lines, with range [0, infinity)
657  * @param noDuplicates True, to avoid duplicates in the resulting groups
658  */
659  static void parallelLines(const InfiniteLines& lines, const Scalar maxAngle, InfiniteLineGroups& parallelGroups, const unsigned int minimalSetSize = 0u, const bool noDuplicates = true);
660 
661  /**
662  * Filters the biggest set of parallel lines from a given set of lines.
663  * Further the resulting lines are sorted by their distance parameter.<br>
664  * @param lines Set of lines to be filtered for one set of parallel lines.
665  * @param minAngle Minimal angle between two successive lines in radian
666  * @param parallels Resulting parallel lines
667  * @return True, if succeeded
668  */
669  static bool parallelLines(const InfiniteLines& lines, const Scalar minAngle, InfiniteLines& parallels);
670 
671  /**
672  * Sorts lines according to their distance values.
673  * @param lines The lines to be sorted
674  */
675  static inline void sortLinesAccordingDistance(InfiniteLines& lines);
676 
677  /**
678  * Sorts groups of elements (of e.g., infinite lines) according to their number of elements in descending order.
679  * @param groups The groups to be ordered
680  * @tparam T The data type of the elements
681  */
682  template <typename T>
683  static inline void sortGroupsDescendingAccordingElements(std::vector<std::vector<T>>& groups);
684 
685  private:
686 
687  /**
688  * Internal line detection function to detects lines inside an 8 bit gray scale image.
689  * Beware: The origin of the pixel data is expected to be in the upper left corner.
690  * @param frame The frame in which the lines will be detected, can be any zipped pixel format, all data channels will be used during the line detection, must be valid
691  * @param filterType Filter to be used for edge detection
692  * @param filterResponse Filter responses to be used
693  * @param infiniteLines Resulting infinite lines
694  * @param finiteLines Optional resulting finite lines, if defined
695  * @param optimizeLines True, to apply a fine adjustment of the lines after detection
696  * @param thresholdParameter Depending on the defined border this threshold is interpreted as a unique vote threshold or an adaptive threshold ratio
697  * @param adaptiveThresholdWindowHalf The half size of the surrounding window for the adaptive threshold in pixel, 0 to avoid the adaptive thresholding, with range [0, infinity)
698  * @param voteThreshold Minimal threshold a vote must exceed to forward a vote to the accumulator
699  * @param angleNeigbors Number of neighbors in angle direction receiving an less-weighted vote
700  * @param determineExactPeakMaximum True, to invoke the determination of the exact peak maximum by interpolation
701  * @param worker Optional worker object to distribute the computational load
702  * @param anglePrecision Number of detectable line angles, the higher the more precise the angle of the line, with range [1, 36000]
703  * @param distancePrecision Number of detectable distance values, the higher the more precise the distance of the line, use -1 to receive a distance precision of 1 pixel, with range (0, infinity) | [-1]
704  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
705  * @param similarDistance Maximal pixel distance for two lines to count as similar for filtering, 0 for non filtering
706  * @param similarAngle Maximal angle in radian for two lines to count as similar for filtering, 0 for non filtering
707  * @return True, if succeeded
708  */
709  static bool internalDetectLines(const Frame& frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines& infiniteLines, FiniteLines2* finiteLines, const bool optimizeLines, const Scalar thresholdParameter, const unsigned int adaptiveThresholdWindowHalf, const unsigned int voteThreshold, const unsigned int angleNeigbors, const bool determineExactPeakMaximum, Worker* worker, const unsigned int anglePrecision, const unsigned int distancePrecision, const bool halfOrientationPrecision, const Scalar similarDistance, const Scalar similarAngle);
710 
711  /**
712  * Creates line votes for horizontal and vertical (0 and 90 degree) filter responses inside a given accumulator object.
713  * @param response Buffer holding the filter responses for the original frame
714  * @param accumulator The accumulator object receiving the votes
715  * @param angleNeigbors Number of neighbors in angle direction receiving an less-weighted vote
716  * @param voteThreshold Threshold a filter response must exceed to count as vote, with range [1, 127]
717  * @param firstRow First row of the responses buffer to be handled
718  * @param numberRows Number of rows of the response buffer to be handled
719  */
720  static void createVotesHorizontalVerticalSubset(const int8_t* response, Accumulator* accumulator, const unsigned int angleNeigbors, const unsigned int voteThreshold, const unsigned int firstRow, const unsigned int numberRows);
721 
722  /**
723  * Creates line votes for diagonal (45 and 135 degree) filter responses inside a given accumulator object.
724  * @param response Buffer holding the filter responses for the original frame
725  * @param accumulator The accumulator object receiving the votes
726  * @param angleNeigbors Number of neighbors in angle direction receiving an less-weighted vote
727  * @param voteThreshold Threshold a filter response must exceed to count as vote, with range [1, 127]
728  * @param firstRow First row of the responses buffer to be handled
729  * @param numberRows Number of rows of the response buffer to be handled
730  */
731  static void createVotesDiagonalSubset(const int8_t* response, Accumulator* accumulator, const unsigned int angleNeigbors, const unsigned int voteThreshold, const unsigned int firstRow, const unsigned int numberRows);
732 
733  /**
734  * Creates line votes for horizontal, vertical and diagonal (0, 90 and 45, 135 degree) filter responses inside a given accumulator object.
735  * @param response Buffer holding the filter responses for the original frame
736  * @param accumulator The accumulator object receiving the votes
737  * @param angleNeigbors Number of neighbors in angle direction receiving an less-weighted vote
738  * @param voteThreshold Threshold a filter response must exceed to count as vote, with range [1, 127]
739  * @param firstRow First row of the responses buffer to be handled
740  * @param numberRows Number of rows of the response buffer to be handled
741  */
742  static void createVotesHorizontalVerticalDiagonalSubset(const int8_t* response, Accumulator* accumulator, const unsigned int angleNeigbors, const unsigned int voteThreshold, const unsigned int firstRow, const unsigned int numberRows);
743 
744  /**
745  * Detects finite lines from a subset of already detected infinite lines additionally using the frame filter responses.
746  * @param infiniteLines Infinite lines to detect finite lines from
747  * @param response Buffer holding the filter responses for the original frame
748  * @param width The width of the original frame in pixel
749  * @param height The height of the original frame in pixel
750  * @param filterResponse Filter responses type which has been used to create the filter response
751  * @param angleBins Number of angle bins
752  * @param horizontalAngleLookup Horizontal angle lookup table
753  * @param diagonalAngleLookup Diagonal angle lookup table
754  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
755  * @param lock Optional lock if this function is executed distributed within several threads
756  * @param finiteLines Resulting finite lines
757  * @param firstLine First infinite line to be handled, with range [0, infiniteLines->size())
758  * @param numberLines Number of infinite lines to be handled, with range [1, infiniteLines->size() - firstLine]
759  */
760  static void detectFiniteLinesSubset(const InfiniteLines* infiniteLines, const int8_t* response, const unsigned int width, const unsigned int height, const FilterResponse filterResponse, const unsigned int angleBins, const Accumulator::AngleLookupData* horizontalAngleLookup, const Accumulator::AngleLookupData* diagonalAngleLookup, const bool halfOrientationPrecision, Lock* lock, FiniteLines2* finiteLines, const unsigned int firstLine, const unsigned int numberLines);
761 
762  /**
763  * Detects finite lines from one infinite line additionally using the frame filter responses.
764  * @param infiniteLine Infinite line to detect finite lines from
765  * @param response Buffer holding the filter responses for the original frame
766  * @param width The width of the original frame in pixel
767  * @param height The height of the original frame in pixel
768  * @param filterResponse Filter responses type which has been used to create the filter response
769  * @param angleBins Number of angle bins
770  * @param horizontalAngleLookup Horizontal angle lookup table
771  * @param diagonalAngleLookup Diagonal angle lookup table
772  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
773  * @param finiteLines Resulting finite lines
774  */
775  static void detectFiniteLines(const InfiniteLine& infiniteLine, const int8_t* response, const unsigned int width, const unsigned int height, const FilterResponse filterResponse, const unsigned int angleBins, const Accumulator::AngleLookupData* horizontalAngleLookup, const Accumulator::AngleLookupData* diagonalAngleLookup, const bool halfOrientationPrecision, FiniteLines2& finiteLines);
776 
777  /**
778  * Refines lines by adjusting the line with the filter responses.
779  * @param infiniteLines Lines to be adjusted
780  * @param number The number of given lines
781  * @param response Buffer holding the filter responses for the original frame
782  * @param width The width of the original frame in pixel
783  * @param height The height of the original frame in pixel
784  * @param filterResponse Filter responses type which has been used to create the filter response
785  * @param radius Search radius along the original line, in pixel
786  * @param accumulator Response accumulator that has been applied to fine the lines
787  * @param halfOrientationPrecision True, to handle flipped lines (e.g. with angle 45 deg and -135) as identical lines
788  * @param optimizedLines Resulting optimized lines
789  * @param firstLine First line to be optimized
790  * @param numberLines Number of lines to be optimized
791  */
792  static void optimizeInfiniteLinesSubset(const InfiniteLine* infiniteLines, const size_t number, const int8_t* response, const unsigned int width, const unsigned int height, const FilterResponse filterResponse, const unsigned int radius, const Accumulator* accumulator, const bool halfOrientationPrecision, InfiniteLine* optimizedLines, const unsigned int firstLine, const unsigned int numberLines);
793 
794  /**
795  * Compares two index sets.
796  * @param first The first index set to compare
797  * @param second The second index set to compare
798  * @return True, if the first one holds lesser elements than the second one
799  */
800  static inline bool compare(const IndexSet32& first, const IndexSet32& second);
801 
802  /**
803  * Compares to lines according to their distance.
804  * @param first The first line to compare
805  * @param second The second line to compare
806  * @return True, if the distance of the first one is lesser than that of the second one
807  */
808  static inline bool compareDistance(const InfiniteLine& first, const InfiniteLine& second);
809 
810  /**
811  * Compares to groups of elements according to their size.
812  * @param first The first group of lines
813  * @param second The second groups of lines
814  * @return True, if the first group holds more elements than the second one
815  * @tparam T The data type of the elements
816  */
817  template <typename T>
818  static inline bool compareElements(const std::vector<T>& first, const std::vector<T>& second);
819 };
820 
821 inline LineDetectorHough::InfiniteLine::InfiniteLine(const Vector2& normal, const Scalar angle, const Scalar distance, const Scalar strength) :
822  Line2(normal * distance, normal.perpendicular()),
823  normal_(normal),
824  angle_(angle),
825  distance_(distance),
826  strength_(strength)
827 {
828  ocean_assert(Numeric::isEqual(normal_.length(), 1));
829  ocean_assert(Numeric::isInsideRange(-Numeric::pi(), angle, Numeric::pi()));
830  ocean_assert(strength_ > Numeric::eps() );
831 }
832 
833 inline Line2 LineDetectorHough::InfiniteLine::cornerAlignedLine(const unsigned int width, const unsigned int height) const
834 {
835  ocean_assert(width >= 3u && height >= 3u);
836 
837  const Vector2 frameCenter(Scalar(width) * Scalar(0.5), Scalar(height) * Scalar(0.5));
838 
839  return Line2(frameCenter + point(), direction());
840 }
841 
842 inline Lines2 LineDetectorHough::InfiniteLine::cornerAlignedLines(const InfiniteLine* lines, const size_t size, const unsigned int width, const unsigned int height, Scalar* strengths)
843 {
844  ocean_assert(width >= 3u && height >= 3u);
845 
846  if (size == 0)
847  {
848  return Lines2();
849  }
850 
851  ocean_assert(lines);
852 
853  Lines2 result;
854  result.reserve(size);
855 
856  const Vector2 frameCenter(Scalar(width) * Scalar(0.5), Scalar(height) * Scalar(0.5));
857 
858  if (strengths)
859  {
860  for (size_t n = 0; n < size; ++n)
861  {
862  result.push_back(Line2(frameCenter + lines[n].point(), lines[n].direction()));
863  strengths[n] = lines[n].strength();
864  }
865  }
866  else
867  {
868  for (size_t n = 0; n < size; ++n)
869  {
870  result.push_back(Line2(frameCenter + lines[n].point(), lines[n].direction()));
871  }
872  }
873 
874  return result;
875 }
876 
878 {
879  return normal_;
880 }
881 
883 {
884  return angle_;
885 }
886 
888 {
889  return distance_;
890 }
891 
893 {
894  return strength_;
895 }
896 
898 {
899  return strength_ < second.strength_;
900 }
901 
902 inline LineDetectorHough::Accumulator::AngleLookupData::AngleLookupData(const unsigned int angleBin, const unsigned int weight) :
903  angleBin_(angleBin),
904  weight_(weight)
905 {
906  // nothing to do here
907 };
908 
910  directionX_(dx),
911  directionY_(dy)
912 {
913  // nothing to do here
914 };
915 
916 inline unsigned int LineDetectorHough::Accumulator::width() const
917 {
918  return accumulatorImageWidth_;
919 }
920 
921 inline unsigned int LineDetectorHough::Accumulator::height() const
922 {
924 }
925 
927 {
928  return accumulatorFrame_.width();
929 }
930 
931 inline unsigned int LineDetectorHough::Accumulator::angleBins() const
932 {
933  return accumulatorFrame_.height();
934 }
935 
937 {
939 }
940 
942 {
944 }
945 
946 inline const uint32_t* LineDetectorHough::Accumulator::votes() const
947 {
948  return accumulatorFrame_.constdata<unsigned int>();
949 }
950 
951 inline LineDetectorHough::Accumulator::operator bool() const
952 {
953  return accumulatorFrame_.width() >= 1 && accumulatorFrame_.height() >= 1;
954 }
955 
957 {
958  std::sort(lines.begin(), lines.end(), compareDistance);
959 }
960 
961 template <typename T>
962 inline void LineDetectorHough::sortGroupsDescendingAccordingElements(std::vector<std::vector<T>>& groups)
963 {
964  std::sort(groups.begin(), groups.end(), compareElements<T>);
965 }
966 
967 inline bool LineDetectorHough::compare(const IndexSet32& first, const IndexSet32& second)
968 {
969  return first.size() > second.size();
970 }
971 
972 inline bool LineDetectorHough::compareDistance(const InfiniteLine& first, const InfiniteLine& second)
973 {
974  return first.distance() < second.distance();
975 }
976 
977 template <typename T>
978 inline bool LineDetectorHough::compareElements(const std::vector<T>& first, const std::vector<T>& second)
979 {
980  return first.size() > second.size();
981 }
982 
983 inline bool LineDetectorHough::detectLines(const Frame& frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines& infiniteLines, FiniteLines2* finiteLines, const bool optimizeLines, const unsigned int accumulatorThreshold, const unsigned int voteThreshold, const unsigned int angleNeigbors, const bool determineExactPeakMaximum, Worker* worker, const unsigned int anglePrecision, const unsigned int distancePrecision, const bool halfOrientationPrecision, const Scalar similarDistance, const Scalar similarAngle)
984 {
985  ocean_assert(accumulatorThreshold > 0);
986  ocean_assert(similarDistance >= 0);
987  ocean_assert(similarAngle >= 0);
988 
989  return internalDetectLines(frame, filterType, filterResponse, infiniteLines, finiteLines, optimizeLines, Scalar(accumulatorThreshold), 0u, voteThreshold, angleNeigbors, determineExactPeakMaximum, worker, anglePrecision, distancePrecision, halfOrientationPrecision, similarDistance, similarAngle);
990 }
991 
992 inline bool LineDetectorHough::detectLinesWithAdaptiveThreshold(const Frame& frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines& infiniteLines, FiniteLines2* finiteLines, const bool optimizeLines, const Scalar thresholdRatio, const unsigned int thresholdWindow, const unsigned int voteThreshold, const unsigned int angleNeigbors, const bool determineExactPeakMaximum, Worker* worker, const unsigned int anglePrecision, const unsigned int distancePrecision, const bool halfOrientationPrecision, const Scalar similarDistance, const Scalar similarAngle)
993 {
994  ocean_assert(thresholdRatio > 0 && thresholdWindow > 0u);
995  ocean_assert(similarDistance >= 0);
996  ocean_assert(similarAngle >= 0);
997 
998  ocean_assert(thresholdWindow >= 5u && (thresholdWindow % 2u) == 1u); // 5 as 3 is the non-suppression-area already
999 
1000  const unsigned int adaptiveThresholdWindowHalf = thresholdWindow / 2u;
1001 
1002  return internalDetectLines(frame, filterType, filterResponse, infiniteLines, finiteLines, optimizeLines, thresholdRatio, adaptiveThresholdWindowHalf, voteThreshold, angleNeigbors, determineExactPeakMaximum, worker, anglePrecision, distancePrecision, halfOrientationPrecision, similarDistance, similarAngle);
1003 }
1004 
1005 }
1006 
1007 }
1008 
1009 }
1010 
1011 #endif // META_OCEAN_CV_DETECTOR_LINE_DETECTOR_HOUGH_H
This class holds angle lookup data.
Definition: LineDetectorHough.h:182
This class holds distance lookup data.
Definition: LineDetectorHough.h:210
This class defines a data lookup manager defined as singleton.
Definition: LineDetectorHough.h:238
Lock lock_
The manager's look.
Definition: LineDetectorHough.h:313
const DirectionLookupData * directionLookupData(const unsigned int angleBins, const unsigned int distanceBins, const bool halfOrientationPrecision)
Returns the direction lookup data for an angle request.
const AngleLookupData * angleLookupDataDiagonal8BitResponse16BitRequest(const unsigned int angleBins, const bool halfOrientationPrecision)
Returns the angle lookup data for 8 bit diagonal (45 and 135 degree) response values.
std::pair< unsigned int, bool > MapPair
Definition of a pair combining an unsigned integer with a boolean state.
Definition: LineDetectorHough.h:247
DirectionLookupMap directionLookupMap_
Lookup map for directions.
Definition: LineDetectorHough.h:310
std::map< MapTriple, DirectionLookupData * > DirectionLookupMap
Definition of a map mapping precision values to direction lookup data.
Definition: LineDetectorHough.h:262
const AngleLookupData * angleLookupData8BitResponse16BitRequest(const unsigned int angleBins, const bool halfOrientationPrecision)
Returns the angle lookup data for 8 bit horizontal and vertical response values.
std::tuple< unsigned int, unsigned int, bool > MapTriple
Definition of a tuple combining angleBins, distanceBins and halfOrientationPrecision.
Definition: LineDetectorHough.h:252
AngleLookupMap angleLookupMapDiagonal_
Lookup map for angles, diagonal.
Definition: LineDetectorHough.h:307
AngleLookupMap angleLookupMap_
Lookup map for angles, horizontal and vertical.
Definition: LineDetectorHough.h:304
std::map< MapPair, AngleLookupData * > AngleLookupMap
Definition of a map mapping precision values to angle lookup data.
Definition: LineDetectorHough.h:257
Vote accumulator array.
Definition: LineDetectorHough.h:173
unsigned int distanceBins() const
Returns the distance precision of this accumulator.
Definition: LineDetectorHough.h:926
static void joinFour(Accumulator *accumulators, const unsigned int firstAngleBin, const unsigned int numberAngleBins)
Joins a subset of four accumulator objects.
unsigned int angleBins() const
Returns the number of bins this accumulator stores for angle votes (including the additional bins for...
Definition: LineDetectorHough.h:931
void detectAdaptivePeaks(InfiniteLines &lines, const Scalar adaptiveVoteThresholdFactor, const unsigned int windowHalf, const bool determineExactPeakMaximum, Worker *worker=nullptr, const bool smoothAccumulator=false)
Detects peaks inside a subset of the accumulator votes using a surrounding window to determine the th...
static void joinTwo(Accumulator *accumulators, const unsigned int firstAngleBin, const unsigned int numberAngleBins)
Joins a subset of two accumulator objects.
const unsigned int accumulatorImageHeight_
Height of the original image in pixel.
Definition: LineDetectorHough.h:529
void detectAdaptivePeaksSubset(const uint32_t *borderedIntegralAccumulator, const Scalar adaptiveVoteThresholdFactor, const unsigned int windowHalf, const bool determineExactPeakMaximum, Lock *lock, InfiniteLines *lines, const unsigned int firstAngleBin, const unsigned int numberAngleBins)
Detects peaks inside a subset of the accumulator votes using a surrounding window to determine the th...
static void joinTwo(Accumulator *accumulators, Worker *worker=nullptr)
Joins two accumulator objects.
unsigned int angleBinsCore() const
Returns the angle precision of this accumulator.
Definition: LineDetectorHough.h:936
void createMirroredAngleBins()
Creates the additional mirrored angle bins at the top and bottom of the accumulator frame.
void detectPeaksSubset(const unsigned int voteThreshold, const bool determineExactPeakMaximum, Lock *lock, InfiniteLines *lines, const unsigned int firstAngleBin, const unsigned int numberAngleBins)
Detects peaks inside a subset of the accumulator votes.
void detectPeaks(InfiniteLines &lines, const unsigned int voteThreshold, const bool determineExactPeakMaximum, Worker *worker=nullptr, const bool smoothAccumulator=false)
Detects peaks inside the accumulator votes.
void accumulateDiagonal(const unsigned int x, const unsigned int y, const int8_t *responsesDiagonal, const unsigned int angleNeigbors=3u)
Adds a new diagonal (45 degree and 135 degree) filter edge filter response to accumulate the correspo...
unsigned int mirroredAngleBins() const
Returns the additional angle bins of this accumulator.
Definition: LineDetectorHough.h:941
void clear()
Clears the accumulation buffer.
unsigned int width() const
Returns the width of the original image in pixel.
Definition: LineDetectorHough.h:916
Frame accumulatorFrame_
Array holding the individual votes.
Definition: LineDetectorHough.h:514
void accumulate(const unsigned int x, const unsigned int y, const int8_t *responses, const unsigned int angleNeigbors=3u)
Adds a new horizontal and vertical edge filter response to accumulate the corresponding vote.
unsigned int accumulatorMirroredAngleBins_
Additional angle bins simplifying border operations.
Definition: LineDetectorHough.h:523
const uint32_t * votes() const
Returns the vote buffer stored for this accumulator.
Definition: LineDetectorHough.h:946
const unsigned int accumulatorImageWidth_
Width of the original image in pixel.
Definition: LineDetectorHough.h:526
Accumulator(const unsigned int width, const unsigned int height, const unsigned int distanceBins, const unsigned int angleBins, const unsigned int mirroredAngleBins, const bool halfOrientationPrecision)
Creates a new vote element by the given precisions for distance and angle.
static void joinFour(Accumulator *accumulators, Worker *worker=nullptr)
Joins four accumulator objects.
static void join(Accumulator *accumulators, const unsigned int number, Worker *worker=nullptr)
Joins an arbitrary number of accumulator objects.
unsigned int height() const
Returns the height of the original image in pixel.
Definition: LineDetectorHough.h:921
static void join(Accumulator *accumulators, const unsigned int number, const unsigned int firstAngleBin, const unsigned int numberAngleBins)
Joins a subset of an arbitrary number of accumulator objects.
This class defines an infinite 2D line.
Definition: LineDetectorHough.h:54
Scalar strength() const
Returns the strength of this line.
Definition: LineDetectorHough.h:892
Vector2 normal_
Line normal.
Definition: LineDetectorHough.h:145
bool isParallel(const InfiniteLine &line, const Scalar cosAngle) const
Returns whether two lines are parallel up to a given angle precision.
Scalar strength_
Line strength.
Definition: LineDetectorHough.h:154
InfiniteLine()=default
Creates an empty line object.
Scalar angle() const
Returns the angle of this line.
Definition: LineDetectorHough.h:882
Line2 cornerAlignedLine(const unsigned int width, const unsigned int height) const
Converts this line (with origin defined in the center of the frame) to a line with origin defined in ...
Definition: LineDetectorHough.h:833
const Vector2 & normal() const
Returns the normal of this line.
Definition: LineDetectorHough.h:877
bool isSimilar(const InfiniteLine &line, const Scalar distance, const Scalar cosAngle, const bool halfOrientationPrecision) const
Returns whether two lines are similar up to a given distance and angle precision.
static Lines2 cornerAlignedLines(const InfiniteLine *lines, const size_t size, const unsigned int width, const unsigned int height, Scalar *strengths=nullptr)
Converts lines (with origin defined in the center of the frame) to a lines with origin defined in the...
Definition: LineDetectorHough.h:842
bool operator<(const InfiniteLine &second) const
Returns whether this line object has a lower strength value than the second one.
Definition: LineDetectorHough.h:897
Scalar distance() const
Returns the distance of this line.
Definition: LineDetectorHough.h:887
This class implements a line detector mainly based on the Hough transformation.
Definition: LineDetectorHough.h:43
std::vector< InfiniteLine > InfiniteLines
Definition of a vector holding infinite lines.
Definition: LineDetectorHough.h:160
static void detectFiniteLinesSubset(const InfiniteLines *infiniteLines, const int8_t *response, const unsigned int width, const unsigned int height, const FilterResponse filterResponse, const unsigned int angleBins, const Accumulator::AngleLookupData *horizontalAngleLookup, const Accumulator::AngleLookupData *diagonalAngleLookup, const bool halfOrientationPrecision, Lock *lock, FiniteLines2 *finiteLines, const unsigned int firstLine, const unsigned int numberLines)
Detects finite lines from a subset of already detected infinite lines additionally using the frame fi...
static void optimizeInfiniteLinesSubset(const InfiniteLine *infiniteLines, const size_t number, const int8_t *response, const unsigned int width, const unsigned int height, const FilterResponse filterResponse, const unsigned int radius, const Accumulator *accumulator, const bool halfOrientationPrecision, InfiniteLine *optimizedLines, const unsigned int firstLine, const unsigned int numberLines)
Refines lines by adjusting the line with the filter responses.
FilterResponse
Definition of usage of different filter responses.
Definition: LineDetectorHough.h:579
static void detectFiniteLines(const InfiniteLine &infiniteLine, const int8_t *response, const unsigned int width, const unsigned int height, const FilterResponse filterResponse, const unsigned int angleBins, const Accumulator::AngleLookupData *horizontalAngleLookup, const Accumulator::AngleLookupData *diagonalAngleLookup, const bool halfOrientationPrecision, FiniteLines2 &finiteLines)
Detects finite lines from one infinite line additionally using the frame filter responses.
static void createVotesHorizontalVerticalDiagonalSubset(const int8_t *response, Accumulator *accumulator, const unsigned int angleNeigbors, const unsigned int voteThreshold, const unsigned int firstRow, const unsigned int numberRows)
Creates line votes for horizontal, vertical and diagonal (0, 90 and 45, 135 degree) filter responses ...
static bool detectLinesWithAdaptiveThreshold(const Frame &frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines &infiniteLines, FiniteLines2 *finiteLines=nullptr, const bool optimizeLines=true, const Scalar adaptiveVoteThresholdFactor=Scalar(8), const unsigned int thresholdWindow=61u, const unsigned int voteThreshold=16, const unsigned int angleNeigbors=2u, const bool determineExactPeakMaximum=true, Worker *worker=nullptr, const unsigned int anglePrecision=360u, const unsigned int distancePrecision=(unsigned int)(-1), const bool halfOrientationPrecision=true, const Scalar similarDistance=Scalar(10), const Scalar similarAngle=Numeric::deg2rad(5))
Detects lines inside a given frame using an adaptive threshold in combination with a surrounding wind...
Definition: LineDetectorHough.h:992
static void filterLines(const InfiniteLines &lines, const Scalar minDistance, const Scalar minAngle, InfiniteLines &filteredLines, const bool halfOrientationPrecision)
Filters a set of similar detected lines so that the strongest and unique lines are returned only.
static bool parallelLines(const InfiniteLines &lines, const Scalar minAngle, InfiniteLines &parallels)
Filters the biggest set of parallel lines from a given set of lines.
static void sortLinesAccordingDistance(InfiniteLines &lines)
Sorts lines according to their distance values.
Definition: LineDetectorHough.h:956
static bool compare(const IndexSet32 &first, const IndexSet32 &second)
Compares two index sets.
Definition: LineDetectorHough.h:967
static void createVotesDiagonalSubset(const int8_t *response, Accumulator *accumulator, const unsigned int angleNeigbors, const unsigned int voteThreshold, const unsigned int firstRow, const unsigned int numberRows)
Creates line votes for diagonal (45 and 135 degree) filter responses inside a given accumulator objec...
static bool internalDetectLines(const Frame &frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines &infiniteLines, FiniteLines2 *finiteLines, const bool optimizeLines, const Scalar thresholdParameter, const unsigned int adaptiveThresholdWindowHalf, const unsigned int voteThreshold, const unsigned int angleNeigbors, const bool determineExactPeakMaximum, Worker *worker, const unsigned int anglePrecision, const unsigned int distancePrecision, const bool halfOrientationPrecision, const Scalar similarDistance, const Scalar similarAngle)
Internal line detection function to detects lines inside an 8 bit gray scale image.
static bool detectLines(const Frame &frame, const FilterType filterType, const FilterResponse filterResponse, InfiniteLines &infiniteLines, FiniteLines2 *finiteLines=nullptr, const bool optimizeLines=true, const unsigned int accumulatorThreshold=100u, const unsigned int voteThreshold=16u, const unsigned int angleNeigbors=2u, const bool determineExactPeakMaximum=true, Worker *worker=nullptr, const unsigned int anglePrecision=360u, const unsigned int distancePrecision=(unsigned int)(-1), const bool halfOrientationPrecision=true, const Scalar similarDistance=Scalar(10), const Scalar similarAngle=Numeric::deg2rad(5))
Detects lines inside a given frame using a threshold ensuring that detected lines have a specific str...
Definition: LineDetectorHough.h:983
static bool compareElements(const std::vector< T > &first, const std::vector< T > &second)
Compares to groups of elements according to their size.
Definition: LineDetectorHough.h:978
static void sortGroupsDescendingAccordingElements(std::vector< std::vector< T >> &groups)
Sorts groups of elements (of e.g., infinite lines) according to their number of elements in descendin...
Definition: LineDetectorHough.h:962
std::vector< IndexSet32 > IndexSetVector
Definition of a vector holding index sets.
Definition: LineDetectorHough.h:558
FilterType
Definition of different edge detector filters.
Definition: LineDetectorHough.h:566
@ FT_SCHARR
Definition: LineDetectorHough.h:570
std::vector< InfiniteLines > InfiniteLineGroups
Definition of a vector holding infinite lines.
Definition: LineDetectorHough.h:165
static bool compareDistance(const InfiniteLine &first, const InfiniteLine &second)
Compares to lines according to their distance.
Definition: LineDetectorHough.h:972
static void createVotesHorizontalVerticalSubset(const int8_t *response, Accumulator *accumulator, const unsigned int angleNeigbors, const unsigned int voteThreshold, const unsigned int firstRow, const unsigned int numberRows)
Creates line votes for horizontal and vertical (0 and 90 degree) filter responses inside a given accu...
static void parallelLines(const InfiniteLines &lines, const Scalar maxAngle, InfiniteLineGroups &parallelGroups, const unsigned int minimalSetSize=0u, const bool noDuplicates=true)
Separates given lines in sets of almost parallel lines.
This class implements Ocean's image class.
Definition: Frame.h:1792
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4168
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3143
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3148
This class implements an infinite line in 2D space.
Definition: Line2.h:83
This class implements a recursive lock object.
Definition: Lock.h:31
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition: Numeric.h:3232
static constexpr bool isInsideRange(const T lower, const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a value lies between a given range up to a provided epsilon border.
Definition: Numeric.h:2872
static constexpr T pi()
Returns PI which is equivalent to 180 degree.
Definition: Numeric.h:926
static constexpr T eps()
Returns a small epsilon.
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition: Numeric.h:2386
This template class is the base class for all singleton objects.
Definition: Singleton.h:71
This class implements houg-transformation-based line detector tests.
Definition: TestLineDetectorHough.h:32
T length() const
Returns the length of the vector.
Definition: Vector2.h:615
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
std::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition: Base.h:114
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Line2 > Lines2
Definition of a vector holding Line2 objects.
Definition: Line2.h:57
LineT2< Scalar > Line2
Definition of the Line2 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single o...
Definition: Line2.h:21
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition: FiniteLine2.h:57
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15