8#ifndef META_OCEAN_CV_ADVANCED_ADVANCED_MOTION_H
9#define META_OCEAN_CV_ADVANCED_ADVANCED_MOTION_H
42template <
typename TMetricInteger,
typename TMetricFloat>
94 inline PointCorrespondences(
const Vector2* previousPoints,
Vector2* predictedNextPoints, uint8_t* validCorrespondences,
const size_t correspondences,
const unsigned int pyramidLayers,
const unsigned int coarsestLayerRadius,
const Scalar maximalError =
Scalar(0.9),
const unsigned int subPixelIterations = 4u);
128 inline const Vector2& previousPosition(
const size_t pointIndex)
const;
136 inline CV::PixelPosition previousPositionDownsampled(
const size_t pointIndex)
const;
144 inline CV::PixelPosition predictedNextPositionDownsampled(
const size_t pointIndex)
const;
152 inline const Vector2& predictedNextPosition(
const size_t pointIndex)
const;
179 inline bool isPointValid(
const size_t pointIndex)
const;
185 inline unsigned int pyramidLayers()
const;
191 inline unsigned int layerRadius()
const;
197 inline unsigned int subPixelIterations()
const;
203 inline size_t size()
const;
209 inline bool isValid()
const;
232 uint8_t* validCorrespondences_ =
nullptr;
235 size_t correspondences_ = 0;
238 unsigned int pyramidLayers_ = 0u;
241 unsigned int coarsestLayerRadius_ = 0u;
250 unsigned int subPixelIterations_ = 0u;
253 unsigned int layerIndex_ = (
unsigned int)(-1);
259 unsigned int coarsestLayerIndex_ = (
unsigned int)(-1);
262 unsigned int nextPyramidFinestLayerWidth_ = 0u;
265 unsigned int nextPyramidFinestLayerHeight_ = 0u;
268 unsigned int previousLayerWidth_ = 0u;
271 unsigned int previousLayerHeight_ = 0u;
274 unsigned int nextLayerWidth_ = 0u;
277 unsigned int nextLayerHeight_ = 0u;
280 unsigned int layerRadius_ = 0u;
283 bool forwardTracking_ =
true;
328 inline size_t measurements()
const;
334 inline bool isValid()
const;
345 unsigned int width_ = 0u;
348 unsigned int height_ = 0u;
354 size_t measurements_ = 0;
365template <
typename TMetricInteger = SumSquareDifferences,
typename TMetricFloat = AdvancedSumSquareDifferences>
385 template <
unsigned int tChannels,
unsigned int tSize>
409 template <
unsigned int tSize>
410 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);
432 template <
unsigned int tSize>
457 template <
unsigned int tChannels,
unsigned int tSize>
483 template <
unsigned int tSize>
484 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);
511 template <
unsigned int tSize>
512 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);
532 template <
unsigned int tSize>
555 template <
unsigned int tChannels,
unsigned int tSize>
575 template <
unsigned int tSize>
597 template <
unsigned int tChannels,
unsigned int tSize>
620 template <
unsigned int tSize>
645 template <
unsigned int tChannels,
unsigned int tSize>
667 template <
unsigned int tSize>
668 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);
685 template <
unsigned int tSize>
710 template <
unsigned int tChannels,
unsigned int tPatchSize>
711 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);
735 template <
unsigned int tPatchSize>
736 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);
755 template <
unsigned int tChannels,
unsigned int tPatchSize>
756 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);
776 template <
unsigned int tSize>
777 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);
799 template <
unsigned int tChannels,
unsigned int tSize>
800 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);
804 previousPoints_(previousPoints),
805 nextPoints_(predictedNextPoints),
806 validCorrespondences_(validCorrespondences),
807 correspondences_(correspondences),
808 pyramidLayers_(pyramidLayers),
809 coarsestLayerRadius_(coarsestLayerRadius),
810 subPixelIterations_(subPixelIterations)
820 ocean_assert(maximalError >= 0);
828 ocean_assert(layerIndex_ == 0u);
830 ocean_assert(pointIndex < correspondences_);
832 const Vector2& previousPoint = forwardTracking_ ? previousPoints_[pointIndex] : nextPoints_[pointIndex];
834 ocean_assert(previousPoint.
x() >=
Scalar(0) && previousPoint.
x() <
Scalar(previousLayerWidth_));
835 ocean_assert(previousPoint.
y() >=
Scalar(0) && previousPoint.
y() <
Scalar(previousLayerHeight_));
837 return previousPoint;
842 ocean_assert(layerIndex_ != (
unsigned int)(-1));
843 ocean_assert(layerIndex_ != 0u);
845 ocean_assert(pointIndex < correspondences_);
846 ocean_assert(invLayerFactor_ >
Scalar(0));
848 const Vector2& previousPoint = forwardTracking_ ? previousPoints_[pointIndex] : nextPoints_[pointIndex];
850 const int32_t downsampledX =
Numeric::round32(previousPoint.
x() * invLayerFactor_);
851 const int32_t downsampledY =
Numeric::round32(previousPoint.
y() * invLayerFactor_);
853 const int32_t clampedX = std::min(downsampledX, int32_t(previousLayerWidth_) - 1);
854 const int32_t clampedY = std::min(downsampledY, int32_t(previousLayerHeight_) - 1);
856 ocean_assert(clampedX >= 0 && clampedY >= 0);
863 ocean_assert(layerIndex_ != (
unsigned int)(-1));
864 ocean_assert(layerIndex_ != 0u);
866 ocean_assert(pointIndex < correspondences_);
868 const Vector2& predictedNextPoint = forwardTracking_ ? nextPoints_[pointIndex] : internalBackwardNextPoints_[pointIndex];
873 ocean_assert(predictedNextPoint.
x() >=
Scalar(0) && predictedNextPoint.
x() <
Scalar(nextLayerWidth_));
874 ocean_assert(predictedNextPoint.
y() >=
Scalar(0) && predictedNextPoint.
y() <
Scalar(nextLayerHeight_));
876 return CV::PixelPosition((
unsigned int)(predictedNextPoint.
x()), (
unsigned int)(predictedNextPoint.
y()));
881 ocean_assert(layerIndex_ == 0u);
883 ocean_assert(pointIndex < correspondences_);
885 if (forwardTracking_)
887 return nextPoints_[pointIndex];
891 return internalBackwardNextPoints_[pointIndex];
897 ocean_assert(layerIndex_ != (
unsigned int)(-1));
899 ocean_assert(pointIndex < correspondences_);
901 ocean_assert(validCorrespondences_ !=
nullptr);
902 return validCorrespondences_[pointIndex] != 0u;
907 ocean_assert(pyramidLayers_ != 0u);
909 return pyramidLayers_;
919 ocean_assert(layerIndex_ == 0u);
921 return subPixelIterations_;
926 return correspondences_;
931 return previousPoints_ !=
nullptr;
936 return measurements_;
941 return width_ >= 1u && height_ >= 1u;
944template <
typename TMetricInteger,
typename TMetricFloat>
945template <
unsigned int tChannels,
unsigned int tSize>
948 static_assert(tChannels >= 1u,
"Invalid channel number!");
949 static_assert(tSize >= 1u,
"Invalid patch size!");
951 ocean_assert(previousPyramid && nextPyramid);
972 ocean_assert(pointCorrespondenceGroups !=
nullptr && numberCorrespondenceGroups >= 1);
974 if (pointCorrespondenceGroups ==
nullptr || numberCorrespondenceGroups == 0)
981 ocean_assert(coarsestPyramidLayerIndex < previousPyramid.
layers());
982 ocean_assert(coarsestPyramidLayerIndex < nextPyramid.
layers());
986 for (
size_t nCorrespondenceGroup = 0; nCorrespondenceGroup < numberCorrespondenceGroups; ++nCorrespondenceGroup)
993 for (
unsigned int layerIndex = coarsestPyramidLayerIndex; layerIndex < previousPyramid.
layers(); --layerIndex)
995 for (
size_t nCorrespondenceGroup = 0; nCorrespondenceGroup < numberCorrespondenceGroups; ++nCorrespondenceGroup)
999 if (!correspondences.
startLayer(layerIndex, previousPyramid, nextPyramid))
1004 const Frame& previousFrame = previousPyramid[layerIndex];
1005 const Frame& nextFrame = nextPyramid[layerIndex];
1007 const uint8_t*
const previousFrameData = previousFrame.
constdata<uint8_t>();
1008 const uint8_t*
const nextFrameData = nextFrame.
constdata<uint8_t>();
1010 const unsigned int previousFramePaddingElements = previousFrame.
paddingElements();
1011 const unsigned int nextFramePaddingElements = nextFrame.
paddingElements();
1013 const unsigned int previousWidth = previousFrame.
width();
1014 const unsigned int previousHeight = previousFrame.
height();
1016 const unsigned int nextWidth = nextFrame.
width();
1017 const unsigned int nextHeight = nextFrame.
height();
1019 const unsigned int layerRadius = correspondences.
layerRadius();
1021 if (layerIndex == 0u)
1027 for (
size_t nPoint = 0; nPoint < correspondences.
size(); ++nPoint)
1032 const Vector2 position = trackPointSubPixelMirroredBorder<tChannels, tSize>(previousFrameData, nextFrameData, previousWidth, previousHeight, nextWidth, nextHeight, previousFramePaddingElements, nextFramePaddingElements, previousPosition, layerRadius, layerRadius, nextPosition, subPixelIterations);
1041 for (
size_t nPoint = 0; nPoint < correspondences.
size(); ++nPoint)
1046 const PixelPosition actualNextPoint =
MotionT<TMetricInteger>::template pointMotionInFrameMirroredBorder<tChannels, tSize>(previousFrameData, nextFrameData, previousWidth, previousHeight, nextWidth, nextHeight, previousPosition, layerRadius, layerRadius, previousFramePaddingElements, nextFramePaddingElements, predictedNextPosition);
1059 for (
size_t nCorrespondenceGroup = 0; nCorrespondenceGroup < numberCorrespondenceGroups; ++nCorrespondenceGroup)
1066 for (
unsigned int layerIndex = coarsestPyramidLayerIndex; layerIndex < previousPyramid.
layers(); --layerIndex)
1068 for (
size_t nCorrespondenceGroup = 0; nCorrespondenceGroup < numberCorrespondenceGroups; ++nCorrespondenceGroup)
1072 if (!correspondences.
startLayer(layerIndex, backwardPreviousPyramid, backwardNextPyramid))
1077 const Frame& previousFrame = backwardPreviousPyramid[layerIndex];
1078 const Frame& nextFrame = backwardNextPyramid[layerIndex];
1080 const uint8_t*
const previousFrameData = previousFrame.
constdata<uint8_t>();
1081 const uint8_t*
const nextFrameData = nextFrame.
constdata<uint8_t>();
1083 const unsigned int previousFramePaddingElements = previousFrame.
paddingElements();
1084 const unsigned int nextFramePaddingElements = nextFrame.
paddingElements();
1086 const unsigned int previousWidth = previousFrame.
width();
1087 const unsigned int previousHeight = previousFrame.
height();
1089 const unsigned int nextWidth = nextFrame.
width();
1090 const unsigned int nextHeight = nextFrame.
height();
1092 const unsigned int layerRadius = correspondences.
layerRadius();
1094 if (layerIndex == 0u)
1100 for (
size_t nPoint = 0; nPoint < correspondences.
size(); ++nPoint)
1107 const Vector2 position = trackPointSubPixelMirroredBorder<tChannels, tSize>(previousFrameData, nextFrameData, previousWidth, previousHeight, nextWidth, nextHeight, previousFramePaddingElements, nextFramePaddingElements, previousPosition, layerRadius, layerRadius, nextPosition, subPixelIterations);
1117 for (
size_t nPoint = 0; nPoint < correspondences.
size(); ++nPoint)
1124 const PixelPosition actualNextPoint =
MotionT<TMetricInteger>::template pointMotionInFrameMirroredBorder<tChannels, tSize>(previousFrameData, nextFrameData, previousWidth, previousHeight, nextWidth, nextHeight, previousPosition, layerRadius, layerRadius, previousFramePaddingElements, nextFramePaddingElements, predictedNextPosition);
1136template <
typename TMetricInteger,
typename TMetricFloat>
1137template <
unsigned int tSize>
1138bool AdvancedMotionT<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)
1140 static_assert(tSize % 2u == 1u,
"Invalid image patch size, must be odd!");
1141 static_assert(tSize >= 3u,
"Invalid image patch size, must be larger than 2!");
1143 ocean_assert(previousFrame && currentFrame);
1148 ocean_assert(previousPoints.size() == roughPoints.size());
1150 ocean_assert(maximalOffset >= 1u);
1151 ocean_assert(subPixelIterations >= 1u);
1153 const unsigned int idealLayers =
FramePyramid::idealLayers(previousFrame.
width(), previousFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius);
1154 ocean_assert(idealLayers >= 1u);
1156 if (idealLayers == 0u)
1161 const FramePyramid previousPyramid(previousFrame, downsamplingMode, idealLayers,
false , worker);
1162 const FramePyramid currentPyramid(currentFrame, downsamplingMode, idealLayers,
false , worker);
1164 return trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, currentPyramid, previousPoints, roughPoints, currentPoints, coarsestLayerRadius, subPixelIterations, worker, metricResults, metricIdentityResults);
1167template <
typename TMetricInteger,
typename TMetricFloat>
1168template <
unsigned int tSize>
1169inline bool AdvancedMotionT<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)
1171 static_assert(tSize % 2u == 1u,
"Invalid image patch size, must be odd!");
1172 static_assert(tSize >= 3u,
"Invalid image patch size, must be larger than 2!");
1177 ocean_assert(previousPoints.size() == roughPoints.size());
1179 ocean_assert(subPixelIterations >= 1u);
1182 const unsigned int numberLayers = min(min(previousPyramid.
layers(), currentPyramid.
layers()), idealLayers);
1184 if (numberLayers == 0u)
1189 currentPoints.resize(previousPoints.size());
1191 if (metricResults !=
nullptr)
1193 metricResults->resize(previousPoints.size());
1196 if (metricIdentityResults !=
nullptr)
1198 metricIdentityResults->resize(previousPoints.size());
1201 if (worker !=
nullptr)
1203 worker->
executeFunction(
Worker::Function::createStatic(&AdvancedMotionT::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()));
1207 trackPointsSubPixelMirroredBorderSubset<tSize>(&previousPyramid, ¤tPyramid, numberLayers, &previousPoints, &roughPoints, ¤tPoints, coarsestLayerRadius, subPixelIterations, metricResults ? metricResults->data() :
nullptr, metricIdentityResults ? metricIdentityResults->data() :
nullptr, 0u, (
unsigned int)(previousPoints.size()));
1213template <
typename TMetricInteger,
typename TMetricFloat>
1214template <
unsigned int tChannels,
unsigned int tSize>
1215inline bool AdvancedMotionT<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)
1217 static_assert(tSize % 2u == 1u,
"Invalid image patch size, must be odd!");
1218 static_assert(tSize >= 3u,
"Invalid image patch size, must be larger than 2!");
1226 ocean_assert(previousPoints.size() == roughPoints.size());
1228 ocean_assert(subPixelIterations >= 1u);
1231 const unsigned int numberLayers = min(min(previousPyramid.
layers(), currentPyramid.
layers()), idealLayers);
1233 if (numberLayers == 0u)
1238 currentPoints.resize(previousPoints.size());
1240 if (metricResults !=
nullptr)
1242 metricResults->resize(previousPoints.size());
1245 if (metricIdentityResults !=
nullptr)
1247 metricIdentityResults->resize(previousPoints.size());
1250 if (worker !=
nullptr)
1252 worker->
executeFunction(
Worker::Function::createStatic(&AdvancedMotionT::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()));
1256 trackPointsSubPixelMirroredBorderSubset<tChannels, tSize>(&previousPyramid, ¤tPyramid, numberLayers, &previousPoints, &roughPoints, ¤tPoints, coarsestLayerRadius, subPixelIterations, metricResults ? metricResults->data() :
nullptr, metricIdentityResults ? metricIdentityResults->data() :
nullptr, 0u, (
unsigned int)(previousPoints.size()));
1262template <
typename TMetricInteger,
typename TMetricFloat>
1263template <
unsigned int tSize>
1264bool AdvancedMotionT<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)
1266 ocean_assert(previousPyramid && nextPyramid);
1268 ocean_assert(previousImagePoints.empty() && nextImagePoints.empty());
1275 const unsigned int maximalTrackingLayers = min(trackingLayers, min(previousPyramid.
layers(), nextPyramid.
layers()));
1277 for (
unsigned int n = 0u; n < maximalTrackingLayers; ++n)
1279 const Frame& previousLayer = previousPyramid[n];
1281 if (previousLayer.
width() < tSize || previousLayer.
height() < tSize)
1292 if (yFrame.
width() == 0u || yFrame.
height() == 0u)
1297 const Scalar layerFactor =
Scalar((
unsigned int)(1 << n));
1308 unsigned int windowLeft, windowTop, windowWidth, windowHeight;
1309 if (!boundingBox.
box2integer(yFrame.
width(), yFrame.
height(), windowLeft, windowTop, windowWidth, windowHeight))
1314 ocean_assert(windowWidth >= 1u && windowWidth <= yFrame.
width());
1315 ocean_assert(windowHeight >= 1u && windowHeight <= yFrame.
height());
1324 if (n == 0u && corners.size() < 50)
1334 if (n == 0u && corners.size() < 20)
1343 if (corners.empty())
1352 if (previousSubRegion.
isEmpty())
1354 cornersSubRegion = std::move(corners);
1358 cornersSubRegion.reserve(corners.size());
1360 for (Detector::HarrisCorners::const_iterator i = corners.begin(); i != corners.end(); ++i)
1362 if (previousSubRegion.
isInside(i->observation() * layerFactor))
1364 cornersSubRegion.push_back(*i);
1369 if (cornersSubRegion.empty())
1374 std::sort(cornersSubRegion.begin(), cornersSubRegion.end());
1377 if (!smallPreviousImagePoints.empty() && horizontalBins != 0u && verticalBins != 0u)
1382 if (smallPreviousImagePoints.empty())
1394 if (trackPointsBidirectionalSubPixelMirroredBorder<tSize>(previousSmall, nextSmall, coarsestLayerRadius, smallPreviousImagePoints, smallNextImagePoints, maximalSqrError, worker))
1396 for (
unsigned int i = 0u; i < smallPreviousImagePoints.size(); ++i)
1398 previousImagePoints.push_back(smallPreviousImagePoints[i] * layerFactor);
1399 nextImagePoints.push_back(smallNextImagePoints[i] * layerFactor);
1407template <
typename TMetricInteger,
typename TMetricFloat>
1408template <
unsigned int tSize>
1409bool AdvancedMotionT<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)
1411 ocean_assert(previousFrame && nextFrame);
1418 const unsigned int layers = min(trackingLayers,
FramePyramid::idealLayers(previousFrame.
width(), previousFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius));
1425 const FramePyramid previousPyramid(previousFrame, downsamplingMode, layers,
false , worker);
1426 const FramePyramid nextPyramid(nextFrame, downsamplingMode, layers,
false , worker);
1428 return trackArbitraryPointsBidirectionalSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, coarsestLayerRadius, previousImagePoints, nextImagePoints, maximalSqrError, previousSubRegion, horizontalBins, verticalBins, strength, worker, trackingLayers);
1431template <
typename TMetricInteger,
typename TMetricFloat>
1432template <
unsigned int tSize>
1435 ocean_assert(previousPyramid && nextPyramid);
1437 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1438 ocean_assert(validIndices ==
nullptr || validIndices->empty());
1440 if (previousImagePoints.empty())
1450 Vectors2 previousPointCandidates(std::move(previousImagePoints));
1451 ocean_assert(previousImagePoints.empty());
1454 Vectors2 nextPointCandidates(previousPointCandidates.size());
1455 if (!trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, previousPointCandidates, previousPointCandidates, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1461 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
1462 if (!trackPointsSubPixelMirroredBorder<tSize>(nextPyramid, previousPyramid, nextPointCandidates, nextPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1467 ocean_assert(previousPointCandidates.size() == nextPointCandidates.size());
1468 ocean_assert(previousPointCandidates.size() == backwardsPreviousPointCandidates.size());
1471 previousImagePoints.reserve(previousPointCandidates.size());
1473 nextImagePoints.clear();
1474 nextImagePoints.reserve(previousPointCandidates.size());
1476 if (validIndices !=
nullptr)
1478 validIndices->clear();
1479 validIndices->reserve(previousPointCandidates.size());
1481 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1484 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1486 previousImagePoints.push_back(previousPointCandidates[n]);
1487 nextImagePoints.push_back(nextImagePoint);
1493 validIndices->push_back(
Index32(n));
1500 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1506 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1510 previousImagePoints.push_back(previousPointCandidates[n]);
1511 nextImagePoints.push_back(nextImagePoint);
1517 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1522template <
typename TMetricInteger,
typename TMetricFloat>
1523template <
unsigned int tChannels,
unsigned int tSize>
1526 ocean_assert(previousPyramid && nextPyramid);
1530 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1531 ocean_assert(validIndices ==
nullptr || validIndices->empty());
1533 if (previousImagePoints.empty())
1543 Vectors2 previousPointCandidates(std::move(previousImagePoints));
1544 ocean_assert(previousImagePoints.empty());
1547 Vectors2 nextPointCandidates(previousPointCandidates.size());
1548 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(previousPyramid, nextPyramid, previousPointCandidates, previousPointCandidates, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1554 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
1555 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(nextPyramid, previousPyramid, nextPointCandidates, nextPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1560 ocean_assert(previousPointCandidates.size() == nextPointCandidates.size());
1561 ocean_assert(previousPointCandidates.size() == backwardsPreviousPointCandidates.size());
1564 previousImagePoints.reserve(previousPointCandidates.size());
1566 nextImagePoints.clear();
1567 nextImagePoints.reserve(previousPointCandidates.size());
1569 if (validIndices !=
nullptr)
1571 validIndices->clear();
1572 validIndices->reserve(previousPointCandidates.size());
1574 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1577 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1579 previousImagePoints.push_back(previousPointCandidates[n]);
1580 nextImagePoints.push_back(nextImagePoint);
1585 validIndices->push_back(
Index32(n));
1592 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1598 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1602 previousImagePoints.push_back(previousPointCandidates[n]);
1603 nextImagePoints.push_back(nextImagePoint);
1609 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1614template <
typename TMetricInteger,
typename TMetricFloat>
1615template <
unsigned int tSize>
1618 ocean_assert(previousPyramid && nextPyramid);
1620 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1622 if (previousImagePoints.empty())
1633 if (!trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, previousImagePoints, previousImagePoints, nextImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1639 Vectors2 backwardsPreviousImagePoints(previousImagePoints.size());
1640 if (!trackPointsSubPixelMirroredBorder<tSize>(nextPyramid, previousPyramid, nextImagePoints, nextImagePoints, backwardsPreviousImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1645 validCorrespondences.assign(previousImagePoints.size(), uint8_t(0));
1647 for (
size_t n = 0; n < previousImagePoints.size(); ++n)
1649 const Vector2 forwardBackwardOffset = previousImagePoints[n] - backwardsPreviousImagePoints[n];
1657 const Vector2 nextImagePoint(nextImagePoints[n] + forwardBackwardOffset *
Scalar(0.5));
1661 nextImagePoints[n] = nextImagePoint;
1663 validCorrespondences[n] = uint8_t(1);
1668 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1673template <
typename TMetricInteger,
typename TMetricFloat>
1674template <
unsigned int tChannels,
unsigned int tSize>
1677 ocean_assert(previousPyramid && nextPyramid);
1681 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1683 if (previousImagePoints.empty())
1694 nextImagePoints.reserve(previousImagePoints.size());
1695 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(previousPyramid, nextPyramid, previousImagePoints, previousImagePoints, nextImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1701 Vectors2 backwardsPreviousImagePoints(previousImagePoints.size());
1702 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(nextPyramid, previousPyramid, nextImagePoints, nextImagePoints, backwardsPreviousImagePoints, coarsestLayerRadius, subPixelIterations, worker))
1707 validCorrespondences.assign(previousImagePoints.size(), uint8_t(0));
1709 for (
size_t n = 0; n < previousImagePoints.size(); ++n)
1711 const Vector2 forwardBackwardOffset = previousImagePoints[n] - backwardsPreviousImagePoints[n];
1719 const Vector2 nextImagePoint(nextImagePoints[n] + forwardBackwardOffset *
Scalar(0.5));
1723 nextImagePoints[n] = nextImagePoint;
1725 validCorrespondences[n] = uint8_t(1);
1730 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1735template <
typename TMetricInteger,
typename TMetricFloat>
1736template <
unsigned int tSize>
1737bool AdvancedMotionT<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)
1739 ocean_assert(previousPyramid && nextPyramid);
1742 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1743 ocean_assert(validIndices ==
nullptr || validIndices->empty());
1745 ocean_assert(&previousImagePoints != &roughNextImagePoints);
1747 if (previousImagePoints.empty())
1757 Vectors2 previousPointCandidates(std::move(previousImagePoints));
1758 ocean_assert(previousImagePoints.empty());
1761 Vectors2 nextPointCandidates(previousPointCandidates.size());
1762 if (!trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, previousPointCandidates, roughNextImagePoints, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1768 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
1769 if (!trackPointsSubPixelMirroredBorder<tSize>(nextPyramid, previousPyramid, nextPointCandidates, previousPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1775 previousImagePoints.reserve(previousPointCandidates.size());
1777 nextImagePoints.clear();
1778 nextImagePoints.reserve(previousPointCandidates.size());
1780 if (validIndices !=
nullptr)
1782 validIndices->clear();
1783 validIndices->reserve(previousPointCandidates.size());
1786 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1789 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1791 previousImagePoints.push_back(previousPointCandidates[n]);
1792 nextImagePoints.push_back(nextImagePoint);
1796 validIndices->push_back((
unsigned int)(n));
1803 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1809 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1813 previousImagePoints.push_back(previousPointCandidates[n]);
1814 nextImagePoints.push_back(nextImagePoint);
1820 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1825template <
typename TMetricInteger,
typename TMetricFloat>
1826template <
unsigned int tChannels,
unsigned int tSize>
1827bool AdvancedMotionT<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)
1829 ocean_assert(previousPyramid && nextPyramid);
1835 ocean_assert(!previousImagePoints.empty() && nextImagePoints.empty());
1836 ocean_assert(validIndices ==
nullptr || validIndices->empty());
1838 ocean_assert(&previousImagePoints != &roughNextImagePoints);
1840 if (previousImagePoints.empty())
1845 if (!previousPyramid
1854 Vectors2 previousPointCandidates(std::move(previousImagePoints));
1855 ocean_assert(previousImagePoints.empty());
1858 Vectors2 nextPointCandidates(previousPointCandidates.size());
1859 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(previousPyramid, nextPyramid, previousPointCandidates, roughNextImagePoints, nextPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1865 Vectors2 backwardsPreviousPointCandidates(previousPointCandidates.size());
1866 if (!trackPointsSubPixelMirroredBorder<tChannels, tSize>(nextPyramid, previousPyramid, nextPointCandidates, previousPointCandidates, backwardsPreviousPointCandidates, coarsestLayerRadius, subPixelIterations, worker))
1872 previousImagePoints.reserve(previousPointCandidates.size());
1874 nextImagePoints.clear();
1875 nextImagePoints.reserve(previousPointCandidates.size());
1877 if (validIndices !=
nullptr)
1879 validIndices->clear();
1880 validIndices->reserve(previousPointCandidates.size());
1883 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1886 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1888 previousImagePoints.push_back(previousPointCandidates[n]);
1889 nextImagePoints.push_back(nextImagePoint);
1893 validIndices->push_back((
unsigned int)(n));
1900 for (
size_t n = 0; n < previousPointCandidates.size(); ++n)
1906 const Vector2 nextImagePoint(nextPointCandidates[n] + (previousPointCandidates[n] - backwardsPreviousPointCandidates[n]) *
Scalar(0.5));
1910 previousImagePoints.push_back(previousPointCandidates[n]);
1911 nextImagePoints.push_back(nextImagePoint);
1917 ocean_assert(previousImagePoints.size() == nextImagePoints.size());
1922template <
typename TMetricInteger,
typename TMetricFloat>
1923template <
unsigned int tSize>
1924bool AdvancedMotionT<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)
1933 const unsigned int previousLayers =
FramePyramid::idealLayers(previousFrame.
width(), previousFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius);
1934 const unsigned int nextLayers =
FramePyramid::idealLayers(nextFrame.
width(), nextFrame.
height(), (tSize / 2u) * 4u, (tSize / 2u) * 4u, 2u, maximalOffset, coarsestLayerRadius);
1935 ocean_assert(previousLayers >= 1u && nextLayers >= 1u);
1937 const unsigned int layers = std::min(previousLayers, nextLayers);
1944 const FramePyramid previousPyramid(previousFrame, downsamplingMode, layers,
false , worker);
1945 const FramePyramid nextPyramid(nextFrame, downsamplingMode, layers,
false , worker);
1947 return trackPointsBidirectionalSubPixelMirroredBorder<tSize>(previousPyramid, nextPyramid, coarsestLayerRadius, previousImagePoints, nextImagePoints, maximalSqrError, worker, validIndices, subPixelIterations);
1950template <
typename TMetricInteger,
typename TMetricFloat>
1951template <
unsigned int tSize>
1954 ocean_assert(previousReferencePoints.empty());
1955 ocean_assert(currentReferencePoints.empty());
1957 ocean_assert(&previousReferencePoints != ¤tReferencePoints);
1959 ocean_assert(horizontalBins >= 1u);
1960 ocean_assert(verticalBins >= 1u);
1964 const unsigned int width = previousFrame.
width();
1965 const unsigned int height = previousFrame.
height();
1967 const unsigned int areaLeft = boundingBox ? boundingBox.
left() : 0u;
1968 const unsigned int areaTop = boundingBox ? boundingBox.
top() : 0u;
1969 const unsigned int areaWidth = boundingBox ? boundingBox.
width() : width;
1970 const unsigned int areaHeight = boundingBox ? boundingBox.
height() : height;
1972 ocean_assert(areaLeft + areaWidth <= width);
1973 ocean_assert(areaTop + areaHeight <= height);
1978 features.reserve(5000);
1980 ocean_assert(!features.empty());
1982 if (features.empty())
1987 std::sort(features.begin(), features.end());
1992 const uint8_t*
const maskData = maskFrame ? maskFrame.
constdata<uint8_t>() :
nullptr;
1993 const unsigned int maskStrideElements = maskFrame ? maskFrame.
strideElements() : 0u;
1995 previousReferencePoints.reserve(distribution.
bins());
1996 for (
unsigned int n = 0u; n < distribution.
bins(); ++n)
1998 const Indices32& indices = distribution[n];
2000 if (!indices.empty())
2002 ocean_assert(indices.front() < allPreviousReferencePoints.size());
2003 const Vector2& point = allPreviousReferencePoints[indices.front()];
2005 const unsigned int xPosition = (
unsigned int)(point.
x());
2006 const unsigned int yPosition = (
unsigned int)(point.
y());
2008 ocean_assert(xPosition < width);
2009 ocean_assert(yPosition < height);
2011 if (maskData ==
nullptr || maskData[yPosition * maskStrideElements + xPosition] == 0xFFu)
2013 previousReferencePoints.push_back(point);
2018 if (previousReferencePoints.empty())
2023 return trackPointsSubPixelMirroredBorder<tSize>(previousPyramid, currentPyramid, previousReferencePoints, previousReferencePoints, currentReferencePoints, 2u, 4u, worker);
2026template <
typename TMetricInteger,
typename TMetricFloat>
2027template <
unsigned int tChannels,
unsigned int tPatchSize>
2028Vector2 AdvancedMotionT<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)
2030 static_assert(tChannels != 0u,
"Invalid number of data channels!");
2031 static_assert(tPatchSize % 2u == 1u,
"Invalid size of the image patch, must be odd!");
2033 constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
2035 ocean_assert(frame0 !=
nullptr && frame1 !=
nullptr);
2037 ocean_assert(width0 >= tPatchSize && height0 >= tPatchSize);
2038 ocean_assert(width1 >= tPatchSize && height1 >= tPatchSize);
2040 ocean_assert(position0.
x() >=
Scalar(0) && position0.
x() <
Scalar(width0));
2041 ocean_assert(position0.
y() >=
Scalar(0) && position0.
y() <
Scalar(height0));
2045 const unsigned int leftCenter1 = (
unsigned int)(max(0,
int(position1.x() - radiusX)));
2046 const unsigned int topCenter1 = (
unsigned int)(max(0,
int(position1.y() - radiusY)));
2048 const unsigned int rightCenter1 = min(position1.x() + radiusX, width1 - 1u);
2049 const unsigned int bottomCenter1 = min(position1.y() + radiusY, height1 - 1u);
2053 uint8_t buffer0[tPatchSize * tPatchSize * tChannels];
2054 uint8_t buffer1[tPatchSize * tPatchSize * tChannels];
2056 const unsigned int x0 = (
unsigned int)(position0.
x());
2057 const unsigned int y0 = (
unsigned int)(position0.
y());
2059 if (x0 - tPatchSize_2 < width0 - tPatchSize && y0 - tPatchSize_2 < height0 - tPatchSize)
2061 ocean_assert(x0 >= tPatchSize_2 && x0 < width0 - (tPatchSize_2 + 1u) && y0 >= tPatchSize_2 && y0 < height0 - (tPatchSize_2 + 1u));
2062 AdvancedFrameInterpolatorBilinear::interpolateSquarePatch8BitPerChannel<tChannels, tPatchSize, PC_TOP_LEFT>(frame0, width0, frame0PaddingElements, buffer0, position0);
2066 ocean_assert(!(x0 >= tPatchSize_2 && x0 < width0 - (tPatchSize_2 + 1u) && y0 >= tPatchSize_2 && y0 < height0 - (tPatchSize_2 + 1u)));
2067 AdvancedFrameInterpolatorBilinear::interpolateSquareMirroredBorder8BitPerChannel<tChannels, tPatchSize>(frame0, width0, height0, frame0PaddingElements, buffer0, position0);
2071 uint32_t bestMetric = uint32_t(-1);
2072 unsigned int bestSqrDistance = (
unsigned int)(-1);
2074 for (
unsigned int y1 = topCenter1; y1 <= bottomCenter1; ++y1)
2076 for (
unsigned int x1 = leftCenter1; x1 <= rightCenter1; ++x1)
2078 uint32_t candidateMetric;
2080 if (x1 - tPatchSize_2 < width1 - tPatchSize && y1 - tPatchSize_2 < height1 - tPatchSize)
2082 candidateMetric = TMetricInteger::template patchBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, x1, y1, frame1PaddingElements, buffer0);
2086 constexpr unsigned int buffer1PaddingElements = 0u;
2088 FrameConverter::patchFrameMirroredBorder<uint8_t, tChannels>(frame1, buffer1, width1, height1, x1, y1, tPatchSize, frame1PaddingElements, buffer1PaddingElements);
2090 candidateMetric = TMetricInteger::template buffer8BitPerChannel<tChannels, tPatchSize * tPatchSize>(buffer0, buffer1);
2095 if (candidateMetric < bestMetric || (candidateMetric == bestMetric && position1.sqrDistance(position) < bestSqrDistance))
2097 bestMetric = candidateMetric;
2098 bestPosition = position;
2100 bestSqrDistance = position1.
sqrDistance(position);
2103 if (metricIdentityResult && x1 == position1.x() && y1 == position1.y())
2105 *metricIdentityResult = candidateMetric;
2110 ocean_assert(bestMetric != (
unsigned int)(-1) && bestPosition);
2112 ocean_assert(abs(
int(bestPosition.
x()) -
int(position1.x())) <=
int(radiusX));
2113 ocean_assert(abs(
int(bestPosition.
y()) -
int(position1.y())) <=
int(radiusY));
2117 *metricResult = bestMetric;
2120 return trackPointBufferSubPixelMirroredBorder<tChannels, tPatchSize>(buffer0, frame1, width1, height1, frame1PaddingElements,
Vector2(
Scalar(bestPosition.
x()),
Scalar(bestPosition.
y())), subPixelIterations, metricResult);
2123template <
typename TMetricInteger,
typename TMetricFloat>
2124template <
unsigned int tPatchSize>
2125inline Vector2 AdvancedMotionT<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)
2127 ocean_assert(channels >= 1u);
2132 return trackPointSubPixelMirroredBorder<1u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
2135 return trackPointSubPixelMirroredBorder<2u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
2138 return trackPointSubPixelMirroredBorder<3u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
2141 return trackPointSubPixelMirroredBorder<4u, tPatchSize>(frame0, frame1, width0, height0, width1, height1, frame0PaddingElements, frame1PaddingElements, position0, radiusX, radiusY, rough1, subPixelIterations, metricResult, metricIdentityResult);
2144 ocean_assert(
false &&
"Invalid pixel format!");
2148template <
typename TMetricInteger,
typename TMetricFloat>
2149template <
unsigned int tChannels,
unsigned int tPatchSize>
2152 static_assert(tChannels >= 1u,
"Invalid number of data channels!");
2153 static_assert(tPatchSize % 2u == 1u,
"Invalid size of the image patch, must be odd!");
2155 ocean_assert(buffer0 !=
nullptr && frame1 !=
nullptr);
2157 ocean_assert(width1 >= tPatchSize && height1 >= tPatchSize);
2159 ocean_assert(roughPosition1.
x() >=
Scalar(0) && roughPosition1.
x() <
Scalar(width1));
2160 ocean_assert(roughPosition1.
y() >=
Scalar(0) && roughPosition1.
y() <
Scalar(height1));
2162 uint32_t metricBest = uint32_t(-1);
2164 if (metricResult !=
nullptr)
2166 metricBest = *metricResult;
2169 const bool result = metricBest == TMetricFloat::template patchMirroredBorderBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, height1, roughPosition1.
x(), roughPosition1.
y(), frame1PaddingElements, buffer0);
2170 ocean_assert_and_suppress_unused(result, result);
2175 const unsigned int x1 = (
unsigned int)(roughPosition1.
x());
2176 const unsigned int y1 = (
unsigned int)(roughPosition1.
y());
2178 if (x1 - (tPatchSize / 2u) < width1 - tPatchSize && y1 - (tPatchSize / 2u) < height1 - tPatchSize)
2180 ocean_assert(x1 >= (tPatchSize / 2u) && y1 >= (tPatchSize / 2u) && x1 < width1 - (tPatchSize / 2u + 1u) && y1 < height1 - (tPatchSize / 2u + 1u));
2181 metricBest = TMetricFloat::template patchBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, roughPosition1.
x(), roughPosition1.
y(), frame1PaddingElements, buffer0);
2185 ocean_assert(!(x1 >= (tPatchSize / 2u) && y1 >= (tPatchSize / 2u) && x1 < width1 - (tPatchSize / 2u + 1u) && y1 < height1 - (tPatchSize / 2u + 1u)));
2186 metricBest = TMetricFloat::template patchMirroredBorderBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, height1, roughPosition1.
x(), roughPosition1.
y(), frame1PaddingElements, buffer0);
2190 constexpr unsigned int numberSteps = 8u;
2192 const Vector2 steps[numberSteps] =
2205 Vector2 position1 = roughPosition1;
2207 for (
unsigned int n = 0u; n < subPixelIterations; ++n)
2209 Vector2 bestPosition1 = position1;
2213 for (
unsigned int i = 0u; i < numberSteps; ++i)
2215 const Vector2 candidatePosition1(position1.
x() + steps[i].
x() * offset, position1.
y() + steps[i].
y() * offset);
2217 if (candidatePosition1.
x() >=
Scalar(0) && candidatePosition1.
x() <
Scalar(width1) && candidatePosition1.
y() >=
Scalar(0) && candidatePosition1.
y() <
Scalar(height1))
2219 const unsigned int x1 = (
unsigned int)(candidatePosition1.
x());
2220 const unsigned int y1 = (
unsigned int)(candidatePosition1.
y());
2222 const uint32_t candidateMetric = (x1 - (tPatchSize / 2u) < width1 - tPatchSize && y1 - (tPatchSize / 2u) < height1 - tPatchSize) ?
2223 TMetricFloat::template patchBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, candidatePosition1.
x(), candidatePosition1.
y(), frame1PaddingElements, buffer0) :
2224 TMetricFloat::template patchMirroredBorderBuffer8BitPerChannel<tChannels, tPatchSize>(frame1, width1, height1, candidatePosition1.
x(), candidatePosition1.
y(), frame1PaddingElements, buffer0);
2226 if (candidateMetric < metricBest)
2228 metricBest = candidateMetric;
2229 bestPosition1 = candidatePosition1;
2234 position1 = bestPosition1;
2238 if (metricResult !=
nullptr)
2240 *metricResult = metricBest;
2243 ocean_assert(position1.
x() >= 0 && position1.
y() >= 0);
2244 ocean_assert(position1.
x() <
Scalar(width1) && position1.
y() <
Scalar(height1));
2249template <
typename TMetricInteger,
typename TMetricFloat>
2250template <
unsigned int tSize>
2251void AdvancedMotionT<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)
2253 static_assert(tSize % 2u == 1u,
"Invalid patch size, must be odd!");
2255 ocean_assert(previousPyramid !=
nullptr && nextPyramid !=
nullptr);
2256 ocean_assert(previousPoints !=
nullptr && nextPoints !=
nullptr);
2258 ocean_assert(previousPyramid->
isValid() && nextPyramid->
isValid());
2263 ocean_assert(roughNextPoints ==
nullptr || previousPoints->size() == roughNextPoints->size());
2264 ocean_assert(nextPoints->size() == previousPoints->size());
2266 ocean_assert(firstPoint + numberPoints <= previousPoints->size());
2268 ocean_assert(numberLayers >= 1u);
2269 ocean_assert(numberLayers <= previousPyramid->layers());
2270 ocean_assert(numberLayers <= nextPyramid->layers());
2272 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
width() >= tSize / 2u);
2273 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
height() >= tSize / 2u);
2280 ocean_assert(coarsestWidthNextPyramid >= 1u && coarsestHeightNextPyramid >= 1u);
2283 ocean_assert(channels >= 1u && channels <= 4u);
2285 for (
unsigned int n = firstPoint; n < firstPoint + numberPoints; ++n)
2287 const Vector2& roughNextPoint = roughNextPoints !=
nullptr ? (*roughNextPoints)[n] : (*previousPoints)[n];
2289 const Scalar x = min(roughNextPoint.
x() * coarsestLayerFactorNextPyramid, coarsestWidthNextPyramid -
Scalar(1));
2290 const Scalar y = min(roughNextPoint.
y() * coarsestLayerFactorNextPyramid, coarsestHeightNextPyramid -
Scalar(1));
2292 intermediateRoughNextPoints[n] =
Vector2(x, y);
2295 for (
unsigned int layerIndex = numberLayers - 1u; layerIndex < numberLayers; --layerIndex)
2297 const Frame& previousLayer = (*previousPyramid)[layerIndex];
2298 const Frame& nextLayer = (*nextPyramid)[layerIndex];
2300 const uint8_t*
const previousLayerData = previousLayer.
constdata<uint8_t>();
2301 const uint8_t*
const nextLayerData = nextLayer.
constdata<uint8_t>();
2303 const unsigned int previousLayerPaddingElements = previousLayer.
paddingElements();
2304 const unsigned int nextLayerPaddingElements = nextLayer.
paddingElements();
2306 const unsigned int previousLayerWidth = previousLayer.
width();
2307 const unsigned int previousLayerHeight = previousLayer.
height();
2309 const unsigned int nextLayerWidth = nextLayer.
width();
2310 const unsigned int nextLayerHeight = nextLayer.
height();
2312 if (layerIndex == 0u)
2316 const unsigned int layerRadiusX = numberLayers == 1u ? coarsestLayerRadius : 2u;
2317 const unsigned int layerRadiusY = numberLayers == 1u ? coarsestLayerRadius : 2u;
2319 for (
unsigned int pointIndex = firstPoint; pointIndex < firstPoint + numberPoints; ++pointIndex)
2321 const Vector2& previousPosition = (*previousPoints)[pointIndex];
2322 ocean_assert(previousPosition.
x() >=
Scalar(0) && previousPosition.
y() >=
Scalar(0));
2323 ocean_assert(previousPosition.
x() <
Scalar(previousLayerWidth) && previousPosition.
y() <
Scalar(previousLayerHeight));
2325 const Vector2& intermediateRoughNextPoint = intermediateRoughNextPoints[pointIndex];
2326 ocean_assert(intermediateRoughNextPoint.
x() >=
Scalar(0) && intermediateRoughNextPoint.
y() >=
Scalar(0));
2327 ocean_assert(intermediateRoughNextPoint.
x() <
Scalar(nextLayerWidth) && intermediateRoughNextPoint.
y() <
Scalar(nextLayerHeight));
2329 unsigned int*
const metricResult = metricResults ? metricResults + pointIndex :
nullptr;
2330 unsigned int*
const metricIdentityResult = metricIdentityResults ? metricIdentityResults + pointIndex :
nullptr;
2332 const Vector2 nextPoint = trackPointSubPixelMirroredBorder<tSize>(previousLayerData, nextLayerData, channels, previousLayerWidth, previousLayerHeight, nextLayerWidth, nextLayerHeight, previousLayerPaddingElements, nextLayerPaddingElements, previousPosition, layerRadiusX, layerRadiusY, intermediateRoughNextPoint, subPixelIterations, metricResult, metricIdentityResult);
2334 ocean_assert(nextPoint.
x() >= 0 && nextPoint.
x() <
Scalar(nextLayerWidth));
2335 ocean_assert(nextPoint.
y() >= 0 && nextPoint.
y() <
Scalar(nextLayerHeight));
2337 ocean_assert(pointIndex < nextPoints->size());
2338 (*nextPoints)[pointIndex] = nextPoint;
2343 ocean_assert(layerIndex > 0u);
2345 const unsigned int layerRadius = (layerIndex == numberLayers - 1u) ? coarsestLayerRadius : 2u;
2349 const Scalar finerNextLayerWidth1 =
Scalar((*nextPyramid)[layerIndex - 1u].width()) -
Scalar(1);
2350 const Scalar finerNextLayerHeight1 =
Scalar((*nextPyramid)[layerIndex - 1u].height()) -
Scalar(1);
2352 for (
unsigned int pointIndex = firstPoint; pointIndex < firstPoint + numberPoints; ++pointIndex)
2354 ocean_assert(intermediateRoughNextPoints[pointIndex].x() >=
Scalar(0) && intermediateRoughNextPoints[pointIndex].y() >=
Scalar(0));
2355 ocean_assert(intermediateRoughNextPoints[pointIndex].x() <
Scalar(nextLayerWidth) && intermediateRoughNextPoints[pointIndex].y() <
Scalar(nextLayerHeight));
2358 ocean_assert(intermediateRoughNextPoint.
x() < nextLayerWidth && intermediateRoughNextPoint.
y() < nextLayerHeight);
2360 unsigned int*
const metricResult = metricResults ? metricResults + pointIndex :
nullptr;
2362 const Vector2& previousPointFinestLayer = (*previousPoints)[pointIndex];
2364 const PixelPosition previousPoint(std::min(
Numeric::round32(previousPointFinestLayer.
x() * layerFactor),
int(previousLayerWidth - 1u)), std::min(
Numeric::round32(previousPointFinestLayer.
y() * layerFactor),
int(previousLayerHeight - 1u)));
2366 ocean_assert(previousPoint.
x() < previousLayerWidth && previousPoint.
y() < previousLayerHeight);
2367 if (previousPoint.
x() < previousLayerWidth && previousPoint.
y() < previousLayerHeight)
2369 const PixelPosition nextPoint =
MotionT<TMetricInteger>::template pointMotionInFrameMirroredBorder<tSize>(previousLayerData, nextLayerData, channels, previousLayerWidth, previousLayerHeight, nextLayerWidth, nextLayerHeight, previousPoint, layerRadius, layerRadius, previousLayerPaddingElements, nextLayerPaddingElements, intermediateRoughNextPoint, metricResult);
2371 ocean_assert(nextPoint.
x() < nextLayerWidth && nextPoint.
y() < nextLayerHeight);
2373 intermediateRoughNextPoints[pointIndex] =
Vector2(min(
Scalar(nextPoint.
x() * 2u), finerNextLayerWidth1), min(
Scalar(nextPoint.
y() * 2u), finerNextLayerHeight1));
2375 ocean_assert(intermediateRoughNextPoints[pointIndex].x() >= 0 && intermediateRoughNextPoints[pointIndex].x() <= finerNextLayerWidth1);
2376 ocean_assert(intermediateRoughNextPoints[pointIndex].y() >= 0 && intermediateRoughNextPoints[pointIndex].y() <= finerNextLayerHeight1);
2380 ocean_assert(
false &&
"This should never happen!");
2382 intermediateRoughNextPoints[pointIndex] =
Vector2(previousPointFinestLayer.
x() * layerFactor *
Scalar(2), previousPointFinestLayer.
y() * layerFactor *
Scalar(2));
2384 ocean_assert(intermediateRoughNextPoints[pointIndex].x() >= 0 && intermediateRoughNextPoints[pointIndex].x() < finerNextLayerWidth1);
2385 ocean_assert(intermediateRoughNextPoints[pointIndex].y() >= 0 && intermediateRoughNextPoints[pointIndex].y() < finerNextLayerHeight1);
2392template <
typename TMetricInteger,
typename TMetricFloat>
2393template <
unsigned int tChannels,
unsigned int tSize>
2394void AdvancedMotionT<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)
2396 static_assert(tSize % 2u == 1u,
"Invalid patch size, must be odd!");
2398 ocean_assert(previousPyramid && currentPyramid);
2399 ocean_assert(previousPoints && roughPoints && currentPoints);
2401 ocean_assert(*previousPyramid && *currentPyramid);
2409 ocean_assert(previousPoints->size() == roughPoints->size());
2410 ocean_assert(currentPoints->size() == previousPoints->size());
2412 ocean_assert(firstPoint + numberPoints <= previousPoints->size());
2414 ocean_assert(numberLayers >= 1u);
2415 ocean_assert(numberLayers <= previousPyramid->layers());
2416 ocean_assert(numberLayers <= currentPyramid->layers());
2418 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
width() >= tSize / 2u);
2419 ocean_assert(previousPyramid->
layer(numberLayers - 1u).
height() >= tSize / 2u);
2426 ocean_assert(lowestCurrentWidth >= 1u && lowestCurrentHeight >= 1u);
2429 ocean_assert_and_suppress_unused(channels >= 1u && channels <= 4u, channels);
2431 for (
unsigned int n = firstPoint; n < firstPoint + numberPoints; ++n)
2433 const Vector2& roughPoint = (*roughPoints)[n];
2435 const Scalar x = min(roughPoint.
x() * lowestLayerFactor, lowestCurrentWidth - 1);
2436 const Scalar y = min(roughPoint.
y() * lowestLayerFactor, lowestCurrentHeight - 1);
2438 intermediateRoughPoints[n] =
Vector2(x, y);
2441 for (
int layerIndex =
int(numberLayers) - 1; layerIndex >= 0; --layerIndex)
2443 const Frame& previousFrame = (*previousPyramid)[layerIndex];
2444 const Frame& currentFrame = (*currentPyramid)[layerIndex];
2446 const uint8_t*
const previousFrameData = previousFrame.
constdata<uint8_t>();
2447 const uint8_t*
const currentFrameData = currentFrame.
constdata<uint8_t>();
2449 const unsigned int previousFramePaddingElements = previousFrame.
paddingElements();
2450 const unsigned int currentFramePaddingElements = currentFrame.
paddingElements();
2452 const unsigned int previousWidth = previousFrame.
width();
2453 const unsigned int previousHeight = previousFrame.
height();
2455 const unsigned int currentWidth = currentFrame.
width();
2456 const unsigned int currentHeight = currentFrame.
height();
2459 if (layerIndex == 0)
2461 const unsigned int layerRadiusX = numberLayers == 1u ? coarsestLayerRadius : 2u;
2462 const unsigned int layerRadiusY = numberLayers == 1u ? coarsestLayerRadius : 2u;
2464 for (
unsigned int i = firstPoint; i < firstPoint + numberPoints; ++i)
2466 ocean_assert(intermediateRoughPoints[i].x() >=
Scalar(0) && intermediateRoughPoints[i].y() >=
Scalar(0));
2467 ocean_assert(intermediateRoughPoints[i].x() <
Scalar(currentWidth) && intermediateRoughPoints[i].y() <
Scalar(currentHeight));
2469 const Vector2& intermediateRoughPoint = intermediateRoughPoints[i];
2471 unsigned int*
const metricResult = metricResults ? metricResults + i :
nullptr;
2472 unsigned int*
const metricIdentityResult = metricIdentityResults ? metricIdentityResults + i :
nullptr;
2474 const Vector2& previousPosition = (*previousPoints)[i];
2476 ocean_assert(previousPosition.
x() >=
Scalar(0) && previousPosition.
y() >=
Scalar(0));
2477 ocean_assert(previousPosition.
x() <
Scalar(previousWidth) && previousPosition.
y() <
Scalar(previousHeight));
2479 const Vector2 position(trackPointSubPixelMirroredBorder<tChannels, tSize>(previousFrameData, currentFrameData, previousWidth, previousHeight, currentWidth, currentHeight, previousFramePaddingElements, currentFramePaddingElements, previousPosition, layerRadiusX, layerRadiusY, intermediateRoughPoint, subPixelIterations, metricResult, metricIdentityResult));
2481 ocean_assert(position.
x() >= 0 && position.
x() <
Scalar(currentWidth));
2482 ocean_assert(position.
y() >= 0 && position.
y() <
Scalar(currentHeight));
2484 ocean_assert(i < currentPoints->size());
2485 (*currentPoints)[i] = position;
2490 ocean_assert(layerIndex > 0);
2492 const unsigned int layerRadiusX = (layerIndex == int(numberLayers) - 1) ? coarsestLayerRadius : 2u;
2493 const unsigned int layerRadiusY = (layerIndex == int(numberLayers) - 1) ? coarsestLayerRadius : 2u;
2495 for (
unsigned int i = firstPoint; i < firstPoint + numberPoints; ++i)
2497 ocean_assert(intermediateRoughPoints[i].x() >=
Scalar(0) && intermediateRoughPoints[i].y() >=
Scalar(0));
2498 ocean_assert(intermediateRoughPoints[i].x() <
Scalar(currentWidth) && intermediateRoughPoints[i].y() <
Scalar(currentHeight));
2502 unsigned int*
const metricResult = metricResults ? metricResults + i :
nullptr;
2506 min(
Numeric::round32((*previousPoints)[i].y() * layerFactor),
int(previousHeight) - 1));
2508 if (previousPosition.
x() < previousWidth && previousPosition.
y() < previousHeight)
2510 const PixelPosition position(
MotionT<TMetricInteger>::template pointMotionInFrameMirroredBorder<tChannels, tSize>(previousFrameData, currentFrameData, previousWidth, previousHeight, currentWidth, currentHeight, previousPosition, layerRadiusX, layerRadiusY, previousFramePaddingElements, currentFramePaddingElements, intermediateRoughPoint, metricResult));
2512 ocean_assert(position.
x() < currentWidth && position.
y() < currentHeight);
2514 const Scalar higherWidth =
Scalar((*currentPyramid)[layerIndex - 1].width());
2515 const Scalar higherHeight =
Scalar((*currentPyramid)[layerIndex - 1].height());
2517 intermediateRoughPoints[i] =
Vector2(min(
Scalar(position.
x() * 2u), higherWidth - 1), min(
Scalar(position.
y() * 2u), higherHeight - 1));
2519 ocean_assert(intermediateRoughPoints[i].x() >= 0 && intermediateRoughPoints[i].x() <
Scalar(higherWidth));
2520 ocean_assert(intermediateRoughPoints[i].y() >= 0 && intermediateRoughPoints[i].y() <
Scalar(higherHeight));
2524 intermediateRoughPoints[i] =
Vector2((*previousPoints)[i].x() * layerFactor *
Scalar(2), (*previousPoints)[i].y() * layerFactor *
Scalar(2));
2526 ocean_assert(intermediateRoughPoints[i].x() >= 0 && intermediateRoughPoints[i].x() <
Scalar(currentFrame.
width() * 2u));
2527 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:761
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:923
This class manages point correspondences for bidirectional tracking across pyramid layers.
Definition AdvancedMotion.h:74
unsigned int subPixelIterations() const
Returns the number of sub-pixel iterations to be applied at the finest pyramid layer.
Definition AdvancedMotion.h:917
bool isPointValid(const size_t pointIndex) const
Returns whether a specific point correspondence is still valid.
Definition AdvancedMotion.h:895
CV::PixelPosition previousPositionDownsampled(const size_t pointIndex) const
Returns the previous image point position downsampled to the current pyramid layer.
Definition AdvancedMotion.h:840
PointCorrespondences()=default
Creates an invalid point correspondences object.
Scalar maximalSqrError_
The squared maximum error threshold for bidirectional tracking validation.
Definition AdvancedMotion.h:244
unsigned int pyramidLayers() const
Returns the number of pyramid layers to be used for tracking.
Definition AdvancedMotion.h:905
size_t size() const
Returns the number of point correspondences.
Definition AdvancedMotion.h:924
const Vector2 & predictedNextPosition(const size_t pointIndex) const
Returns the predicted next image point position at the finest pyramid layer.
Definition AdvancedMotion.h:879
void propagateNextPositionDownsampled(const size_t pointIndex, const CV::PixelPosition &nextPoint)
Propagates the next point position from the current pyramid layer to the finer layer below.
void startForwardTracking(const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid)
Initializes the forward tracking from the previous pyramid to the next pyramid.
unsigned int pyramidLayers_
The number of pyramid layers to use for tracking.
Definition AdvancedMotion.h:238
const Vector2 * previousPoints_
The image points in the previous pyramid, always at finest layer resolution.
Definition AdvancedMotion.h:226
Scalar maximalSqrErrorLayer_
The squared maximum error threshold used during layer processing (includes search radius)
Definition AdvancedMotion.h:247
uint8_t * validCorrespondences_
Binary validity flags for each correspondence (0x00 = invalid, 0x01 = valid)
Definition AdvancedMotion.h:232
void startBackwardTracking(const CV::FramePyramid &, const CV::FramePyramid &nextPyramid)
Initializes the backward tracking from the next pyramid back to the previous pyramid.
CV::PixelPosition predictedNextPositionDownsampled(const size_t pointIndex) const
Returns the predicted next image point position downsampled to the current pyramid layer.
Definition AdvancedMotion.h:861
static unsigned int coarsestPyramidLayer(const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid, const PointCorrespondences *pointCorrespondenceGroups, const size_t numberCorrespondenceGroups)
Determines the coarsest pyramid layer index across multiple correspondence groups.
const Vector2 & previousPosition(const size_t pointIndex) const
Returns the previous image point position at the finest pyramid layer.
Definition AdvancedMotion.h:826
Vectors2 internalBackwardNextPoints_
Internal storage for backward tracking results used for bidirectional validation.
Definition AdvancedMotion.h:286
void propagateNextPosition(const size_t pointIndex, const Vector2 &nextPoint)
Propagates the final next point position at the finest pyramid layer.
bool isValid() const
Returns whether this object holds valid parameters.
Definition AdvancedMotion.h:929
Vector2 * nextPoints_
The tracked next image points, progressively refined through pyramid layers (coarsest to finest)
Definition AdvancedMotion.h:229
unsigned int layerRadius() const
Returns the search radius for the current pyramid layer.
Definition AdvancedMotion.h:912
bool startLayer(const unsigned int layerIndex, const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid)
Starts processing a specific pyramid layer.
This class collects statistics about tracking distances between corresponding 2D feature points.
Definition AdvancedMotion.h:296
std::string toString() const
Returns a string of the tracking statistics.
size_t measurements() const
Returns the number of measurements this statistic holds, (the number of calls to addCorrespondences()...
Definition AdvancedMotion.h:934
Scalars sqrDistances_
The squared Euclidean distances between all added point correspondences.
Definition AdvancedMotion.h:351
void addCorrespondences(const Vector2 *previousImagePoints, const Vector2 *nextImagePoints, const uint8_t *validCorrespondences, const size_t size)
Adds a set of point correspondences to the tracking statistics, filtering by validity flags.
void addCorrespondences(const Vector2 *previousImagePoints, const Vector2 *nextImagePoints, const size_t size)
Adds a set of point correspondences to the tracking statistics.
bool isValid() const
Returns whether this tracking statistic object is valid.
Definition AdvancedMotion.h:939
TrackingStatistic(const unsigned int width, const unsigned int height)
Creates a new tracking statistic object.
Definition AdvancedMotion.h:60
std::vector< uint32_t > MetricResults
Definition of a vector holding metric results.
Definition AdvancedMotion.h:66
This class implements advanced motion techniques (mainly with sub-pixel accuracy or binary masks) all...
Definition AdvancedMotion.h:367
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:1264
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:2028
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:2150
static bool trackPointsBidirectionalSubPixelMirroredBorder(const CV::FramePyramid &previousPyramid, const CV::FramePyramid &nextPyramid, PointCorrespondences *pointCorrespondenceGroups, const size_t numberCorrespondenceGroups)
Tracks multiple groups of point correspondences bidirectionally between two frame pyramids with sub-p...
Definition AdvancedMotion.h:946
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:2251
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:1138
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:1737
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:1952
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:46
const Frame & finestLayer() const
Returns the finest layer frame of this pyramid.
Definition FramePyramid.h:785
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:828
bool isValid() const
Returns whether this pyramid holds at least one frame layer.
Definition FramePyramid.h:913
DownsamplingMode
Definition of individual down sampling modes.
Definition FramePyramid.h:53
@ DM_FILTER_14641
Down sampling is realized by a 5x5 Gaussian filter.
Definition FramePyramid.h:81
static constexpr unsigned int sizeFactor(const unsigned int layerIndex)
Returns the size factor of a specified layer in relation to the finest layer.
Definition FramePyramid.h:884
unsigned int layers() const
Returns the number of layers this pyramid holds.
Definition FramePyramid.h:811
const FrameType & frameType() const
Returns the frame type of the finest layer.
Definition FramePyramid.h:861
unsigned int finestHeight() const
Returns the height of the finest (first) layer.
Definition FramePyramid.h:834
const Frame & layer(const unsigned int layer) const
Returns the frame of a specified layer.
Definition FramePyramid.h:773
This class implements patch-based motion techniques.
Definition Motion.h:60
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:1879
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:4222
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:4332
const FrameType & frameType() const
Returns the frame type of this frame.
Definition Frame.h:3936
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4612
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:4206
@ 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:3241
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition Frame.h:3286
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition Frame.h:3281
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:3251
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3246
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:3298
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3271
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:2073
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1499
static constexpr T maxValue()
Returns the max scalar value.
Definition Numeric.h:3253
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:1159
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
PixelBoundingBoxT< unsigned int > PixelBoundingBox
Definition of the default PixelBoundingBox object with data type allowing only positive coordinate va...
Definition PixelBoundingBox.h:28
PixelPositionT< unsigned int > PixelPosition
Definition of the default PixelPosition object with a data type allowing only positive coordinate val...
Definition PixelPosition.h:32
std::vector< HarrisCorner > HarrisCorners
Definition of a vector holding Harris corners.
Definition HarrisCorner.h:30
BoxT2< Scalar > Box2
Definition of the Box2 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or...
Definition Box2.h:29
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition Math.h:145
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15