8 #ifndef META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_HIGH_PERFORMANCE_F_1_H
9 #define META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_HIGH_PERFORMANCE_F_1_H
33 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
55 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;
74 template <
unsigned int tChannels>
75 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;
83 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
94 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
95 void Optimizer4NeighborhoodHighPerformanceF1<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
97 ocean_assert(layerF1_.frame().numberPlanes() == 1u);
99 switch (layerF1_.frame().channels())
102 optimizeSubsetChannels<1u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
106 optimizeSubsetChannels<2u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
110 optimizeSubsetChannels<3u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
114 optimizeSubsetChannels<4u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
118 ocean_assert(
false &&
"Invalid frame type.");
122 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
123 template <
unsigned int tChannels>
124 void Optimizer4NeighborhoodHighPerformanceF1<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
126 const unsigned int layerWidth = layerF1_.width();
127 const unsigned int layerHeight = layerF1_.height();
129 ocean_assert(layerWidth != 0u && layerHeight != 0u);
131 const std::vector<Scalar> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
133 Frame& layerFrame = layerF1_.frame();
134 const Frame& layerMask = layerF1_.mask();
135 MappingF1& layerMapping = layerF1_.mapping();
140 ocean_assert(firstColumn + numberColumns <= layerFrame.
width());
141 ocean_assert(firstRow + numberRows <= layerFrame.
height());
145 uint8_t*
const layerFrameData = layerFrame.
data<uint8_t>();
146 const uint8_t*
const layerMaskData = layerMask.
constdata<uint8_t>();
148 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
149 const unsigned int layerFrameStrideElements = layerFrame.
strideElements();
151 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
152 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
156 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
157 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
160 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
162 const unsigned int xStart = firstColumn;
163 const unsigned int yStart = firstRow;
164 const unsigned int xEnd = firstColumn + numberColumns;
165 const unsigned int yEnd = firstRow + numberRows;
167 ocean_assert(xEnd - xStart <= layerWidth);
168 ocean_assert(yEnd - yStart <= layerHeight);
173 for (
unsigned int yy = yStart; yy < yEnd; ++yy)
175 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
177 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xStart;
178 Vector2* positionRow = layerMapping.
row(y) + xStart;
180 for (
unsigned int x = xStart; x < xEnd; ++x)
182 bool foundBetter =
false;
184 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
185 if (*maskRow != 0xFF)
187 Scalar newPositionX = positionRow->x();
188 Scalar newPositionY = positionRow->y();
190 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
191 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
194 Scalar testPositionX, testPositionY;
197 ocean_assert(maskRow - 1 == layerMask.
constpixel<uint8_t>(x - 1u, y));
198 if (x > 0 && *(maskRow - 1) != 0xFF)
200 ocean_assert(layerMapping.
position(x - 1, y).
x() > 0);
201 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
204 testPositionX = (positionRow - 1)->x() + 1;
205 testPositionY = (positionRow - 1)->y();
210 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
212 if (
Scalar(testCost) < newCost)
214 newPositionX = testPositionX;
215 newPositionY = testPositionY;
216 newCost =
Scalar(testCost);
223 ocean_assert(maskRow - layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y - 1u));
224 if (y > 0 && *(maskRow - layerMaskStrideElements) != 0xFF)
226 ocean_assert(layerMapping.
position(x, y - 1).
x() > 0);
227 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
230 testPositionX = (positionRow - layerWidth)->x();
231 testPositionY = (positionRow - layerWidth)->y() + 1;
236 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
238 if (
Scalar(testCost) < newCost)
240 newPositionX = testPositionX;
241 newPositionY = testPositionY;
242 newCost =
Scalar(testCost);
249 for (
unsigned int n = 0; n < radii; ++n)
251 ocean_assert(newPositionX != -1 && newPositionY != -1);
253 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
254 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
257 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
258 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
262 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
263 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
264 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
266 if (testCost < newCost)
268 newPositionX = testPositionX;
269 newPositionY = testPositionY;
270 newCost =
Scalar(testCost);
275 if (tUpdateFrame && foundBetter)
277 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
280 *positionRow =
Vector2(newPositionX, newPositionY);
282 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
294 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
296 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
298 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
299 Vector2* positionRow = layerMapping.
row(y) + xEnd - 1u;
301 for (
unsigned int x = xEnd - 1u; x != xStart - 1u ; --x)
303 bool foundBetter =
false;
305 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
306 if (*maskRow != 0xFF)
308 Scalar newPositionX = positionRow->x();
309 Scalar newPositionY = positionRow->y();
311 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
312 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
315 Scalar testPositionX, testPositionY;
318 ocean_assert(maskRow + 1 == layerMask.
constpixel<uint8_t>(x + 1u, y));
319 if (x < layerWidth - 1 && *(maskRow + 1) != 0xFF)
321 ocean_assert(layerMapping.
position(x + 1, y).
x() > 0);
322 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
325 testPositionX = (positionRow + 1)->x() - 1;
326 testPositionY = (positionRow + 1)->y();
331 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
333 if (
Scalar(testCost) < newCost)
335 newPositionX = testPositionX;
336 newPositionY = testPositionY;
337 newCost =
Scalar(testCost);
344 ocean_assert(maskRow + layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y + 1u));
345 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF)
347 ocean_assert(layerMapping.
position(x, y + 1).
x() > 0);
348 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
351 testPositionX = (positionRow + layerWidth)->x();
352 testPositionY = (positionRow + layerWidth)->y() - 1;
357 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
359 if (
Scalar(testCost) < newCost)
361 newPositionX = testPositionX;
362 newPositionY = testPositionY;
363 newCost =
Scalar(testCost);
370 for (
unsigned int n = 0; n < radii; ++n)
372 ocean_assert(newPositionX != -1 && newPositionY != -1);
374 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
375 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
377 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
378 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
382 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
383 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
384 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
386 if (testCost < newCost)
388 newPositionX = testPositionX;
389 newPositionY = testPositionY;
390 newCost =
Scalar(testCost);
395 if (tUpdateFrame && foundBetter)
397 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
400 *positionRow =
Vector2(newPositionX, newPositionY);
402 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 appearanceCost5x5(const unsigned int xTarget, const unsigned int yTarget, const Scalar xSource, const Scalar ySource, const uint8_t *frame, const uint8_t *mask, const unsigned int framePaddingElements, const unsigned int maskPaddingElements, const unsigned int borderFactor) const
Calculates the appearance cost for a given point in a given frame.
Definition: MappingF1.h:265
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 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