8 #ifndef META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_REFERENCE_FRAME_F_1_H
9 #define META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_REFERENCE_FRAME_F_1_H
35 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
58 void optimizeSubset(
const unsigned int radii,
const unsigned int maxSpatialCost,
const unsigned int boundingBoxTop,
const unsigned int boundingBoxHeight,
const bool downIsMain,
const unsigned int firstColumn,
const unsigned int numberColumns,
const unsigned int rowOffset,
const unsigned int firstRow,
const unsigned int numberRows,
const unsigned int threadIndex)
const override;
76 template <
unsigned int tChannels>
77 void optimizeSubsetChannels(
const unsigned int radii,
const unsigned int maxSpatialCost,
const unsigned int boundingBoxTop,
const unsigned int boundingBoxHeight,
const bool downIsMain,
const unsigned int firstColumn,
const unsigned int numberColumns,
const unsigned int rowOffset,
const unsigned int firstRow,
const unsigned int numberRows,
const unsigned int threadIndex)
const;
88 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
95 referenceFrame_(reference)
100 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
101 void Optimizer4NeighborhoodReferenceFrameF1<tWeightFactor, tBorderFactor, tUpdateFrame>::optimizeSubset(
const unsigned int radii,
const unsigned int maxSpatialCost,
const unsigned int boundingBoxTop,
const unsigned int boundingBoxHeight,
const bool downIsMain,
const unsigned int firstColumn,
const unsigned int numberColumns,
const unsigned int rowOffset,
const unsigned int firstRow,
const unsigned int numberRows,
const unsigned int threadIndex)
const
103 ocean_assert(layerF1_.frame().numberPlanes() == 1u);
105 switch (layerF1_.frame().channels())
108 optimizeSubsetChannels<1u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
112 optimizeSubsetChannels<2u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
116 optimizeSubsetChannels<3u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
120 optimizeSubsetChannels<4u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
124 ocean_assert(
false &&
"Invalid frame type.");
128 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
129 template <
unsigned int tChannels>
130 void Optimizer4NeighborhoodReferenceFrameF1<tWeightFactor, tBorderFactor, tUpdateFrame>::optimizeSubsetChannels(
const unsigned int radii,
const unsigned int maxSpatialCost,
const unsigned int boundingBoxTop,
const unsigned int boundingBoxHeight,
const bool downIsMain,
const unsigned int firstColumn,
const unsigned int numberColumns,
const unsigned int rowOffset,
const unsigned int firstRow,
const unsigned int numberRows,
const unsigned int threadIndex)
const
132 const unsigned int layerWidth = layerF1_.width();
133 const unsigned int layerHeight = layerF1_.height();
135 ocean_assert(layerWidth != 0u && layerHeight != 0u);
137 const std::vector<Scalar> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
139 Frame& layerFrame = layerF1_.frame();
140 const Frame& layerMask = layerF1_.mask();
141 MappingF1& layerMapping = layerF1_.mapping();
143 ocean_assert(layerWidth != 0u && layerHeight != 0u);
147 ocean_assert(referenceFrame_.width() == layerWidth);
148 ocean_assert(referenceFrame_.height() == layerHeight);
149 ocean_assert(referenceFrame_.pixelOrigin() == layerFrame.
pixelOrigin());
151 ocean_assert(firstColumn + numberColumns <= layerFrame.
width());
152 ocean_assert(firstRow + numberRows <= layerFrame.
height());
156 uint8_t*
const layerFrameData = layerFrame.
data<uint8_t>();
157 const uint8_t*
const layerMaskData = layerMask.
constdata<uint8_t>();
158 const uint8_t*
const referenceData = referenceFrame_.constdata<uint8_t>();
160 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
161 const unsigned int layerFrameStrideElements = layerFrame.
strideElements();
162 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
163 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
164 const unsigned int referencePaddingElements = referenceFrame_.paddingElements();
168 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
169 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
172 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
174 const unsigned int xStart = firstColumn;
175 const unsigned int yStart = firstRow;
176 const unsigned int xEnd = firstColumn + numberColumns;
177 const unsigned int yEnd = firstRow + numberRows;
179 ocean_assert(xEnd - xStart <= layerWidth);
180 ocean_assert(yEnd - yStart <= layerHeight);
185 for (
unsigned int yy = yStart; yy < yEnd; ++yy)
187 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
189 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xStart;
190 Vector2* positionRow = layerMapping.
row(y) + xStart;
192 for (
unsigned int x = xStart; x < xEnd; ++x)
194 bool foundBetter =
false;
196 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
197 if (*maskRow != 0xFF)
199 Scalar newPositionX = positionRow->x();
200 Scalar newPositionY = positionRow->y();
202 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
203 const unsigned int oldColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
206 Scalar testPositionX, testPositionY;
209 ocean_assert((maskRow - 1) == layerMask.
constpixel<uint8_t>(x - 1u, y));
210 if (x > 0u && *(maskRow - 1) != 0xFFu)
212 ocean_assert(layerMapping.
position(x - 1u, y).
x() > 0);
213 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
216 testPositionX = (positionRow - 1)->x() + 1;
217 testPositionY = (positionRow - 1)->y();
222 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
224 if (
Scalar(testCost) < newCost)
226 newPositionX = testPositionX;
227 newPositionY = testPositionY;
228 newCost =
Scalar(testCost);
235 ocean_assert((maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
236 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu)
238 ocean_assert(layerMapping.
position(x, y - 1).
x() > 0);
239 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
242 testPositionX = (positionRow - layerWidth)->x();
243 testPositionY = (positionRow - layerWidth)->y() + 1;
248 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
250 if (
Scalar(testCost) < newCost)
252 newPositionX = testPositionX;
253 newPositionY = testPositionY;
254 newCost =
Scalar(testCost);
261 for (
unsigned int n = 0; n < radii; ++n)
263 ocean_assert(newPositionX != -1 && newPositionY != -1);
265 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
266 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
269 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
270 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
274 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
275 const unsigned int testColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
276 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
278 if (testCost < newCost)
280 newPositionX = testPositionX;
281 newPositionY = testPositionY;
282 newCost =
Scalar(testCost);
287 if (tUpdateFrame && foundBetter)
289 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
292 *positionRow =
Vector2(newPositionX, newPositionY);
294 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
306 for (
unsigned int yy = yEnd - 1; yy != yStart - 1; --yy)
308 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
310 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
311 Vector2* positionRow = layerMapping.
row(y) + xEnd - 1u;
313 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
315 bool foundBetter =
false;
317 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
318 if (*maskRow != 0xFFu)
320 Scalar newPositionX = positionRow->x();
321 Scalar newPositionY = positionRow->y();
323 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
324 const unsigned int oldColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
327 Scalar testPositionX, testPositionY;
330 ocean_assert((maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
331 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
333 ocean_assert(layerMapping.
position(x + 1, y).
x() > 0);
334 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
337 testPositionX = (positionRow + 1)->x() - 1;
338 testPositionY = (positionRow + 1)->y();
343 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
345 if (
Scalar(testCost) < newCost)
347 newPositionX = testPositionX;
348 newPositionY = testPositionY;
349 newCost =
Scalar(testCost);
356 ocean_assert((maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
357 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
359 ocean_assert(layerMapping.
position(x, y + 1).
x() > 0);
360 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
363 testPositionX = (positionRow + layerWidth)->x();
364 testPositionY = (positionRow + layerWidth)->y() - 1;
369 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
371 if (
Scalar(testCost) < newCost)
373 newPositionX = testPositionX;
374 newPositionY = testPositionY;
375 newCost =
Scalar(testCost);
382 for (
unsigned int n = 0; n < radii; ++n)
384 ocean_assert(newPositionX != -1 && newPositionY != -1);
386 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
387 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
389 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
390 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
394 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
395 const unsigned int testColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
396 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
398 if (testCost < newCost)
400 newPositionX = testPositionX;
401 newPositionY = testPositionY;
402 newCost =
Scalar(testCost);
407 if (tUpdateFrame && foundBetter)
409 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
412 *positionRow =
Vector2(newPositionX, newPositionY);
414 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
T bottomEnd() const
Returns the bottom (excluding) pixel position of this bounding box.
Definition: PixelBoundingBox.h:451
T top() const
Returns the top (including) pixel position of this bounding box.
Definition: PixelBoundingBox.h:423
This class implements a single layer for pixel synthesis within one frame and sub-pixel accuracy.
Definition: LayerF1.h:44
Cost function:
Definition: MappingF1.h:52
unsigned int appearanceReferenceCost5x5(const unsigned int xTarget, const unsigned int yTarget, const Scalar xSource, const Scalar ySource, const uint8_t *frame, const uint8_t *mask, const uint8_t *reference, const unsigned int framePaddingElements, const unsigned int maskPaddingElements, const unsigned int referencePaddingElements, const unsigned int borderFactor) const
Calculates the appearance cost for a given point between two given frames.
Definition: MappingF1.h:317
Scalar spatialCost4Neighborhood(const unsigned int xTarget, const unsigned int yTarget, const Scalar xSource, const Scalar ySource, const uint8_t *targetMask, const unsigned int targetMaskPaddingElements, const Scalar maxCost) const
Calculates the smallest/cheapest spatial cost for a given point in a four-neighborhood and normalizes...
Definition: MappingF1.h:259
const Vector2 * row(const unsigned int y) const
Returns the pointer to a mapping row.
Definition: MappingF.h:210
const Vector2 & position(const unsigned int x, const unsigned int y) const
Returns the mapping for a given position.
Definition: MappingF.h:189
This class implements the base class for all synthesis optimizers that use one single frame.
Definition: Optimizer1.h:28
This class implements an optimizer for a mapping with float accuracy that uses a reference frame as a...
Definition: Optimizer4NeighborhoodReferenceFrameF1.h:40
void optimizeSubset(const unsigned int radii, const unsigned int maxSpatialCost, const unsigned int boundingBoxTop, const unsigned int boundingBoxHeight, const bool downIsMain, const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int rowOffset, const unsigned int firstRow, const unsigned int numberRows, const unsigned int threadIndex) const override
Optimizes a subset of the synthesis frame.
Definition: Optimizer4NeighborhoodReferenceFrameF1.h:101
void optimizeSubsetChannels(const unsigned int radii, const unsigned int maxSpatialCost, const unsigned int boundingBoxTop, const unsigned int boundingBoxHeight, const bool downIsMain, const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int rowOffset, const unsigned int firstRow, const unsigned int numberRows, const unsigned int threadIndex) const
Specialization of the default subset optimization function.
Definition: Optimizer4NeighborhoodReferenceFrameF1.h:130
Optimizer4NeighborhoodReferenceFrameF1(LayerF1 &layer, RandomGenerator &randomGenerator, const Frame &reference)
Creates a new optimizer object.
Definition: Optimizer4NeighborhoodReferenceFrameF1.h:89
LayerF1 & layerF1_
Specialized layer reference.
Definition: Optimizer4NeighborhoodReferenceFrameF1.h:82
const Frame & referenceFrame_
Reference frame that is used during the optimization.
Definition: Optimizer4NeighborhoodReferenceFrameF1.h:85
This class is the base class for all optimizers that use a mapping with float accuracy.
Definition: OptimizerF.h:29
This class is the base class for all synthesis optimizers.
Definition: Optimizer.h:30
This class is the base class for all optimizers that are able to optimize seperate subsets of the syn...
Definition: OptimizerSubset.h:30
This class implements Ocean's image class.
Definition: Frame.h:1792
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:4058
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4168
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition: Frame.h:4159
const T * constpixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific pixel.
Definition: Frame.h:4250
const T * constrow(const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific row.
Definition: Frame.h:4193
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:4042
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3143
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition: Frame.h:3188
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition: Frame.h:3153
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition: Frame.h:41
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3148
static bool formatIsGeneric(const PixelFormat pixelFormat, const DataType dataType, const uint32_t channels, const uint32_t planes=1u, const uint32_t widthMultiple=1u, const uint32_t heightMultiple=1u)
Checks whether a given pixel format is a specific layout regarding data channels and data type.
Definition: Frame.h:3406
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition: Numeric.h:2064
This class implements a generator for random numbers.
Definition: RandomGenerator.h:42
static T scalar(const T lower, const T upper)
Returns a random number between two borders.
Definition: Random.h:388
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
T modulo(const T &value, const T &ring)
Returns the modulo value of a given parameter within a ring allowing positive and negative parameters...
Definition: base/Utilities.h:924
float Scalar
Definition of a scalar type.
Definition: Math.h:128
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15