8#ifndef META_OCEAN_CV_ADVANCED_ADVANCED_MOTION_H
9#define META_OCEAN_CV_ADVANCED_ADVANCED_MOTION_H
44template <
typename TMetricInteger,
typename TMetricFloat>
class AdvancedMotion;
67template <
typename TMetricInteger = SumSquareDifferences,
typename TMetricFloat = AdvancedSumSquareDifferences>
101 template <
unsigned int tSize>
102 static bool trackPointsSubPixelMirroredBorder(
const Frame& previousFrame,
const Frame& currentFrame,
const Vectors2& previousPoints,
const Vectors2& roughPoints,
Vectors2& currentPoints,
const unsigned int maximalOffset,
const unsigned int coarsestLayerRadius,
const FramePyramid::DownsamplingMode downsamplingMode =
FramePyramid::DM_FILTER_14641,
const unsigned int subPixelIterations = 4u,
Worker* worker =
nullptr,
MetricResults* metricResults =
nullptr,
MetricResults* metricIdentityResults =
nullptr);
125 template <
unsigned int tSize>
151 template <
unsigned int tChannels,
unsigned int tSize>
172 template <
unsigned int tSize>
194 template <
unsigned int tSize>
220 template <
unsigned int tSize>
221 static bool trackArbitraryPointsBidirectionalSubPixelMirroredBorder(
const CV::FramePyramid& previousPyramid,
const CV::FramePyramid& nextPyramid,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError =
Scalar(0.9 * 0.9),
const SubRegion& previousSubRegion =
SubRegion(),
const unsigned int horizontalBins = 0u,
const unsigned int verticalBins = 0u,
const unsigned int strength = 30u,
Worker* worker =
nullptr,
const unsigned int trackingLayers = 1u);
248 template <
unsigned int tSize>
249 static bool trackArbitraryPointsBidirectionalSubPixelMirroredBorder(
const Frame& previousFrame,
const Frame& nextFrame,
const unsigned int maximalOffset,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError =
Scalar(0.9 * 0.9),
const SubRegion& previousSubRegion =
SubRegion(),
const unsigned int horizontalBins = 0u,
const unsigned int verticalBins = 0u,
const unsigned int strength = 30u,
const FramePyramid::DownsamplingMode downsamplingMode =
FramePyramid::DM_FILTER_14641,
Worker* worker =
nullptr,
const unsigned int trackingLayers = 1u);
270 template <
unsigned int tSize>
294 template <
unsigned int tChannels,
unsigned int tSize>
315 template <
unsigned int tSize>
338 template <
unsigned int tChannels,
unsigned int tSize>
361 template <
unsigned int tSize>
386 template <
unsigned int tChannels,
unsigned int tSize>
408 template <
unsigned int tSize>
409 static bool trackPointsBidirectionalSubPixelMirroredBorder(
const Frame& previousFrame,
const Frame& nextFrame,
const unsigned int maximalOffset,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError =
Scalar(0.9 * 0.9),
const FramePyramid::DownsamplingMode downsamplingMode =
FramePyramid::DM_FILTER_14641,
Worker* worker =
nullptr,
Indices32* validIndices =
nullptr,
const unsigned int subPixelIterations = 4u);
426 template <
unsigned int tSize>
451 template <
unsigned int tChannels,
unsigned int tPatchSize>
452 static Vector2 trackPointSubPixelMirroredBorder(
const uint8_t* frame0,
const uint8_t* frame1,
const unsigned int width0,
const unsigned int height0,
const unsigned int width1,
const unsigned int height1,
const unsigned int frame0PaddingElements,
const unsigned int frame1PaddingElements,
const Vector2& position0,
const unsigned int radiusX,
const unsigned int radiusY,
const Vector2& rough1 =
Vector2(
Numeric::maxValue(),
Numeric::maxValue()),
const unsigned int subPixelIterations = 4u, uint32_t* metricResult =
nullptr, uint32_t* metricIdentityResult =
nullptr);
476 template <
unsigned int tPatchSize>
477 static inline Vector2 trackPointSubPixelMirroredBorder(
const uint8_t* frame0,
const uint8_t* frame1,
const unsigned int channels,
const unsigned int width0,
const unsigned int height0,
const unsigned int width1,
const unsigned int height1,
const unsigned int frame0PaddingElements,
const unsigned int frame1PaddingElements,
const Vector2& position0,
const unsigned int radiusX,
const unsigned int radiusY,
const Vector2& rough1 =
Vector2(
Numeric::maxValue(),
Numeric::maxValue()),
const unsigned int subPixelIterations = 4u, uint32_t* metricResult =
nullptr, uint32_t* metricIdentityResult =
nullptr);
496 template <
unsigned int tChannels,
unsigned int tPatchSize>
497 static Vector2 trackPointBufferSubPixelMirroredBorder(
const uint8_t* buffer0,
const uint8_t* frame1,
const unsigned int width1,
const unsigned int height1,
const unsigned int frame1PaddingElements,
const Vector2& roughPosition1,
const unsigned int subPixelIterations, uint32_t* metricResult =
nullptr);
517 template <
unsigned int tSize>
518 static void trackPointsSubPixelMirroredBorderSubset(
const FramePyramid* previousPyramid,
const FramePyramid* nextPyramid,
const unsigned int numberLayers,
const Vectors2* previousPoints,
const Vectors2* roughNextPoints,
Vectors2* nextPoints,
const unsigned int coarsestLayerRadius,
const unsigned int subPixelIterations,
unsigned int* metricResults,
unsigned int* metricIdentityResults,
const unsigned int firstPoint,
const unsigned int numberPoints);
540 template <
unsigned int tChannels,
unsigned int tSize>
541 static void trackPointsSubPixelMirroredBorderSubset(
const FramePyramid* previousPyramid,
const FramePyramid* currentPyramid,
const unsigned int numberLayers,
const Vectors2* previousPoints,
const Vectors2* roughPoints,
Vectors2* currentPoints,
const unsigned int coarsestLayerRadius,
const unsigned int subPixelIterations,
unsigned int* metricResults,
unsigned int* metricIdentityResults,
const unsigned int firstPoint,
const unsigned int numberPoints);
544template <
typename TMetricInteger,
typename TMetricFloat>
545template <
unsigned int tSize>
546bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsSubPixelMirroredBorder(
const Frame& previousFrame,
const Frame& currentFrame,
const Vectors2& previousPoints,
const Vectors2& roughPoints,
Vectors2& currentPoints,
const unsigned int maximalOffset,
const unsigned int coarsestLayerRadius,
const FramePyramid::DownsamplingMode downsamplingMode,
const unsigned int subPixelIterations,
Worker* worker,
MetricResults* metricResults,
MetricResults* metricIdentityResults)
548 static_assert(tSize % 2u == 1u,
"Invalid image patch size, must be odd!");
549 static_assert(tSize >= 3u,
"Invalid image patch size, must be larger than 2!");
551 ocean_assert(previousFrame && currentFrame);
556 ocean_assert(previousPoints.size() == roughPoints.size());
558 ocean_assert(maximalOffset >= 1u);
559 ocean_assert(subPixelIterations >= 1u);
561 const unsigned int idealLayers =
FramePyramid::idealLayers(previousFrame.
width(), previousFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius);
562 ocean_assert(idealLayers >= 1u);
564 if (idealLayers == 0u)
569 const FramePyramid previousPyramid(previousFrame, downsamplingMode, idealLayers,
false , worker);
570 const FramePyramid currentPyramid(currentFrame, downsamplingMode, idealLayers,
false , worker);
572 return trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, currentPyramid, previousPoints, roughPoints, currentPoints, coarsestLayerRadius, subPixelIterations, worker, metricResults, metricIdentityResults);
575template <
typename TMetricInteger,
typename TMetricFloat>
576template <
unsigned int tSize>
577inline bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsSubPixelMirroredBorder(
const FramePyramid& previousPyramid,
const FramePyramid& currentPyramid,
const Vectors2& previousPoints,
const Vectors2& roughPoints,
Vectors2& currentPoints,
const unsigned int coarsestLayerRadius,
const unsigned int subPixelIterations,
Worker* worker,
MetricResults* metricResults,
MetricResults* metricIdentityResults)
579 static_assert(tSize % 2u == 1u,
"Invalid image patch size, must be odd!");
580 static_assert(tSize >= 3u,
"Invalid image patch size, must be larger than 2!");
585 ocean_assert(previousPoints.size() == roughPoints.size());
587 ocean_assert(subPixelIterations >= 1u);
590 const unsigned int numberLayers = min(min(previousPyramid.
layers(), currentPyramid.
layers()), idealLayers);
592 if (numberLayers == 0u)
597 currentPoints.resize(previousPoints.size());
601 metricResults->resize(previousPoints.size());
604 if (metricIdentityResults)
606 metricIdentityResults->resize(previousPoints.size());
611 worker->
executeFunction(
Worker::Function::createStatic(&AdvancedMotion::trackPointsSubPixelMirroredBorderSubset<tSize>, &previousPyramid, ¤tPyramid, numberLayers, &previousPoints, &roughPoints, ¤tPoints, coarsestLayerRadius, subPixelIterations, metricResults ? metricResults->data() :
nullptr, metricIdentityResults ? metricIdentityResults->data() :
nullptr, 0u, 0u), 0u, (
unsigned int)(previousPoints.size()));
615 trackPointsSubPixelMirroredBorderSubset<tSize>(&previousPyramid, ¤tPyramid, numberLayers, &previousPoints, &roughPoints, ¤tPoints, coarsestLayerRadius, subPixelIterations, metricResults ? metricResults->data() :
nullptr, metricIdentityResults ? metricIdentityResults->data() :
nullptr, 0u, (
unsigned int)(previousPoints.size()));
621template <
typename TMetricInteger,
typename TMetricFloat>
622template <
unsigned int tChannels,
unsigned int tSize>
623inline bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsSubPixelMirroredBorder(
const FramePyramid& previousPyramid,
const FramePyramid& currentPyramid,
const Vectors2& previousPoints,
const Vectors2& roughPoints,
Vectors2& currentPoints,
const unsigned int coarsestLayerRadius,
const unsigned int subPixelIterations,
Worker* worker,
MetricResults* metricResults,
MetricResults* metricIdentityResults)
625 static_assert(tSize % 2u == 1u,
"Invalid image patch size, must be odd!");
626 static_assert(tSize >= 3u,
"Invalid image patch size, must be larger than 2!");
634 ocean_assert(previousPoints.size() == roughPoints.size());
636 ocean_assert(subPixelIterations >= 1u);
639 const unsigned int numberLayers = min(min(previousPyramid.
layers(), currentPyramid.
layers()), idealLayers);
641 if (numberLayers == 0u)
646 currentPoints.resize(previousPoints.size());
650 metricResults->resize(previousPoints.size());
653 if (metricIdentityResults)
655 metricIdentityResults->resize(previousPoints.size());
660 worker->
executeFunction(
Worker::Function::createStatic(&AdvancedMotion::trackPointsSubPixelMirroredBorderSubset<tChannels, tSize>, &previousPyramid, ¤tPyramid, numberLayers, &previousPoints, &roughPoints, ¤tPoints, coarsestLayerRadius, subPixelIterations, metricResults ? metricResults->data() :
nullptr, metricIdentityResults ? metricIdentityResults->data() :
nullptr, 0u, 0u), 0u, (
unsigned int)(previousPoints.size()));
664 trackPointsSubPixelMirroredBorderSubset<tChannels, tSize>(&previousPyramid, ¤tPyramid, numberLayers, &previousPoints, &roughPoints, ¤tPoints, coarsestLayerRadius, subPixelIterations, metricResults ? metricResults->data() :
nullptr, metricIdentityResults ? metricIdentityResults->data() :
nullptr, 0u, (
unsigned int)(previousPoints.size()));
670template <
typename TMetricInteger,
typename TMetricFloat>
671template <
unsigned int tSize>
672bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackArbitraryPointsBidirectionalSubPixelMirroredBorder(
const CV::FramePyramid& previousPyramid,
const CV::FramePyramid& nextPyramid,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError,
const SubRegion& previousSubRegion,
const unsigned int horizontalBins,
const unsigned int verticalBins,
const unsigned int strength,
Worker* worker,
const unsigned int trackingLayers)
674 ocean_assert(previousPyramid && nextPyramid);
676 ocean_assert(previousImagePoints.empty() && nextImagePoints.empty());
683 const unsigned int maximalTrackingLayers = min(trackingLayers, min(previousPyramid.
layers(), nextPyramid.
layers()));
685 for (
unsigned int n = 0u; n < maximalTrackingLayers; ++n)
687 const Frame& previousLayer = previousPyramid[n];
689 if (previousLayer.
width() < tSize || previousLayer.
height() < tSize)
705 const Scalar layerFactor =
Scalar((
unsigned int)(1 << n));
716 unsigned int windowLeft, windowTop, windowWidth, windowHeight;
717 if (!boundingBox.
box2integer(yFrame.
width(), yFrame.
height(), windowLeft, windowTop, windowWidth, windowHeight))
722 ocean_assert(windowWidth >= 1u && windowWidth <= yFrame.
width());
723 ocean_assert(windowHeight >= 1u && windowHeight <= yFrame.
height());
732 if (n == 0u && corners.size() < 50)
742 if (n == 0u && corners.size() < 20)
760 if (previousSubRegion.
isEmpty())
762 cornersSubRegion = std::move(corners);
766 cornersSubRegion.reserve(corners.size());
768 for (Detector::HarrisCorners::const_iterator i = corners.begin(); i != corners.end(); ++i)
770 if (previousSubRegion.
isInside(i->observation() * layerFactor))
772 cornersSubRegion.push_back(*i);
777 if (cornersSubRegion.empty())
782 std::sort(cornersSubRegion.begin(), cornersSubRegion.end());
785 if (!smallPreviousImagePoints.empty() && horizontalBins != 0u && verticalBins != 0u)
790 if (smallPreviousImagePoints.empty())
802 if (trackPointsBidirectionalSubPixelMirroredBorder<tSize>(previousSmall, nextSmall, coarsestLayerRadius, smallPreviousImagePoints, smallNextImagePoints, maximalSqrError, worker))
804 for (
unsigned int i = 0u; i < smallPreviousImagePoints.size(); ++i)
806 previousImagePoints.push_back(smallPreviousImagePoints[i] * layerFactor);
807 nextImagePoints.push_back(smallNextImagePoints[i] * layerFactor);
815template <
typename TMetricInteger,
typename TMetricFloat>
816template <
unsigned int tSize>
817bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackArbitraryPointsBidirectionalSubPixelMirroredBorder(
const Frame& previousFrame,
const Frame& nextFrame,
const unsigned int maximalOffset,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError,
const SubRegion& previousSubRegion,
const unsigned int horizontalBins,
const unsigned int verticalBins,
const unsigned int strength,
const FramePyramid::DownsamplingMode downsamplingMode,
Worker* worker,
const unsigned int trackingLayers)
819 ocean_assert(previousFrame && nextFrame);
826 const unsigned int layers = min(trackingLayers,
FramePyramid::idealLayers(previousFrame.
width(), previousFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius));
833 const FramePyramid previousPyramid(previousFrame, downsamplingMode, layers,
false , worker);
834 const FramePyramid nextPyramid(nextFrame, downsamplingMode, layers,
false , worker);
836 return trackArbitraryPointsBidirectionalSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, coarsestLayerRadius, previousImagePoints, nextImagePoints, maximalSqrError, previousSubRegion, horizontalBins, verticalBins, strength, worker, trackingLayers);
839template <
typename TMetricInteger,
typename TMetricFloat>
840template <
unsigned int tSize>
843 ocean_assert(previousPyramid && nextPyramid);
845 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
846 ocean_assert(!validIndices || validIndices->empty());
848 if (previousImagePoints.empty())
858 Vectors2 previousPointCandidates(std::move(previousImagePoints));
859 ocean_assert(previousImagePoints.empty());
862 Vectors2 nextPointCandidates(previousPointCandidates.size());
863 if (!trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, previousPointCandidates, previousPointCandidates, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
869 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
870 if (!trackPointsSubPixelMirroredBorder<tSize>(nextPyramid, previousPyramid, nextPointCandidates, nextPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
875 ocean_assert(previousPointCandidates.size() == nextPointCandidates.size());
876 ocean_assert(previousPointCandidates.size() == backwardsPreviousPointCandidates.size());
879 previousImagePoints.reserve(previousPointCandidates.size());
881 nextImagePoints.clear();
882 nextImagePoints.reserve(previousPointCandidates.size());
884 if (validIndices !=
nullptr)
886 validIndices->clear();
887 validIndices->reserve(previousPointCandidates.size());
889 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
892 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
894 previousImagePoints.push_back(previousPointCandidates[n]);
895 nextImagePoints.push_back(nextImagePoint);
901 validIndices->push_back(
Index32(n));
908 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
914 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
918 previousImagePoints.push_back(previousPointCandidates[n]);
919 nextImagePoints.push_back(nextImagePoint);
925 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
930template <
typename TMetricInteger,
typename TMetricFloat>
931template <
unsigned int tChannels,
unsigned int tSize>
934 ocean_assert(previousPyramid && nextPyramid);
938 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
939 ocean_assert(!validIndices || validIndices->empty());
941 if (previousImagePoints.empty())
951 Vectors2 previousPointCandidates(std::move(previousImagePoints));
952 ocean_assert(previousImagePoints.empty());
955 Vectors2 nextPointCandidates(previousPointCandidates.size());
956 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(previousPyramid, nextPyramid, previousPointCandidates, previousPointCandidates, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
962 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
963 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(nextPyramid, previousPyramid, nextPointCandidates, nextPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
968 ocean_assert(previousPointCandidates.size() == nextPointCandidates.size());
969 ocean_assert(previousPointCandidates.size() == backwardsPreviousPointCandidates.size());
972 previousImagePoints.reserve(previousPointCandidates.size());
974 nextImagePoints.clear();
975 nextImagePoints.reserve(previousPointCandidates.size());
977 if (validIndices !=
nullptr)
979 validIndices->clear();
980 validIndices->reserve(previousPointCandidates.size());
982 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
985 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
987 previousImagePoints.push_back(previousPointCandidates[n]);
988 nextImagePoints.push_back(nextImagePoint);
993 validIndices->push_back(
Index32(n));
1000 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1006 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1010 previousImagePoints.push_back(previousPointCandidates[n]);
1011 nextImagePoints.push_back(nextImagePoint);
1017 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1022template <
typename TMetricInteger,
typename TMetricFloat>
1023template <
unsigned int tSize>
1026 ocean_assert(previousPyramid && nextPyramid);
1028 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1030 if (previousImagePoints.empty())
1041 if (!trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, previousImagePoints, previousImagePoints, nextImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1047 Vectors2 backwardsPreviousImagePoints(previousImagePoints.size());
1048 if (!trackPointsSubPixelMirroredBorder<tSize>(nextPyramid, previousPyramid, nextImagePoints, nextImagePoints, backwardsPreviousImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1053 validCorrespondences.assign(previousImagePoints.size(), uint8_t(0));
1055 for (
size_t n = 0; n < previousImagePoints.size(); ++n)
1057 const Vector2 forwardBackwardOffset = previousImagePoints[n] - backwardsPreviousImagePoints[n];
1065 const Vector2 nextImagePoint(nextImagePoints[n] + forwardBackwardOffset *
Scalar(0.5));
1069 nextImagePoints[n] = nextImagePoint;
1071 validCorrespondences[n] = uint8_t(1);
1076 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1081template <
typename TMetricInteger,
typename TMetricFloat>
1082template <
unsigned int tChannels,
unsigned int tSize>
1085 ocean_assert(previousPyramid && nextPyramid);
1089 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1091 if (previousImagePoints.empty())
1102 nextImagePoints.reserve(previousImagePoints.size());
1103 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(previousPyramid, nextPyramid, previousImagePoints, previousImagePoints, nextImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1109 Vectors2 backwardsPreviousImagePoints(previousImagePoints.size());
1110 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(nextPyramid, previousPyramid, nextImagePoints, nextImagePoints, backwardsPreviousImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1115 validCorrespondences.assign(previousImagePoints.size(), uint8_t(0));
1117 for (
size_t n = 0; n < previousImagePoints.size(); ++n)
1119 const Vector2 forwardBackwardOffset = previousImagePoints[n] - backwardsPreviousImagePoints[n];
1127 const Vector2 nextImagePoint(nextImagePoints[n] + forwardBackwardOffset *
Scalar(0.5));
1131 nextImagePoints[n] = nextImagePoint;
1133 validCorrespondences[n] = uint8_t(1);
1138 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1143template <
typename TMetricInteger,
typename TMetricFloat>
1144template <
unsigned int tSize>
1145bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsBidirectionalSubPixelMirroredBorderWithRoughLocations(
const CV::FramePyramid& previousPyramid,
const CV::FramePyramid& nextPyramid,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
const Vectors2& roughNextImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError,
Worker* worker,
Indices32* validIndices,
const unsigned int subPixelIterations)
1147 ocean_assert(previousPyramid && nextPyramid);
1150 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1151 ocean_assert(!validIndices || validIndices->empty());
1153 ocean_assert(&previousImagePoints != &roughNextImagePoints);
1155 if (previousImagePoints.empty())
1165 Vectors2 previousPointCandidates(std::move(previousImagePoints));
1166 ocean_assert(previousImagePoints.empty());
1169 Vectors2 nextPointCandidates(previousPointCandidates.size());
1170 if (!trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, previousPointCandidates, roughNextImagePoints, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1176 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
1177 if (!trackPointsSubPixelMirroredBorder<tSize>(nextPyramid, previousPyramid, nextPointCandidates, previousPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1183 previousImagePoints.reserve(previousPointCandidates.size());
1185 nextImagePoints.clear();
1186 nextImagePoints.reserve(previousPointCandidates.size());
1190 validIndices->clear();
1191 validIndices->reserve(previousPointCandidates.size());
1194 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1197 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1199 previousImagePoints.push_back(previousPointCandidates[n]);
1200 nextImagePoints.push_back(nextImagePoint);
1204 validIndices->push_back((
unsigned int)(n));
1211 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1217 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1221 previousImagePoints.push_back(previousPointCandidates[n]);
1222 nextImagePoints.push_back(nextImagePoint);
1228 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1233template <
typename TMetricInteger,
typename TMetricFloat>
1234template <
unsigned int tChannels,
unsigned int tSize>
1235bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsBidirectionalSubPixelMirroredBorderWithRoughLocations(
const CV::FramePyramid& previousPyramid,
const CV::FramePyramid& nextPyramid,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
const Vectors2& roughNextImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError,
Worker* worker,
Indices32* validIndices,
const unsigned int subPixelIterations)
1237 ocean_assert(previousPyramid && nextPyramid);
1243 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1244 ocean_assert(!validIndices || validIndices->empty());
1246 ocean_assert(&previousImagePoints != &roughNextImagePoints);
1248 if (previousImagePoints.empty())
1253 if (!previousPyramid
1262 Vectors2 previousPointCandidates(std::move(previousImagePoints));
1263 ocean_assert(previousImagePoints.empty());
1266 Vectors2 nextPointCandidates(previousPointCandidates.size());
1267 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(previousPyramid, nextPyramid, previousPointCandidates, roughNextImagePoints, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1273 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
1274 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(nextPyramid, previousPyramid, nextPointCandidates, previousPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1280 previousImagePoints.reserve(previousPointCandidates.size());
1282 nextImagePoints.clear();
1283 nextImagePoints.reserve(previousPointCandidates.size());
1287 validIndices->clear();
1288 validIndices->reserve(previousPointCandidates.size());
1291 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1294 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1296 previousImagePoints.push_back(previousPointCandidates[n]);
1297 nextImagePoints.push_back(nextImagePoint);
1301 validIndices->push_back((
unsigned int)(n));
1308 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1314 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1318 previousImagePoints.push_back(previousPointCandidates[n]);
1319 nextImagePoints.push_back(nextImagePoint);
1325 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1330template <
typename TMetricInteger,
typename TMetricFloat>
1331template <
unsigned int tSize>
1332bool AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsBidirectionalSubPixelMirroredBorder(
const Frame& previousFrame,
const Frame& nextFrame,
const unsigned int maximalOffset,
const unsigned int coarsestLayerRadius,
Vectors2& previousImagePoints,
Vectors2& nextImagePoints,
const Scalar maximalSqrError,
const FramePyramid::DownsamplingMode downsamplingMode,
Worker* worker,
Indices32* validIndices,
const unsigned int subPixelIterations)
1341 const unsigned int previousLayers =
FramePyramid::idealLayers(previousFrame.
width(), previousFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius);
1342 const unsigned int nextLayers =
FramePyramid::idealLayers(nextFrame.
width(), nextFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius);
1343 ocean_assert(previousLayers >= 1u && nextLayers >= 1u);
1345 const unsigned int layers = std::min(previousLayers, nextLayers);
1352 const FramePyramid previousPyramid(previousFrame, downsamplingMode, layers,
false , worker);
1353 const FramePyramid nextPyramid(nextFrame, downsamplingMode, layers,
false , worker);
1355 return trackPointsBidirectionalSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, coarsestLayerRadius, previousImagePoints, nextImagePoints, maximalSqrError, worker, validIndices, subPixelIterations);
1358template <
typename TMetricInteger,
typename TMetricFloat>
1359template <
unsigned int tSize>
1362 ocean_assert(previousReferencePoints.empty());
1363 ocean_assert(currentReferencePoints.empty());
1365 ocean_assert(&previousReferencePoints != ¤tReferencePoints);
1367 ocean_assert(horizontalBins >= 1u);
1368 ocean_assert(verticalBins >= 1u);
1372 const unsigned int width = previousFrame.
width();
1373 const unsigned int height = previousFrame.
height();
1375 const unsigned int areaLeft = boundingBox ? boundingBox.
left() : 0u;
1376 const unsigned int areaTop = boundingBox ? boundingBox.
top() : 0u;
1377 const unsigned int areaWidth = boundingBox ? boundingBox.
width() : width;
1378 const unsigned int areaHeight = boundingBox ? boundingBox.
height() : height;
1380 ocean_assert(areaLeft + areaWidth <= width);
1381 ocean_assert(areaTop + areaHeight <= height);
1386 features.reserve(5000);
1388 ocean_assert(!features.empty());
1390 if (features.empty())
1395 std::sort(features.begin(), features.end());
1400 const uint8_t*
const maskData = maskFrame ? maskFrame.
constdata<uint8_t>() :
nullptr;
1401 const unsigned int maskStrideElements = maskFrame ? maskFrame.
strideElements() : 0u;
1403 previousReferencePoints.reserve(distribution.
bins());
1404 for (
unsigned int n = 0u; n < distribution.
bins(); ++n)
1406 const Indices32& indices = distribution[n];
1408 if (!indices.empty())
1410 ocean_assert(indices.front() < allPreviousReferencePoints.size());
1411 const Vector2& point = allPreviousReferencePoints[indices.front()];
1413 const unsigned int xPosition = (
unsigned int)(point.
x());
1414 const unsigned int yPosition = (
unsigned int)(point.
y());
1416 ocean_assert(xPosition < width);
1417 ocean_assert(yPosition < height);
1419 if (maskData ==
nullptr || maskData[yPosition * maskStrideElements + xPosition] == 0xFFu)
1421 previousReferencePoints.push_back(point);
1426 if (previousReferencePoints.empty())
1431 return trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, currentPyramid, previousReferencePoints, previousReferencePoints, currentReferencePoints, 2u, 4u, worker);
1434template <
typename TMetricInteger,
typename TMetricFloat>
1435template <
unsigned int tChannels,
unsigned int tPatchSize>
1436Vector2 AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointSubPixelMirroredBorder(
const uint8_t* frame0,
const uint8_t* frame1,
const unsigned int width0,
const unsigned int height0,
const unsigned int width1,
const unsigned int height1,
const unsigned int frame0PaddingElements,
const unsigned int frame1PaddingElements,
const Vector2& position0,
const unsigned int radiusX,
const unsigned int radiusY,
const Vector2& rough1,
const unsigned int subPixelIterations, uint32_t* metricResult, uint32_t* metricIdentityResult)
1438 static_assert(tChannels != 0u,
"Invalid number of data channels!");
1439 static_assert(tPatchSize % 2u == 1u,
"Invalid size of the image patch, must be odd!");
1441 constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
1443 ocean_assert(frame0 !=
nullptr && frame1 !=
nullptr);
1445 ocean_assert(width0 >= tPatchSize && height0 >= tPatchSize);
1446 ocean_assert(width1 >= tPatchSize && height1 >= tPatchSize);
1448 ocean_assert(position0.
x() >=
Scalar(0) && position0.
x() <
Scalar(width0));
1449 ocean_assert(position0.
y() >=
Scalar(0) && position0.
y() <
Scalar(height0));
1453 const unsigned int leftCenter1 = (
unsigned int)(max(0,
int(position1.x() - radiusX)));
1454 const unsigned int topCenter1 = (
unsigned int)(max(0,
int(position1.y() - radiusY)));
1456 const unsigned int rightCenter1 = min(position1.x() + radiusX, width1 - 1u);
1457 const unsigned int bottomCenter1 = min(position1.y() + radiusY, height1 - 1u);
1461 uint8_t buffer0[tPatchSize * tPatchSize * tChannels];
1462 uint8_t buffer1[tPatchSize * tPatchSize * tChannels];
1464 const unsigned int x0 = (
unsigned int)(position0.
x());
1465 const unsigned int y0 = (
unsigned int)(position0.
y());
1467 if (x0 - tPatchSize_2 < width0 - tPatchSize && y0 - tPatchSize_2 < height0 - tPatchSize)
1469 ocean_assert(x0 >= tPatchSize_2 && x0 < width0 - (tPatchSize_2 + 1u) && y0 >= tPatchSize_2 && y0 < height0 - (tPatchSize_2 + 1u));
1470 AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize, PC_TOP_LEFT>(frame0, width0, frame0PaddingElements, buffer0, position0);
1474 ocean_assert(!(x0 >= tPatchSize_2 && x0 < width0 - (tPatchSize_2 + 1u) && y0 >= tPatchSize_2 && y0 < height0 - (tPatchSize_2 + 1u)));
1475 AdvancedFrameInterpolatorBilinear::interpolateSquareMirroredBorder8BitPerChannel<tChannels, tPatchSize>(frame0, width0, height0, frame0PaddingElements, buffer0, position0);
1479 uint32_t bestMetric = uint32_t(-1);
1480 unsigned int bestSqrDistance = (
unsigned int)(-1);
1482 for (
unsigned int y1 = topCenter1; y1 <= bottomCenter1; ++y1)
1484 for (
unsigned int x1 = leftCenter1; x1 <= rightCenter1; ++x1)
1486 uint32_t candidateMetric;
1488 if (x1 - tPatchSize_2 < width1 - tPatchSize && y1 - tPatchSize_2 < height1 - tPatchSize)
1490 candidateMetric = TMetricInteger::template patchBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, x1, y1, frame1PaddingElements, buffer0);
1494 constexpr unsigned int buffer1PaddingElements = 0u;
1496 FrameConverter::patchFrameMirroredBorder<uint8_t, tChannels>(frame1, buffer1, width1, height1, x1, y1, tPatchSize, frame1PaddingElements, buffer1PaddingElements);
1498 candidateMetric = TMetricInteger::template buffer8BitPerChannel<tChannels, tPatchSize * tPatchSize>(buffer0, buffer1);
1503 if (candidateMetric < bestMetric || (candidateMetric == bestMetric && position1.sqrDistance(position) < bestSqrDistance))
1505 bestMetric = candidateMetric;
1506 bestPosition = position;
1508 bestSqrDistance = position1.
sqrDistance(position);
1511 if (metricIdentityResult && x1 == position1.x() && y1 == position1.y())
1513 *metricIdentityResult = candidateMetric;
1518 ocean_assert(bestMetric != (
unsigned int)(-1) && bestPosition);
1520 ocean_assert(abs(
int(bestPosition.
x()) -
int(position1.x())) <=
int(radiusX));
1521 ocean_assert(abs(
int(bestPosition.
y()) -
int(position1.y())) <=
int(radiusY));
1525 *metricResult = bestMetric;
1528 return trackPointBufferSubPixelMirroredBorder<tChannels, tPatchSize>(buffer0, frame1, width1, height1, frame1PaddingElements,
Vector2(
Scalar(bestPosition.
x()),
Scalar(bestPosition.
y())), subPixelIterations, metricResult);
1531template <
typename TMetricInteger,
typename TMetricFloat>
1532template <
unsigned int tPatchSize>
1533inline Vector2 AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointSubPixelMirroredBorder(
const uint8_t* frame0,
const uint8_t* frame1,
const unsigned int channels,
const unsigned int width0,
const unsigned int height0,
const unsigned int width1,
const unsigned int height1,
const unsigned int frame0PaddingElements,
const unsigned int frame1PaddingElements,
const Vector2& position0,
const unsigned int radiusX,
const unsigned int radiusY,
const Vector2& rough1,
const unsigned int subPixelIterations, uint32_t* metricResult, uint32_t* metricIdentityResult)
1535 ocean_assert(channels >= 1u);
1540 return trackPointSubPixelMirroredBorder<1u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
1543 return trackPointSubPixelMirroredBorder<2u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
1546 return trackPointSubPixelMirroredBorder<3u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
1549 return trackPointSubPixelMirroredBorder<4u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
1552 ocean_assert(
false &&
"Invalid pixel format!");
1556template <
typename TMetricInteger,
typename TMetricFloat>
1557template <
unsigned int tChannels,
unsigned int tPatchSize>
1560 static_assert(tChannels >= 1u,
"Invalid number of data channels!");
1561 static_assert(tPatchSize % 2u == 1u,
"Invalid size of the image patch, must be odd!");
1563 ocean_assert(buffer0 !=
nullptr && frame1 !=
nullptr);
1565 ocean_assert(width1 >= tPatchSize && height1 >= tPatchSize);
1567 ocean_assert(roughPosition1.
x() >=
Scalar(0) && roughPosition1.
x() <
Scalar(width1));
1568 ocean_assert(roughPosition1.
y() >=
Scalar(0) && roughPosition1.
y() <
Scalar(height1));
1570 uint32_t metricBest = uint32_t(-1);
1572 if (metricResult !=
nullptr)
1574 metricBest = *metricResult;
1577 const bool result = metricBest == TMetricFloat::template patchMirroredBorderBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, height1, roughPosition1.
x(), roughPosition1.
y(), frame1PaddingElements, buffer0);
1578 ocean_assert_and_suppress_unused(result, result);
1583 const unsigned int x1 = (
unsigned int)(roughPosition1.
x());
1584 const unsigned int y1 = (
unsigned int)(roughPosition1.
y());
1586 if (x1 - (tPatchSize / 2u) < width1 - tPatchSize && y1 - (tPatchSize / 2u) < height1 - tPatchSize)
1588 ocean_assert(x1 >= (tPatchSize / 2u) && y1 >= (tPatchSize / 2u) && x1 < width1 - (tPatchSize / 2u + 1u) && y1 < height1 - (tPatchSize / 2u + 1u));
1589 metricBest = TMetricFloat::template patchBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, roughPosition1.
x(), roughPosition1.
y(), frame1PaddingElements, buffer0);
1593 ocean_assert(!(x1 >= (tPatchSize / 2u) && y1 >= (tPatchSize / 2u) && x1 < width1 - (tPatchSize / 2u + 1u) && y1 < height1 - (tPatchSize / 2u + 1u)));
1594 metricBest = TMetricFloat::template patchMirroredBorderBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, height1, roughPosition1.
x(), roughPosition1.
y(), frame1PaddingElements, buffer0);
1598 constexpr unsigned int numberSteps = 8u;
1600 const Vector2 steps[numberSteps] =
1613 Vector2 position1 = roughPosition1;
1615 for (
unsigned int n = 0u; n < subPixelIterations; ++n)
1617 Vector2 bestPosition1 = position1;
1621 for (
unsigned int i = 0u; i < numberSteps; ++i)
1623 const Vector2 candidatePosition1(position1.
x() + steps[i].
x() * offset, position1.
y() + steps[i].
y() * offset);
1625 if (candidatePosition1.
x() >=
Scalar(0) && candidatePosition1.
x() <
Scalar(width1) && candidatePosition1.
y() >=
Scalar(0) && candidatePosition1.
y() <
Scalar(height1))
1627 const unsigned int x1 = (
unsigned int)(candidatePosition1.
x());
1628 const unsigned int y1 = (
unsigned int)(candidatePosition1.
y());
1630 const uint32_t candidateMetric = (x1 - (tPatchSize / 2u) < width1 - tPatchSize && y1 - (tPatchSize / 2u) < height1 - tPatchSize) ?
1631 TMetricFloat::template patchBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, candidatePosition1.
x(), candidatePosition1.
y(), frame1PaddingElements, buffer0) :
1632 TMetricFloat::template patchMirroredBorderBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, height1, candidatePosition1.
x(), candidatePosition1.
y(), frame1PaddingElements, buffer0);
1634 if (candidateMetric < metricBest)
1636 metricBest = candidateMetric;
1637 bestPosition1 = candidatePosition1;
1643 position1 = bestPosition1;
1647 if (metricResult !=
nullptr)
1649 *metricResult = metricBest;
1652 ocean_assert(position1.
x() >= 0 && position1.
y() >= 0);
1653 ocean_assert(position1.
x() <
Scalar(width1) && position1.
y() <
Scalar(height1));
1658template <
typename TMetricInteger,
typename TMetricFloat>
1659template <
unsigned int tSize>
1660void AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsSubPixelMirroredBorderSubset(
const FramePyramid* previousPyramid,
const FramePyramid* nextPyramid,
const unsigned int numberLayers,
const Vectors2* previousPoints,
const Vectors2* roughNextPoints,
Vectors2* nextPoints,
const unsigned int coarsestLayerRadius,
const unsigned int subPixelIterations,
unsigned int* metricResults,
unsigned int* metricIdentityResults,
const unsigned int firstPoint,
const unsigned int numberPoints)
1662 static_assert(tSize % 2u == 1u,
"Invalid patch size, must be odd!");
1664 ocean_assert(previousPyramid !=
nullptr && nextPyramid !=
nullptr);
1665 ocean_assert(previousPoints !=
nullptr && nextPoints !=
nullptr);
1667 ocean_assert(previousPyramid->
isValid() && nextPyramid->
isValid());
1672 ocean_assert(roughNextPoints ==
nullptr || previousPoints->size() == roughNextPoints->size());
1673 ocean_assert(nextPoints->size() == previousPoints->size());
1675 ocean_assert(firstPoint + numberPoints <= previousPoints->size());
1677 ocean_assert(numberLayers >= 1u);
1678 ocean_assert(numberLayers <= previousPyramid->layers());
1679 ocean_assert(numberLayers <= nextPyramid->layers());
1681 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
width() >= tSize / 2u);
1682 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
height() >= tSize / 2u);
1689 ocean_assert(coarsetsWidthNextPyramid >= 1u && coarsetsHeightNextPyramid >= 1u);
1692 ocean_assert(channels >= 1u && channels <= 4u);
1694 for (
unsigned int n = firstPoint; n < firstPoint + numberPoints; ++n)
1696 const Vector2& roughNextPoint = roughNextPoints !=
nullptr ? (*roughNextPoints)[n] : (*previousPoints)[n];
1698 const Scalar x = min(roughNextPoint.
x() * coarsetsLayerFactorNextPyramid, coarsetsWidthNextPyramid -
Scalar(1));
1699 const Scalar y = min(roughNextPoint.
y() * coarsetsLayerFactorNextPyramid, coarsetsHeightNextPyramid -
Scalar(1));
1701 intermediateRoughNextPoints[n] =
Vector2(x, y);
1704 for (
unsigned int layerIndex = numberLayers - 1u; layerIndex < numberLayers; --layerIndex)
1706 const Frame& previousLayer = (*previousPyramid)[layerIndex];
1707 const Frame& nextLayer = (*nextPyramid)[layerIndex];
1709 const uint8_t*
const previousLayerData = previousLayer.
constdata<uint8_t>();
1710 const uint8_t*
const nextLayerData = nextLayer.
constdata<uint8_t>();
1712 const unsigned int previousLayerPaddingElements = previousLayer.
paddingElements();
1713 const unsigned int nextLayerPaddingElements = nextLayer.
paddingElements();
1715 const unsigned int previousLayerWidth = previousLayer.
width();
1716 const unsigned int previousLayerHeight = previousLayer.
height();
1718 const unsigned int nextLayerWidth = nextLayer.
width();
1719 const unsigned int nextLayerHeight = nextLayer.
height();
1721 if (layerIndex == 0u)
1725 const unsigned int layerRadiusX = numberLayers == 1u ? coarsestLayerRadius : 2u;
1726 const unsigned int layerRadiusY = numberLayers == 1u ? coarsestLayerRadius : 2u;
1728 for (
unsigned int pointIndex = firstPoint; pointIndex < firstPoint + numberPoints; ++pointIndex)
1730 const Vector2& previousPosition = (*previousPoints)[pointIndex];
1731 ocean_assert(previousPosition.
x() >=
Scalar(0) && previousPosition.
y() >=
Scalar(0));
1732 ocean_assert(previousPosition.
x() <
Scalar(previousLayerWidth) && previousPosition.
y() <
Scalar(previousLayerHeight));
1734 const Vector2& intermediateRoughNextPoint = intermediateRoughNextPoints[pointIndex];
1735 ocean_assert(intermediateRoughNextPoint.
x() >=
Scalar(0) && intermediateRoughNextPoint.
y() >=
Scalar(0));
1736 ocean_assert(intermediateRoughNextPoint.
x() <
Scalar(nextLayerWidth) && intermediateRoughNextPoint.
y() <
Scalar(nextLayerHeight));
1738 unsigned int*
const metricResult = metricResults ? metricResults + pointIndex :
nullptr;
1739 unsigned int*
const metricIdentityResult = metricIdentityResults ? metricIdentityResults + pointIndex :
nullptr;
1741 const Vector2 nextPoint = trackPointSubPixelMirroredBorder<tSize>(previousLayerData, nextLayerData, channels, previousLayerWidth, previousLayerHeight, nextLayerWidth, nextLayerHeight, previousLayerPaddingElements, nextLayerPaddingElements, previousPosition, layerRadiusX, layerRadiusY, intermediateRoughNextPoint, subPixelIterations, metricResult, metricIdentityResult);
1743 ocean_assert(nextPoint.
x() >= 0 && nextPoint.
x() <
Scalar(nextLayerWidth));
1744 ocean_assert(nextPoint.
y() >= 0 && nextPoint.
y() <
Scalar(nextLayerHeight));
1746 ocean_assert(pointIndex < nextPoints->size());
1747 (*nextPoints)[pointIndex] = nextPoint;
1752 ocean_assert(layerIndex > 0u);
1754 const unsigned int layerRadius = (layerIndex == numberLayers - 1u) ? coarsestLayerRadius : 2u;
1758 const Scalar finerNextLayerWidth1 =
Scalar((*nextPyramid)[layerIndex - 1u].width()) -
Scalar(1);
1759 const Scalar finerNextLayerHeight1 =
Scalar((*nextPyramid)[layerIndex - 1u].height()) -
Scalar(1);
1761 for (
unsigned int pointIndex = firstPoint; pointIndex < firstPoint + numberPoints; ++pointIndex)
1763 ocean_assert(intermediateRoughNextPoints[pointIndex].x() >=
Scalar(0) && intermediateRoughNextPoints[pointIndex].y() >=
Scalar(0));
1764 ocean_assert(intermediateRoughNextPoints[pointIndex].x() <
Scalar(nextLayerWidth) && intermediateRoughNextPoints[pointIndex].y() <
Scalar(nextLayerHeight));
1767 ocean_assert(intermediateRoughNextPoint.
x() < nextLayerWidth && intermediateRoughNextPoint.
y() < nextLayerHeight);
1769 unsigned int*
const metricResult = metricResults ? metricResults + pointIndex :
nullptr;
1771 const Vector2& previousPointFinestLayer = (*previousPoints)[pointIndex];
1773 const PixelPosition previousPoint(std::min(
Numeric::round32(previousPointFinestLayer.
x() * layerFactor),
int(previousLayerWidth - 1u)), std::min(
Numeric::round32(previousPointFinestLayer.
y() * layerFactor),
int(previousLayerHeight - 1u)));
1775 ocean_assert(previousPoint.
x() < previousLayerWidth && previousPoint.
y() < previousLayerHeight);
1776 if (previousPoint.
x() < previousLayerWidth && previousPoint.
y() < previousLayerHeight)
1778 const PixelPosition nextPoint =
Motion<TMetricInteger>::template pointMotionInFrameMirroredBorder<tSize>(previousLayerData, nextLayerData, channels, previousLayerWidth, previousLayerHeight, nextLayerWidth, nextLayerHeight, previousPoint, layerRadius, layerRadius, previousLayerPaddingElements, nextLayerPaddingElements, intermediateRoughNextPoint, metricResult);
1780 ocean_assert(nextPoint.
x() < nextLayerWidth && nextPoint.
y() < nextLayerHeight);
1782 intermediateRoughNextPoints[pointIndex] =
Vector2(min(
Scalar(nextPoint.
x() * 2u), finerNextLayerWidth1), min(
Scalar(nextPoint.
y() * 2u), finerNextLayerHeight1));
1784 ocean_assert(intermediateRoughNextPoints[pointIndex].x() >= 0 && intermediateRoughNextPoints[pointIndex].x() <= finerNextLayerWidth1);
1785 ocean_assert(intermediateRoughNextPoints[pointIndex].y() >= 0 && intermediateRoughNextPoints[pointIndex].y() <= finerNextLayerHeight1);
1789 ocean_assert(
false &&
"This should never happen!");
1791 intermediateRoughNextPoints[pointIndex] =
Vector2(previousPointFinestLayer.
x() * layerFactor *
Scalar(2), previousPointFinestLayer.
y() * layerFactor *
Scalar(2));
1793 ocean_assert(intermediateRoughNextPoints[pointIndex].x() >= 0 && intermediateRoughNextPoints[pointIndex].x() < finerNextLayerWidth1);
1794 ocean_assert(intermediateRoughNextPoints[pointIndex].y() >= 0 && intermediateRoughNextPoints[pointIndex].y() < finerNextLayerHeight1);
1801template <
typename TMetricInteger,
typename TMetricFloat>
1802template <
unsigned int tChannels,
unsigned int tSize>
1803void AdvancedMotion<TMetricInteger, TMetricFloat>::trackPointsSubPixelMirroredBorderSubset(
const FramePyramid* previousPyramid,
const FramePyramid* currentPyramid,
const unsigned int numberLayers,
const Vectors2* previousPoints,
const Vectors2* roughPoints,
Vectors2* currentPoints,
const unsigned int coarsestLayerRadius,
const unsigned int subPixelIterations,
unsigned int* metricResults,
unsigned int* metricIdentityResults,
const unsigned int firstPoint,
const unsigned int numberPoints)
1805 static_assert(tSize % 2u == 1u,
"Invalid patch size, must be odd!");
1807 ocean_assert(previousPyramid && currentPyramid);
1808 ocean_assert(previousPoints && roughPoints && currentPoints);
1810 ocean_assert(*previousPyramid && *currentPyramid);
1818 ocean_assert(previousPoints->size() == roughPoints->size());
1819 ocean_assert(currentPoints->size() == previousPoints->size());
1821 ocean_assert(firstPoint + numberPoints <= previousPoints->size());
1823 ocean_assert(numberLayers >= 1u);
1824 ocean_assert(numberLayers <= previousPyramid->layers());
1825 ocean_assert(numberLayers <= currentPyramid->layers());
1827 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
width() >= tSize / 2u);
1828 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
height() >= tSize / 2u);
1835 ocean_assert(lowestCurrentWidth >= 1u && lowestCurrentHeight >= 1u);
1838 ocean_assert_and_suppress_unused(channels >= 1u && channels <= 4u, channels);
1840 for (
unsigned int n = firstPoint; n < firstPoint + numberPoints; ++n)
1842 const Vector2& roughPoint = (*roughPoints)[n];
1844 const Scalar x = min(roughPoint.
x() * lowestLayerFactor, lowestCurrentWidth - 1);
1845 const Scalar y = min(roughPoint.
y() * lowestLayerFactor, lowestCurrentHeight - 1);
1847 intermediateRoughPoints[n] =
Vector2(x, y);
1850 for (
int l =
int(numberLayers) - 1; l >= 0; --l)
1852 const Frame previousFrame = (*previousPyramid)[l];
1853 const Frame currentFrame = (*currentPyramid)[l];
1855 const uint8_t*
const previousFrameData = previousFrame.
constdata<uint8_t>();
1856 const uint8_t*
const currentFrameData = currentFrame.
constdata<uint8_t>();
1858 const unsigned int previousFramePaddingElements = previousFrame.
paddingElements();
1859 const unsigned int currentFramePaddingElements = currentFrame.
paddingElements();
1861 const unsigned int previousWidth = previousFrame.
width();
1862 const unsigned int previousHeight = previousFrame.
height();
1864 const unsigned int currentWidth = currentFrame.
width();
1865 const unsigned int currentHeight = currentFrame.
height();
1870 const unsigned int layerRadiusX = numberLayers == 1u ? coarsestLayerRadius : 2u;
1871 const unsigned int layerRadiusY = numberLayers == 1u ? coarsestLayerRadius : 2u;
1873 for (
unsigned int i = firstPoint; i < firstPoint + numberPoints; ++i)
1875 ocean_assert(intermediateRoughPoints[i].x() >=
Scalar(0) && intermediateRoughPoints[i].y() >=
Scalar(0));
1876 ocean_assert(intermediateRoughPoints[i].x() <
Scalar(currentWidth) && intermediateRoughPoints[i].y() <
Scalar(currentHeight));
1878 const Vector2& intermediateRoughPoint = intermediateRoughPoints[i];
1880 unsigned int*
const metricResult = metricResults ? metricResults + i :
nullptr;
1881 unsigned int*
const metricIdentityResult = metricIdentityResults ? metricIdentityResults + i :
nullptr;
1883 const Vector2& previousPosition = (*previousPoints)[i];
1885 ocean_assert(previousPosition.
x() >=
Scalar(0) && previousPosition.
y() >=
Scalar(0));
1886 ocean_assert(previousPosition.
x() <
Scalar(previousWidth) && previousPosition.
y() <
Scalar(previousHeight));
1888 const Vector2 position(trackPointSubPixelMirroredBorder<tChannels, tSize>(previousFrameData, currentFrameData, previousWidth, previousHeight, currentWidth, currentHeight, previousFramePaddingElements, currentFramePaddingElements, previousPosition, layerRadiusX, layerRadiusY, intermediateRoughPoint, subPixelIterations, metricResult, metricIdentityResult));
1890 ocean_assert(position.
x() >= 0 && position.
x() <
Scalar(currentWidth));
1891 ocean_assert(position.
y() >= 0 && position.
y() <
Scalar(currentHeight));
1893 ocean_assert(i < currentPoints->size());
1894 (*currentPoints)[i] = position;
1899 ocean_assert(l > 0);
1901 const unsigned int layerRadiusX = (l == int(numberLayers) - 1) ? coarsestLayerRadius : 2u;
1902 const unsigned int layerRadiusY = (l == int(numberLayers) - 1) ? coarsestLayerRadius : 2u;
1904 for (
unsigned int i = firstPoint; i < firstPoint + numberPoints; ++i)
1906 ocean_assert(intermediateRoughPoints[i].x() >=
Scalar(0) && intermediateRoughPoints[i].y() >=
Scalar(0));
1907 ocean_assert(intermediateRoughPoints[i].x() <
Scalar(currentWidth) && intermediateRoughPoints[i].y() <
Scalar(currentHeight));
1911 unsigned int*
const metricResult = metricResults ? metricResults + i :
nullptr;
1915 min(
Numeric::round32((*previousPoints)[i].y() * layerFactor),
int(previousHeight) - 1));
1917 if (previousPosition.
x() < previousWidth && previousPosition.
y() < previousHeight)
1919 const PixelPosition position(
Motion<TMetricInteger>::template pointMotionInFrameMirroredBorder<tChannels, tSize>(previousFrameData, currentFrameData, previousWidth, previousHeight, currentWidth, currentHeight, previousPosition, layerRadiusX, layerRadiusY, previousFramePaddingElements, currentFramePaddingElements, intermediateRoughPoint, metricResult));
1921 ocean_assert(position.
x() < currentWidth && position.
y() < currentHeight);
1923 const Scalar higherWidth =
Scalar((*currentPyramid)[l - 1].width());
1924 const Scalar higherHeight =
Scalar((*currentPyramid)[l - 1].height());
1926 intermediateRoughPoints[i] =
Vector2(min(
Scalar(position.
x() * 2u), higherWidth - 1), min(
Scalar(position.
y() * 2u), higherHeight - 1));
1928 ocean_assert(intermediateRoughPoints[i].x() >= 0 && intermediateRoughPoints[i].x() <
Scalar(higherWidth));
1929 ocean_assert(intermediateRoughPoints[i].y() >= 0 && intermediateRoughPoints[i].y() <
Scalar(higherHeight));
1933 intermediateRoughPoints[i] =
Vector2((*previousPoints)[i].x() * layerFactor *
Scalar(2), (*previousPoints)[i].y() * layerFactor *
Scalar(2));
1935 ocean_assert(intermediateRoughPoints[i].x() >= 0 && intermediateRoughPoints[i].x() <
Scalar(currentFrame.
width() * 2u));
1936 ocean_assert(intermediateRoughPoints[i].y() >= 0 && intermediateRoughPoints[i].y() <
Scalar(currentFrame.
height() * 2u));
bool isValid() const
Returns whether the box holds valid parameters.
Definition Box2.h:769
bool box2integer(const int constraintLeft, const int constraintTop, const int constraintRight, const int constraintBottom, int &intersectionLeft, int &intersectionTop, unsigned int &intersectionWidth, unsigned int &intersectionHeight) const
Calculates the intersection of this bounding box (with floating point accuracy) and a second bounding...
Definition Box2.h:931
This class implements advanced motion techniques (mainly with sub-pixel accuracy or binary masks) all...
Definition AdvancedMotion.h:69
static bool trackPointsBidirectionalSubPixelMirroredBorder(const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid, const unsigned int coarsestLayerRadius, Vectors2 &previousImagePoints, Vectors2 &nextImagePoints, const Scalar maximalSqrError=Scalar(0.9 *0.9), Worker *worker=nullptr, Indices32 *validIndices=nullptr, const unsigned int subPixelIterations=4u)
Tracks a set of given points between two frame pyramids with sub-pixel accuracy.
Definition AdvancedMotion.h:841
static bool trackPointsSubPixelMirroredBorder(const Frame &previousFrame, const Frame ¤tFrame, const Vectors2 &previousPoints, const Vectors2 &roughPoints, Vectors2 ¤tPoints, const unsigned int maximalOffset, const unsigned int coarsestLayerRadius, const FramePyramid::DownsamplingMode downsamplingMode=FramePyramid::DM_FILTER_14641, const unsigned int subPixelIterations=4u, Worker *worker=nullptr, MetricResults *metricResults=nullptr, MetricResults *metricIdentityResults=nullptr)
Tracks a set of given points between two frames, with sub-pixel accuracy.
Definition AdvancedMotion.h:546
std::vector< uint32_t > MetricResults
Definition of a vector holding metric results.
Definition AdvancedMotion.h:75
static Vector2 trackPointSubPixelMirroredBorder(const uint8_t *frame0, const uint8_t *frame1, const unsigned int width0, const unsigned int height0, const unsigned int width1, const unsigned int height1, const unsigned int frame0PaddingElements, const unsigned int frame1PaddingElements, const Vector2 &position0, const unsigned int radiusX, const unsigned int radiusY, const Vector2 &rough1=Vector2(Numeric::maxValue(), Numeric::maxValue()), const unsigned int subPixelIterations=4u, uint32_t *metricResult=nullptr, uint32_t *metricIdentityResult=nullptr)
Tracks the location of one given 2D point from one image to another image with sub-pixel precision by...
Definition AdvancedMotion.h:1436
static bool trackArbitraryPointsBidirectionalSubPixelMirroredBorder(const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid, const unsigned int coarsestLayerRadius, Vectors2 &previousImagePoints, Vectors2 &nextImagePoints, const Scalar maximalSqrError=Scalar(0.9 *0.9), const SubRegion &previousSubRegion=SubRegion(), const unsigned int horizontalBins=0u, const unsigned int verticalBins=0u, const unsigned int strength=30u, Worker *worker=nullptr, const unsigned int trackingLayers=1u)
Tracks a set of arbitrary (unknown) points between two frame pyramids with sub-pixel accuracy.
Definition AdvancedMotion.h:672
static Vector2 trackPointBufferSubPixelMirroredBorder(const uint8_t *buffer0, const uint8_t *frame1, const unsigned int width1, const unsigned int height1, const unsigned int frame1PaddingElements, const Vector2 &roughPosition1, const unsigned int subPixelIterations, uint32_t *metricResult=nullptr)
Tracks the location of one given 2D point from one image to another image with sub-pixel precision by...
Definition AdvancedMotion.h:1558
static bool trackPointsBidirectionalSubPixelMirroredBorderWithRoughLocations(const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid, const unsigned int coarsestLayerRadius, Vectors2 &previousImagePoints, const Vectors2 &roughNextImagePoints, Vectors2 &nextImagePoints, const Scalar maximalSqrError=Scalar(0.9 *0.9), Worker *worker=nullptr, Indices32 *validIndices=nullptr, const unsigned int subPixelIterations=4u)
Tracks a set of given points between two frame pyramids with sub-pixel accuracy.
Definition AdvancedMotion.h:1145
static bool trackReliableReferencePoints(const FramePyramid &previousPyramid, const FramePyramid ¤tPyramid, Vectors2 &previousReferencePoints, Vectors2 ¤tReferencePoints, const unsigned int horizontalBins=16u, const unsigned int verticalBins=16u, const PixelBoundingBox &boundingBox=PixelBoundingBox(), const Frame &maskFrame=Frame(), Worker *worker=nullptr)
Detects and tracks reliable arbitrary reference points between two frames.
Definition AdvancedMotion.h:1360
static void trackPointsSubPixelMirroredBorderSubset(const FramePyramid *previousPyramid, const FramePyramid *nextPyramid, const unsigned int numberLayers, const Vectors2 *previousPoints, const Vectors2 *roughNextPoints, Vectors2 *nextPoints, const unsigned int coarsestLayerRadius, const unsigned int subPixelIterations, unsigned int *metricResults, unsigned int *metricIdentityResults, const unsigned int firstPoint, const unsigned int numberPoints)
Tracks a subset of given points between two frame pyramids with sub-pixel accuracy.
Definition AdvancedMotion.h:1660
static bool trackPointsSubPixelMask(const FramePyramid &previousPyramid, const FramePyramid ¤tPyramid, const FramePyramid &previousMaskPyramid, const FramePyramid ¤tMaskPyramid, const Vectors2 &previousPoints, const Vectors2 &roughCurrentPoints, Vectors2 ¤tPoints, const unsigned int coarsestLayerRadius, const unsigned int subPixelIterations=4u, Worker *worker=nullptr)
Tracks a set of given points between two frame pyramids with sub-pixel accuracy while each pyramid la...
static bool trackPointsMask(const FramePyramid &previousPyramid, const FramePyramid ¤tPyramid, const FramePyramid &previousMaskPyramid, const FramePyramid ¤tMaskPyramid, const PixelPositions &previousPoints, const PixelPositions &roughCurrentPoints, PixelPositions ¤tPoints, const unsigned int coarsestLayerRadius, Worker *worker=nullptr)
Tracks a set of given points between two frame pyramids with pixel accuracy while each pyramid layer ...
static bool detectCorners(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, const unsigned int threshold, const bool frameIsUndistorted, HarrisCorners &corners, const bool determineExactPosition=false, Worker *worker=nullptr)
Detects Harris corners inside a given 8 bit grayscale image.
Definition HarrisCornerDetector.h:397
static Geometry::ImagePoints corners2imagePoints(const HarrisCorners &corners)
Converts Harris corners to simple 2D image positions.
Definition HarrisCorner.h:110
static bool convert(const Frame &source, const FrameType::PixelFormat targetPixelFormat, const FrameType::PixelOrigin targetPixelOrigin, Frame &target, const bool forceCopy=true, Worker *worker=nullptr, const Options &options=Options())
Converts a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same d...
@ CP_AVOID_COPY_IF_POSSIBLE
Tries to avoid copying the frame data whenever possible.
Definition FrameConverter.h:96
This class implements a frame pyramid.
Definition FramePyramid.h:37
const Frame & finestLayer() const
Returns the finest layer frame of this pyramid.
Definition FramePyramid.h:735
static unsigned int idealLayers(const unsigned int width, const unsigned int height, const unsigned int invalidCoarsestWidthOrHeight, unsigned int *coarsestLayerWidth=nullptr, unsigned int *coarsestLayerHeight=nullptr)
Determines the number of layers until an invalid frame size would be reached in the next layer.
unsigned int finestWidth() const
Returns the width of the finest (first) layer.
Definition FramePyramid.h:778
bool isValid() const
Returns whether this pyramid holds at least one frame layer.
Definition FramePyramid.h:863
DownsamplingMode
Definition of individual down sampling modes.
Definition FramePyramid.h:44
@ DM_FILTER_14641
Down sampling is realized by a 5x5 Gaussian filter.
Definition FramePyramid.h:72
unsigned int layers() const
Returns the number of layers this pyramid holds.
Definition FramePyramid.h:761
const FrameType & frameType() const
Returns the frame type of the finest layer.
Definition FramePyramid.h:811
unsigned int finestHeight() const
Returns the height of the finest (first) layer.
Definition FramePyramid.h:784
static constexpr unsigned int sizeFactor(const unsigned int layer)
Returns the size factor of a specified layer in relation to the finest layer.
Definition FramePyramid.h:834
const Frame & layer(const unsigned int layer) const
Returns the frame of a specified layer.
Definition FramePyramid.h:723
This class implements patch-based motion techniques.
Definition Motion.h:59
T left() const
Returns the left (including) pixel position of this bounding box.
Definition PixelBoundingBox.h:416
unsigned int width() const
Returns the width (the number of horizontal including pixels) of this bounding box.
Definition PixelBoundingBox.h:482
T top() const
Returns the top (including) pixel position of this bounding box.
Definition PixelBoundingBox.h:423
unsigned int height() const
Returns the height (the number of vertical including pixels) of this bounding box.
Definition PixelBoundingBox.h:489
static PixelPositionT< unsigned int > vector2pixelPosition(const Vector2 &value)
Converts a 2D vector into a pixel position.
T y() const
Returns the vertical coordinate position of this object.
Definition PixelPosition.h:468
unsigned int sqrDistance(const PixelPositionT< T > &position) const
Returns the square difference between two pixel positions.
Definition PixelPosition.h:487
T x() const
Returns the horizontal coordinate position of this object.
Definition PixelPosition.h:456
This class implement a sub-region either defined by 2D triangles or defined by a binary mask.
Definition SubRegion.h:32
const Box2 & boundingBox() const
Returns the bounding box of this sub-region.
Definition SubRegion.h:218
bool isEmpty() const
Returns whether this sub-region is empty.
Definition SubRegion.h:223
bool isInside(const Vector2 &point) const
Returns whether a given point lies inside this sub-region.
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition Caller.h:2877
This class implements Ocean's image class.
Definition Frame.h:1808
unsigned int strideElements(const unsigned int planeIndex=0u) const
Returns the number of elements within one row, including optional padding at the end of a row for a s...
Definition Frame.h:4141
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:4251
const FrameType & frameType() const
Returns the frame type of this frame.
Definition Frame.h:3855
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4531
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition Frame.h:4125
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition Frame.h:594
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3170
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition Frame.h:3215
static bool arePixelFormatsCompatible(const PixelFormat pixelFormatA, const PixelFormat pixelFormatB)
Returns whether two given pixel formats are compatible.
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition Frame.h:3180
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3175
bool isPixelFormatCompatible(const PixelFormat pixelFormat) const
Returns whether the pixel format of this frame type is compatible with a given pixel format.
Definition Frame.h:3227
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3200
unsigned int bins() const
Returns the number of bins this distribution holds.
Definition SpatialDistribution.h:1088
This class implements a distribution array.
Definition SpatialDistribution.h:228
static DistributionArray distributeToArray(const ImagePoint *imagePoints, const size_t number, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int averagePointsPerBin, const unsigned int maxHorizontalBins, const unsigned int maxVerticalBins, unsigned int &horizontalBins, unsigned int &verticalBins)
Distributes the given 2D image points into a spatial array.
Definition SpatialDistribution.h:1685
static ImagePoints distributeAndFilter(const ImagePoint *imagePoints, const size_t numberImagePoints, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int horizontalBins, const unsigned int verticalBins)
Distributes the given image points into an array of specified size and returns (at most) one point fr...
Definition SpatialDistribution.h:1713
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition Numeric.h:2067
static constexpr T maxValue()
Returns the max scalar value.
Definition Numeric.h:3247
This class implements a vector with shifted elements.
Definition ShiftVector.h:27
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
T sqr() const
Returns the square of the vector length.
Definition Vector2.h:633
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition base/Utilities.h:1113
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
std::vector< PixelPosition > PixelPositions
Definition of a vector holding pixel positions (with positive coordinate values).
Definition PixelPosition.h:46
PixelBoundingBoxT< unsigned int > PixelBoundingBox
Definition of the default PixelBoundingBox object with data type allowing only positive coordinate va...
Definition PixelBoundingBox.h:28
std::vector< HarrisCorner > HarrisCorners
Definition of a vector holding Harris corners.
Definition HarrisCorner.h:30
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
BoxT2< Scalar > Box2
Definition of the Box2 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or...
Definition Box2.h:29
The namespace covering the entire Ocean framework.
Definition Accessor.h:15