8 #ifndef META_OCEAN_CV_DETECTOR_LINE_EVALUATOR_H
9 #define META_OCEAN_CV_DETECTOR_LINE_EVALUATOR_H
18 #include <unordered_map>
19 #include <unordered_set>
41 typedef unsigned int Id;
46 typedef std::unordered_set<Id>
IdSet;
160 inline double angle()
const;
347 typedef std::unordered_set<unsigned long long>
Id64Set;
369 template <
typename T>
370 static bool areLinesOverlapping(
const FiniteLineT2<T>& lineGroundTruth,
const FiniteLineT2<T>& lineEvaluation,
const T angleThresholdCos,
const T distanceThresholdPixels,
const DistanceMeasure distanceMeasure, T* projectedLength =
nullptr, T* outOfBorderDistance0 =
nullptr, T* outOfBorderDistance1 =
nullptr, T* locationOnLine0 =
nullptr, T* locationOnLine1 =
nullptr);
386 template <
typename T>
387 static void determineOverlappingAmount(
const FiniteLineT2<T>& lineGroundTruth,
const FiniteLineT2<T>& lineEvaluation, T* projectedLength =
nullptr, T* outOfBorderDistance0 =
nullptr, T* outOfBorderDistance1 =
nullptr, T* locationOnLine0 =
nullptr, T* locationOnLine1 =
nullptr);
399 template <
typename T>
417 template <
typename T>
438 template <
typename T>
439 static bool evaluateLineMatches(
const std::unordered_map<
Id,
FiniteLineT2<T>>& linesGroundTruth,
const std::unordered_map<
Id,
FiniteLineT2<T>>& linesEvaluation,
const LineMatchMap& lineMatches,
double& coverage,
double& medianAngle,
double& medianDistance,
size_t& countPerfectMatches,
size_t& countPartialMatches,
size_t& countComplexMatches,
size_t& notCoveredGroundTruthLines,
size_t& notCoveredEvaluationLines,
IdSet* notCoveredGroundTruthLineIds =
nullptr,
IdSet* notCoveredEvaluationLineIds =
nullptr);
451 template <
typename T>
464 template <
typename T>
473 static inline unsigned long long combineIds(
const Id& firstId,
const Id& secondId);
496 maximalDistance_(maximalDistance)
518 return maximalDistance_;
523 targetIds_(targetIds),
525 medianAngle_(medianAngle),
526 medianDistance_(medianDistance)
535 targetIds_(std::move(targetIds)),
537 medianAngle_(medianAngle),
538 medianDistance_(medianDistance)
567 return medianDistance_;
571 PartialLineMatch(sourceId, targetIds, coverage, medianAngle, medianDistance),
572 connectedSourceIds_(connectedSourceIds),
573 connectedTargetIds_(connectedTargetIds)
585 return connectedSourceIds_;
590 return connectedTargetIds_;
593 template <
typename T>
596 ocean_assert(lineGroundTruth.
isValid() && lineEvaluation.
isValid());
598 ocean_assert(angleThresholdCos >= T(0) && angleThresholdCos <= T(1));
599 ocean_assert(distanceThresholdPixels >= T(0));
605 if (absCosineValue < angleThresholdCos)
610 const T sqrDistanceThresholdPixels = distanceThresholdPixels * distanceThresholdPixels;
626 if (internalSqrDistance > sqrDistanceThresholdPixels)
633 T internalOutOfBoundaryDistanceOnGroundTruth0, internalLocationOnGroundTruth0;
636 T internalOutOfBoundaryDistanceOnGroundTruth1, internalLocationOnGroundTruth1;
643 const T sqrDistanceOnEvaluationLine = std::max(pointOnInfiniteGroundTruth0.
sqrDistance(lineEvaluation.
point0()), pointOnInfiniteGroundTruth1.
sqrDistance(lineEvaluation.
point1()));
649 if (sqrDistanceOnEvaluationLine > sqrDistanceThresholdPixels)
654 internalSqrDistance = sqrDistanceOnEvaluationLine;
660 if (sqrDistanceOnEvaluationLine < internalSqrDistance)
662 internalSqrDistance = sqrDistanceOnEvaluationLine;
667 if (internalSqrDistance > sqrDistanceThresholdPixels)
680 ocean_assert(internalOutOfBoundaryDistanceOnGroundTruth0 <= internalOutOfBoundaryDistanceOnGroundTruth1);
682 if (internalOutOfBoundaryDistanceOnGroundTruth1 < 0 || internalOutOfBoundaryDistanceOnGroundTruth0 > 0)
689 ocean_assert(internalLocationOnGroundTruth0 <= internalLocationOnGroundTruth1);
693 *projectedLength = internalLocationOnGroundTruth1 - internalLocationOnGroundTruth0;
698 if (outOfBorderDistance0)
700 *outOfBorderDistance0 = internalOutOfBoundaryDistanceOnGroundTruth0;
703 if (outOfBorderDistance1)
705 *outOfBorderDistance1 = internalOutOfBoundaryDistanceOnGroundTruth1;
710 *locationOnLine0 = internalLocationOnGroundTruth0;
715 *locationOnLine1 = internalLocationOnGroundTruth1;
721 template <
typename T>
724 ocean_assert(lineGroundTruth.
isValid() && lineEvaluation.
isValid());
726 T internalOutOfBoundaryDistanceOnGroundTruth0, internalLocationOnGroundTruth0;
729 T internalOutOfBoundaryDistanceOnGroundTruth1, internalLocationOnGroundTruth1;
737 *projectedLength = internalLocationOnGroundTruth1 - internalLocationOnGroundTruth0;
740 if (outOfBorderDistance0)
742 *outOfBorderDistance0 = internalOutOfBoundaryDistanceOnGroundTruth0;
745 if (outOfBorderDistance1)
747 *outOfBorderDistance1 = internalOutOfBoundaryDistanceOnGroundTruth1;
752 *locationOnLine0 = internalLocationOnGroundTruth0;
757 *locationOnLine1 = internalLocationOnGroundTruth1;
761 template <
typename T>
764 ocean_assert(lineGroundTruth.
isValid() && lineEvaluation.
isValid());
791 const T sqrDistanceOnEvaluationLine = std::max(pointOnInfiniteGroundTruth0.
sqrDistance(lineEvaluation.
point0()), pointOnInfiniteGroundTruth1.
sqrDistance(lineEvaluation.
point1()));
801 template <
typename T>
804 ocean_assert(!linesGroundTruth.empty() && !linesEvaluation.empty());
806 ocean_assert(perfectMatchAngleThreshold >= 0 && perfectMatchAngleThreshold <=
NumericT<T>::pi_2());
807 ocean_assert(perfectMatchPixelThreshold >= 0);
809 ocean_assert(matchAngleThreshold >= 0 && matchAngleThreshold <=
NumericT<T>::pi_2());
810 ocean_assert(matchCloseToLinePixelThreshold >= 0);
812 ocean_assert(partialMatchNonOverlappingPixelThreshold >= 0);
813 ocean_assert(complexMatchMaximalGapPixelThreshold >= 0);
815 typedef std::unordered_map<Id, FiniteLineT2<T>> LineMap;
822 Id64Set groundTruthEvaluationSet;
824 const T perfectMatchAngleThresholdCos =
NumericT<T>::cos(perfectMatchAngleThreshold);
827 for (
typename LineMap::const_iterator iG = linesGroundTruth.cbegin(); iG != linesGroundTruth.cend(); ++iG)
829 const Id& groundTruthId = iG->first;
831 ocean_assert(lineGroundTruth.
isValid());
833 for (
typename LineMap::const_iterator iE = linesEvaluation.cbegin(); iE != linesEvaluation.cend(); ++iE)
835 const Id& evaluationId = iE->first;
837 ocean_assert(lineEvaluation.
isValid());
843 groundTruthToEvaluationMap[groundTruthId].insert(evaluationId);
846 groundTruthEvaluationSet.insert(
combineIds(groundTruthId, evaluationId));
849 evaluationToGroundTruthMap[evaluationId].insert(groundTruthId);
858 for (
typename LineMap::const_iterator iG = linesGroundTruth.cbegin(); iG != linesGroundTruth.cend(); ++iG)
860 const Id& groundTruthId = iG->first;
869 for (
typename LineMap::const_iterator iE = linesEvaluation.cbegin(); !complexMatch && iE != linesEvaluation.cend(); ++iE)
871 const Id& evaluationId = iE->first;
874 if (groundTruthEvaluationSet.find(
combineIds(groundTruthId, evaluationId)) != groundTruthEvaluationSet.cend())
876 T projectedLengthEvaluationLine;
877 T outOfBoundaryDistance0, outOfBoundaryDistance1;
878 T locationOnLine0, locationOnLine1;
881 determineOverlappingAmount(lineGroundTruth, lineEvaluation, &projectedLengthEvaluationLine, &outOfBoundaryDistance0, &outOfBoundaryDistance1, &locationOnLine0, &locationOnLine1);
885 if (projectedNonOverlappingLength <= partialMatchNonOverlappingPixelThreshold)
887 const T projectedOverlappingLength = projectedLengthEvaluationLine - projectedNonOverlappingLength;
890 ocean_assert_and_suppress_unused(projectedOverlappingLength <= lineGroundTruth.
length() +
NumericT<T>::weakEps(), projectedOverlappingLength);
892 ocean_assert(locationOnLine0 <= locationOnLine1);
893 partialMatchUnion.
addSegment(locationOnLine0, locationOnLine1);
895 targetIds.insert(evaluationId);
902 complexMatch =
determineComplexMatch(linesGroundTruth, linesEvaluation, groundTruthToEvaluationMap, evaluationToGroundTruthMap, groundTruthId, groundTruthEvaluationSet, complexMatchMaximalGapPixelThreshold);
913 lineMatches.insert(std::make_pair(groundTruthId, complexMatch));
917 if (partialMatchUnion)
919 ocean_assert(!targetIds.empty());
923 if (targetIds.size() == 1)
927 const Id evaluationId = *targetIds.begin();
928 const FiniteLineT2<T>& lineEvaluation = linesEvaluation.find(evaluationId)->second;
933 if (absCosineValue >= perfectMatchAngleThresholdCos)
935 if (lineGroundTruth.
isEqual(lineEvaluation, perfectMatchPixelThreshold))
940 const T maximalProjectedDistance = std::max(projectedDistancePoint0, projectedDistancePoint1);
942 lineMatch = std::make_shared<PerfectLineMatch>(groundTruthId, evaluationId,
NumericT<T>::acos(absCosineValue), maximalProjectedDistance);
951 const T lengthGroundTruthLine = lineGroundTruth.
length();
952 const T lengthMatch = partialMatchUnion.
unionSize();
956 const T matchCoverage = lengthMatch / lengthGroundTruthLine;
958 std::vector<T> angles(targetIds.size());
959 std::vector<T> distances(targetIds.size());
961 const FiniteLineT2<T>& groundTruthLine = linesGroundTruth.find(groundTruthId)->second;
964 for (
const Id& targetId : targetIds)
966 const FiniteLineT2<T>& evaluationLine = linesEvaluation.find(targetId)->second;
972 const double medianAngle = double(Median::median<T>(angles.data(), angles.size()));
973 const double medianDistance = double(Median::median<T>(distances.data(), distances.size()));
975 lineMatch = std::make_shared<PartialLineMatch>(groundTruthId, std::move(targetIds), matchCoverage, medianAngle, medianDistance);
978 lineMatches.insert(std::make_pair(groundTruthId, lineMatch));
982 ocean_assert(targetIds.empty());
987 ocean_assert(lineMatches.size() <= linesGroundTruth.size());
992 template <
typename T>
993 bool LineEvaluator::evaluateLineMatches(
const std::unordered_map<
Id,
FiniteLineT2<T>>& linesGroundTruth,
const std::unordered_map<
Id,
FiniteLineT2<T>>& linesEvaluation,
const LineMatchMap& lineMatches,
double& coverage,
double& medianAngle,
double& medianDistance,
size_t& countPerfectMatches,
size_t& countPartialMatches,
size_t& countComplexMatches,
size_t& notCoveredGroundTruthLines,
size_t& notCoveredEvaluationLines,
IdSet* notCoveredGroundTruthLineIds,
IdSet* notCoveredEvaluationLineIds)
995 if (lineMatches.empty())
1000 ocean_assert(lineMatches.size() <= linesGroundTruth.size());
1001 if (lineMatches.size() > linesGroundTruth.size())
1006 double sumLengthGroundTruth = 0.0;
1008 for (
typename std::unordered_map<
Id,
FiniteLineT2<T>>::const_iterator iG = linesGroundTruth.cbegin(); iG != linesGroundTruth.cend(); ++iG)
1010 sumLengthGroundTruth += double(iG->second.length());
1013 ocean_assert(sumLengthGroundTruth > 0.0);
1014 if (sumLengthGroundTruth <= 0.0)
1019 countPerfectMatches = 0;
1020 countPartialMatches = 0;
1021 countComplexMatches = 0;
1023 double sumLengthMatches = 0.0;
1025 std::vector<double> angles;
1026 angles.reserve(lineMatches.size());
1028 std::vector<double> distances;
1029 distances.reserve(lineMatches.size());
1031 IdSet coveredEvaluationLineIds;
1033 for (
typename LineMatchMap::const_iterator iMatch = lineMatches.cbegin(); iMatch != lineMatches.cend(); ++iMatch)
1036 ocean_assert(match);
1038 const typename std::unordered_map<Id, FiniteLineT2<T>>::const_iterator iG = linesGroundTruth.find(match->sourceId());
1040 ocean_assert(iG != linesGroundTruth.cend());
1041 if (iG == linesGroundTruth.cend())
1047 ocean_assert(groundTruthLine.
isValid());
1049 const double lengthGroundTruth = double(groundTruthLine.
length());
1051 switch (match->matchType())
1057 sumLengthMatches += double(lengthGroundTruth);
1058 angles.push_back(perfectMatch.
angle());
1061 coveredEvaluationLineIds.insert(perfectMatch.
targetId());
1063 countPerfectMatches++;
1072 sumLengthMatches += partialMatch.
coverage() * lengthGroundTruth;
1076 coveredEvaluationLineIds.insert(partialMatch.
targetIds().cbegin(), partialMatch.
targetIds().cend());
1078 countPartialMatches++;
1087 sumLengthMatches += complexMatch.
coverage() * lengthGroundTruth;
1091 coveredEvaluationLineIds.insert(complexMatch.
targetIds().cbegin(), complexMatch.
targetIds().cend());
1093 countComplexMatches++;
1099 ocean_assert(
false &&
"Invalid type!");
1105 coverage = sumLengthMatches / sumLengthGroundTruth;
1108 medianDistance =
Median::median(distances.data(), distances.size());
1110 ocean_assert(coveredEvaluationLineIds.size() <= linesEvaluation.size());
1111 if (coveredEvaluationLineIds.size() > linesEvaluation.size())
1116 notCoveredGroundTruthLines = linesGroundTruth.size() - lineMatches.size();
1118 notCoveredEvaluationLines = linesEvaluation.size() - coveredEvaluationLineIds.size();
1120 if (notCoveredGroundTruthLineIds)
1122 notCoveredGroundTruthLineIds->clear();
1124 for (
typename std::unordered_map<
Id,
FiniteLineT2<T>>::const_iterator iG = linesGroundTruth.cbegin(); iG != linesGroundTruth.cend(); ++iG)
1126 if (lineMatches.find(iG->first) == lineMatches.cend())
1128 notCoveredGroundTruthLineIds->insert(iG->first);
1133 if (notCoveredEvaluationLineIds)
1135 notCoveredEvaluationLineIds->clear();
1137 for (
typename std::unordered_map<
Id,
FiniteLineT2<T>>::const_iterator iE = linesEvaluation.cbegin(); iE != linesEvaluation.cend(); ++iE)
1139 if (coveredEvaluationLineIds.find(iE->first) == coveredEvaluationLineIds.cend())
1141 notCoveredEvaluationLineIds->insert(iE->first);
1149 template <
typename T>
1152 ocean_assert(lineOfInterest.
isValid());
1153 ocean_assert(!lineIdsToProject.empty());
1157 for (
const Id& lineIdToProject : lineIdsToProject)
1159 ocean_assert(lines.find(lineIdToProject) != lines.cend());
1161 const FiniteLineT2<T>& lineToProject = lines.find(lineIdToProject)->second;
1162 ocean_assert(lineToProject.
isValid());
1164 T locationOnLineOfInterest0;
1167 T locationOnLineOfInterest1;
1172 segmentUnion.
addSegment(locationOnLineOfInterest0, locationOnLineOfInterest1);
1175 return segmentUnion;
1178 template <
typename T>
1181 ocean_assert(complexMatchMaximalGapPixelThreshold >= 0);
1204 IdSet connectedGroundTruthIds;
1205 IdSet connectedEvaluationIds;
1207 std::vector<Id> groundTruthIdStack(1, groundTruthId);
1209 while (!groundTruthIdStack.empty())
1211 const Id currentGroundTruthId = groundTruthIdStack.back();
1212 groundTruthIdStack.pop_back();
1214 connectedGroundTruthIds.insert(currentGroundTruthId);
1216 const IdToIdSetMap::const_iterator iMappingsG2E = groundTruthToEvaluationMap.find(currentGroundTruthId);
1218 if (iMappingsG2E != groundTruthToEvaluationMap.cend())
1220 for (
const Id& connectedEvaluationId : iMappingsG2E->second)
1222 const IdSet::const_iterator iConnectedEvaluation = connectedEvaluationIds.find(connectedEvaluationId);
1224 if (iConnectedEvaluation == connectedEvaluationIds.cend())
1226 connectedEvaluationIds.insert(connectedEvaluationId);
1228 const IdToIdSetMap::const_iterator iMappingsE2G = evaluationToGroundTruthMap.find(connectedEvaluationId);
1230 if (iMappingsE2G != evaluationToGroundTruthMap.cend())
1232 for (
const Id& connectedGroundTruthId : iMappingsE2G->second)
1234 if (connectedGroundTruthIds.find(connectedGroundTruthId) == connectedGroundTruthIds.cend())
1236 groundTruthIdStack.push_back(connectedGroundTruthId);
1248 IdSet validEvaluationIds;
1250 for (
const Id& connectedEvaluationId : connectedEvaluationIds)
1252 const FiniteLineT2<T>& connectedEvaluationLine = linesEvaluation.find(connectedEvaluationId)->second;
1254 const SegmentUnion<T> connectedEvaluationUnion = determineProjectedSegmentUnion<T>(connectedEvaluationLine, connectedGroundTruthIds, linesGroundTruth);
1256 const T lengthConnectedEvaluationLine = connectedEvaluationLine.
length();
1259 if (clampedConnectedEvaluationUnion)
1261 const T frontGap = clampedConnectedEvaluationUnion.
segments().begin()->first;
1262 ocean_assert(frontGap >= T(0));
1264 const T backGap = lengthConnectedEvaluationLine - clampedConnectedEvaluationUnion.
segments().rbegin()->second;
1265 ocean_assert(backGap >= T(0));
1267 const T maximalGap = std::max(frontGap, std::max(backGap, clampedConnectedEvaluationUnion.
maximalGap()));
1269 if (maximalGap < complexMatchMaximalGapPixelThreshold)
1271 ocean_assert(validEvaluationIds.find(connectedEvaluationId) == validEvaluationIds.end());
1272 validEvaluationIds.insert(connectedEvaluationId);
1282 const Id& connectedGroundTruthId = groundTruthId;
1284 const FiniteLineT2<T>& connectedGroundTruthLine = linesGroundTruth.find(connectedGroundTruthId)->second;
1285 const T lengthConnectedGroundTruthLine = connectedGroundTruthLine.
length();
1288 IdSet connectedTargetIds;
1290 std::vector<T> angles;
1291 angles.reserve(validEvaluationIds.size());
1293 std::vector<T> distances;
1294 distances.reserve(validEvaluationIds.size());
1296 for (
const Id& validEvaluationId : validEvaluationIds)
1298 const FiniteLineT2<T>& validEvaluationLine = linesEvaluation.find(validEvaluationId)->second;
1300 if (groundTruthEvaluationSet.find(
combineIds(connectedGroundTruthId, validEvaluationId)) != groundTruthEvaluationSet.cend())
1314 locationOnLine0 =
minmax(T(0), locationOnLine0, lengthConnectedGroundTruthLine);
1315 locationOnLine1 =
minmax(T(0), locationOnLine1, lengthConnectedGroundTruthLine);
1317 ocean_assert(locationOnLine0 <= locationOnLine1);
1318 if (locationOnLine0 < locationOnLine1)
1320 connectedPartialMatch.
addSegment(locationOnLine0, locationOnLine1);
1321 connectedTargetIds.insert(validEvaluationId);
1326 angles.push_back(angle);
1327 distances.push_back(distance);
1332 if (connectedPartialMatch)
1334 ocean_assert(!connectedTargetIds.empty());
1336 const T lengthMatch = connectedPartialMatch.
unionSize();
1340 const T matchCoverage = lengthMatch / lengthConnectedGroundTruthLine;
1342 const double medianAngle = double(Median::median<T>(angles.data(), angles.size()));
1343 const double medianDistance = double(Median::median<T>(distances.data(), distances.size()));
1345 return std::make_shared<ComplexLineMatch>(connectedGroundTruthId, connectedTargetIds, matchCoverage, medianAngle, medianDistance, connectedGroundTruthIds, validEvaluationIds);
1353 static_assert(
sizeof(
Id) * 2 ==
sizeof(
unsigned long long),
"Invalid data type!");
1355 return (
unsigned long long)firstId | ((
unsigned long long)secondId << 32ull);
This class implements a complex match between one source line and several target lines.
Definition: LineEvaluator.h:271
const IdSet & connectedTargetIds() const
Returns the ids of all sibling/connected target lines which have been investigated during the match c...
Definition: LineEvaluator.h:588
const IdSet & connectedSourceIds() const
Returns the ids of all sibling/connected source lines which have been investigated during the match c...
Definition: LineEvaluator.h:583
IdSet connectedTargetIds_
The ids of all sibling/connected target lines which have been investigated during the match creation.
Definition: LineEvaluator.h:310
ComplexLineMatch(const Id sourceId, const IdSet &targetIds, const double coverage, const double medianAngle, const double medianDistance, const IdSet &connectedSourceIds, const IdSet &connectedTargetIds)
Creates a new match object.
Definition: LineEvaluator.h:570
IdSet connectedSourceIds_
The ids of all sibling/connected source lines which have been investigated during the match creation.
Definition: LineEvaluator.h:307
MatchType matchType() const override
Returns the type of the match.
Definition: LineEvaluator.h:578
This class is the base class for all line matches.
Definition: LineEvaluator.h:58
MatchType
Definition of individual match types.
Definition: LineEvaluator.h:65
@ MT_INVALID
An invalid type.
Definition: LineEvaluator.h:67
@ MT_PARTIAL
A partial match,.
Definition: LineEvaluator.h:71
@ MT_PERFECT
A perfect match,.
Definition: LineEvaluator.h:69
@ MT_COMPLEX
A complex match,.
Definition: LineEvaluator.h:73
Id sourceId_
The id of the source line.
Definition: LineEvaluator.h:106
virtual MatchType matchType() const =0
Returns the type of the match.
LineMatch(const Id sourceId)
Creates a new match object.
Definition: LineEvaluator.h:476
Id sourceId() const
Returns the id of the source line.
Definition: LineEvaluator.h:487
virtual ~LineMatch()
Destructs a match object.
Definition: LineEvaluator.h:482
This class implements a partial match between one source line and several target lines.
Definition: LineEvaluator.h:191
double medianAngle_
The median angle between the source line and all target lines, in radian, with range [0,...
Definition: LineEvaluator.h:253
double coverage() const
The amout the target lines cover the source line.
Definition: LineEvaluator.h:555
double medianDistance() const
Returns the median distance between the source line and all target lines.
Definition: LineEvaluator.h:565
const IdSet & targetIds() const
Returns the ids of all target lines belonging to the partial match.
Definition: LineEvaluator.h:550
PartialLineMatch(const Id sourceId, const IdSet &targetIds, const double coverage, const double medianAngle, const double medianDistance)
Creates a new partial match object.
Definition: LineEvaluator.h:521
double coverage_
The coverage of the source line (the amout the target lines cover the source line),...
Definition: LineEvaluator.h:250
MatchType matchType() const override
Returns the type of the match.
Definition: LineEvaluator.h:545
double medianDistance_
The median distance between the source line and all target lines, with range [0, infinity)
Definition: LineEvaluator.h:256
IdSet targetIds_
The ids of all target lines.
Definition: LineEvaluator.h:247
double medianAngle() const
Returns the median angle between the source line and all target lines.
Definition: LineEvaluator.h:560
This class implements a perfect match between a source line and a target line.
Definition: LineEvaluator.h:132
Id targetId() const
Returns the id of the target line.
Definition: LineEvaluator.h:506
PerfectLineMatch(const Id sourceId, const Id targetId, const double angle, const double maximalDistance)
Creates a new match object.
Definition: LineEvaluator.h:492
unsigned int targetId_
The id of the target line.
Definition: LineEvaluator.h:171
double angle_
The absolute angle between both lines, with range [0, PI/2].
Definition: LineEvaluator.h:174
double maximalDistance_
The maximal distance between infinite source line and target line, with range [0, infinity)
Definition: LineEvaluator.h:177
double angle() const
Returns the angle between the source and the target line.
Definition: LineEvaluator.h:511
MatchType matchType() const override
Returns the type of the match.
Definition: LineEvaluator.h:501
double maximalDistance() const
Returns maximal distance between infinite source line and target line.
Definition: LineEvaluator.h:516
This class implements an evalutator for line segments.
Definition: LineEvaluator.h:35
std::unordered_map< Id, IdSet > IdToIdSetMap
Definition of an unordered map mapping ids to sets of ids.
Definition: LineEvaluator.h:51
static bool evaluateLineMatches(const std::unordered_map< Id, FiniteLineT2< T >> &linesGroundTruth, const std::unordered_map< Id, FiniteLineT2< T >> &linesEvaluation, const LineMatchMap &lineMatches, double &coverage, double &medianAngle, double &medianDistance, size_t &countPerfectMatches, size_t &countPartialMatches, size_t &countComplexMatches, size_t ¬CoveredGroundTruthLines, size_t ¬CoveredEvaluationLines, IdSet *notCoveredGroundTruthLineIds=nullptr, IdSet *notCoveredEvaluationLineIds=nullptr)
Evaluates the overall quality of line matches.
Definition: LineEvaluator.h:993
DistanceMeasure
Definition of individual strategies to determine the distance between two line segments.
Definition: LineEvaluator.h:317
@ DM_PROJECTED_ONTO_GROUND_TRUTH
The end points of the evaluation line are projected onto the infinite ground truth line,...
Definition: LineEvaluator.h:324
@ DM_PROJECTED_ONTO_EVALUATION_LINE
The end points of the ground truth lines are projected onto the infinite evaluation line,...
Definition: LineEvaluator.h:332
@ DM_PROJECTED_ONTO_EACH_OTHER
This measure combines 'DM_PROJECTED_ONTO_GROUND_TRUTH' and 'DM_PROJECTED_ONTO_EVALUATION_LINE'.
Definition: LineEvaluator.h:339
std::unordered_set< Id > IdSet
Definition of an unordered set of ids.
Definition: LineEvaluator.h:46
unsigned int Id
Definition of an id identifying e.g., a specific line.
Definition: LineEvaluator.h:41
static unsigned long long combineIds(const Id &firstId, const Id &secondId)
Combines two (32 bit) ids to one 64 bit value.
Definition: LineEvaluator.h:1351
std::shared_ptr< LineMatch > LineMatchRef
Definition of a shared pointer for a LineMatch object.
Definition: LineEvaluator.h:113
static void determineSimilarity(const FiniteLineT2< T > &lineGroundTruth, const FiniteLineT2< T > &lineEvaluation, const DistanceMeasure distanceMeasure, T &angle, T &distance)
Determines the similarity between two lines known to be overlapping.
Definition: LineEvaluator.h:762
static SegmentUnion< T > determineProjectedSegmentUnion(const FiniteLineT2< T > &lineOfInterest, const IdSet &lineIdsToProject, const std::unordered_map< Id, FiniteLineT2< T >> &lines)
Determines the union of segments resulting from projecting several finite lines onto a unique finite ...
Definition: LineEvaluator.h:1150
static LineMatchRef determineComplexMatch(const std::unordered_map< Id, FiniteLineT2< T >> &linesGroundTruth, const std::unordered_map< Id, FiniteLineT2< T >> &linesEvaluation, const IdToIdSetMap &groundTruthToEvaluationMap, const IdToIdSetMap evaluationToGroundTruthMap, const Id groundTruthId, const Id64Set &groundTruthEvaluationSet, const T complexMatchMaximalGapPixelThreshold)
Determines a complex match for a given ground truth line.
Definition: LineEvaluator.h:1179
static void determineOverlappingAmount(const FiniteLineT2< T > &lineGroundTruth, const FiniteLineT2< T > &lineEvaluation, T *projectedLength=nullptr, T *outOfBorderDistance0=nullptr, T *outOfBorderDistance1=nullptr, T *locationOnLine0=nullptr, T *locationOnLine1=nullptr)
Determines the overlapping metrics between two lines that are known to overlapping (and to be similar...
Definition: LineEvaluator.h:722
std::unordered_multimap< Id, LineMatchRef > LineMatchMap
Definition of an unordered multi map mapping ids to match objects.
Definition: LineEvaluator.h:118
static bool areLinesOverlapping(const FiniteLineT2< T > &lineGroundTruth, const FiniteLineT2< T > &lineEvaluation, const T angleThresholdCos, const T distanceThresholdPixels, const DistanceMeasure distanceMeasure, T *projectedLength=nullptr, T *outOfBorderDistance0=nullptr, T *outOfBorderDistance1=nullptr, T *locationOnLine0=nullptr, T *locationOnLine1=nullptr)
Checks whether two given lines are overlapping up to some extend and determines some overlapping metr...
Definition: LineEvaluator.h:594
static LineMatchMap evaluateLineSegments(const std::unordered_map< Id, FiniteLineT2< T >> &linesGroundTruth, const std::unordered_map< Id, FiniteLineT2< T >> &linesEvaluation, const T perfectMatchAngleThreshold=NumericT< T >::deg2rad(2), const T perfectMatchPixelThreshold=T(2), const T matchAngleThreshold=NumericT< T >::deg2rad(5), const T matchCloseToLinePixelThreshold=T(3), const T partialMatchNonOverlappingPixelThreshold=T(25), const T complexMatchMaximalGapPixelThreshold=T(15))
Evaluates two sets of finite lines.
Definition: LineEvaluator.h:802
std::unordered_set< unsigned long long > Id64Set
Definition of a set holding a pair of ids.
Definition: LineEvaluator.h:347
This class implements an finite line in 2D space.
Definition: FiniteLine2.h:82
bool isValid() const
Returns whether this line has valid parameters.
Definition: FiniteLine2.h:622
bool isEqual(const FiniteLineT2< T > &line, const T &epsilon) const
Returns whether two lines are equal up to a specified epsilon.
Definition: FiniteLine2.h:628
T length() const
Returns the length of the finite line.
Definition: FiniteLine2.h:403
const VectorT2< T > & direction() const
Returns the direction of the line: normalized(point1() - point0())
Definition: FiniteLine2.h:381
const VectorT2< T > & point0() const
Returns the first end point of the line.
Definition: FiniteLine2.h:348
VectorT2< T > nearestPointOnInfiniteLine(const VectorT2< T > &point, T *outOfBoundaryDistance=nullptr, T *finiteLineLocation=nullptr) const
Returns the point on the infinite line (defined by this finite line) to an arbitrary given point.
Definition: FiniteLine2.h:475
const VectorT2< T > & point1() const
Returns the second end point of the line.
Definition: FiniteLine2.h:354
This class provides basic numeric functionalities.
Definition: Numeric.h:57
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_2()
Returns PI/2 which is equivalent to 90 degree.
Definition: Numeric.h:938
static T abs(const T value)
Returns the absolute value of a given value.
Definition: Numeric.h:1220
static T sqrt(const T value)
Returns the square root of a given value.
Definition: Numeric.h:1533
static T cos(const T value)
Returns the cosine of a given value.
Definition: Numeric.h:1584
static T acos(const T value)
Returns the arccosine of a given value.
Definition: Numeric.h:2907
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
This class implements a functionality to determine the union of individual segments.
Definition: SegmentUnion.h:39
const SegmentMap & segments() const
Returns the segments of this object.
Definition: SegmentUnion.h:570
T maximalGap() const
Returns the maximal gap between all successive segments.
Definition: SegmentUnion.h:537
SegmentUnion< T > intersection(const T &startPosition, const T &stopPosition) const
Returns the intersection of this union with a given range (an additional segment).
Definition: SegmentUnion.h:379
void addSegment(const T &startPosition, const T &stopPosition)
Adds a new segment to this union object.
Definition: SegmentUnion.h:109
T unionSize() const
Returns the sum of all segment sizes.
Definition: SegmentUnion.h:578
static void sortLowestToFront2(T &value0, T &value1)
Sorts two values so that the lowest value will finally be the first value.
Definition: base/Utilities.h:619
This class implements a vector with two elements.
Definition: Vector2.h:96
T distance(const VectorT2< T > &right) const
Returns the distance between this 2D position and a second 2D position.
Definition: Vector2.h:627
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition: Vector2.h:633
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition: base/Utilities.h:903
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition: base/Utilities.h:1089
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15