Ocean
Loading...
Searching...
No Matches
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"
15#include "ocean/base/Worker.h"
16
18#include "ocean/math/Line2.h"
19#include "ocean/math/Vector2.h"
20
21#include <algorithm>
22#include <tuple>
23
24namespace Ocean
25{
26
27// Forward declaration for test library.
28namespace Test { namespace TestCV { namespace TestDetector { class TestLineDetectorHough; } } }
29
30namespace CV
31{
32
33namespace 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 */
42class 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 */
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
821inline 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));
830 ocean_assert(strength_ > Numeric::eps() );
831}
832
833inline 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
842inline 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
902inline 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
916inline unsigned int LineDetectorHough::Accumulator::width() const
917{
919}
920
921inline unsigned int LineDetectorHough::Accumulator::height() const
922{
924}
925
927{
928 return accumulatorFrame_.width();
929}
930
932{
933 return accumulatorFrame_.height();
934}
935
940
945
946inline const uint32_t* LineDetectorHough::Accumulator::votes() const
947{
948 return accumulatorFrame_.constdata<unsigned int>();
949}
950
951inline 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
961template <typename T>
962inline void LineDetectorHough::sortGroupsDescendingAccordingElements(std::vector<std::vector<T>>& groups)
963{
964 std::sort(groups.begin(), groups.end(), compareElements<T>);
965}
966
967inline bool LineDetectorHough::compare(const IndexSet32& first, const IndexSet32& second)
968{
969 return first.size() > second.size();
970}
971
972inline bool LineDetectorHough::compareDistance(const InfiniteLine& first, const InfiniteLine& second)
973{
974 return first.distance() < second.distance();
975}
976
977template <typename T>
978inline bool LineDetectorHough::compareElements(const std::vector<T>& first, const std::vector<T>& second)
979{
980 return first.size() > second.size();
981}
982
983inline 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
992inline 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
const AngleLookupData * angleLookupData8BitResponse16BitRequest(const unsigned int angleBins, const bool halfOrientationPrecision)
Returns the angle lookup data for 8 bit horizontal and vertical response values.
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.
Lock lock_
The manager's look.
Definition LineDetectorHough.h:313
std::pair< unsigned int, bool > MapPair
Definition of a pair combining an unsigned integer with a boolean state.
Definition LineDetectorHough.h:247
const DirectionLookupData * directionLookupData(const unsigned int angleBins, const unsigned int distanceBins, const bool halfOrientationPrecision)
Returns the direction lookup data for an angle request.
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
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:1808
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:4248
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3170
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3175
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 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:627
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:129
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:28
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition FiniteLine2.h:57
The namespace covering the entire Ocean framework.
Definition Accessor.h:15