8 #ifndef META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_HIGH_PERFORMANCE_I_H
9 #define META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_HIGH_PERFORMANCE_I_H
37 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
59 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;
78 template <
unsigned int tChannels>
79 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;
87 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
98 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
99 void Optimizer4NeighborhoodHighPerformanceI1<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
101 ocean_assert(layerI1_.frame().numberPlanes() == 1u);
103 switch (layerI1_.frame().channels())
106 optimizeSubsetChannels<1u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
110 optimizeSubsetChannels<2u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
114 optimizeSubsetChannels<3u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
118 optimizeSubsetChannels<4u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
122 ocean_assert(
false &&
"Invalid frame type.");
126 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
127 template <
unsigned int tChannels>
128 void Optimizer4NeighborhoodHighPerformanceI1<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
130 const unsigned int layerWidth = layerI1_.width();
131 const unsigned int layerHeight = layerI1_.height();
132 ocean_assert(layerWidth != 0 && layerHeight != 0);
134 const std::vector<int> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
136 Frame& layerFrame = layerI1_.frame();
137 const Frame& layerMask = layerI1_.mask();
138 MappingI1& layerMapping = layerI1_.mapping();
143 ocean_assert(firstColumn + numberColumns <= layerFrame.
width());
144 ocean_assert(firstRow + numberRows <= layerFrame.
height());
148 uint8_t*
const layerFrameData = layerFrame.
data<uint8_t>();
149 const uint8_t*
const layerMaskData = layerMask.
constdata<uint8_t>();
151 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
152 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
153 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
157 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
158 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
161 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
163 const unsigned int xStart = firstColumn;
164 const unsigned int yStart = firstRow;
165 const unsigned int xEnd = firstColumn + numberColumns;
166 const unsigned int yEnd = firstRow + numberRows;
168 ocean_assert(xEnd - xStart <= layerWidth);
169 ocean_assert(yEnd - yStart <= layerHeight);
174 for (
unsigned int yy = yStart; yy < yEnd; ++yy)
176 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
178 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xStart;
181 for (
unsigned int x = xStart; x < xEnd; ++x)
183 bool foundBetter =
false;
185 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
186 if (*maskRow != 0xFF)
188 unsigned int newPositionX = positionRow->x();
189 unsigned int newPositionY = positionRow->y();
191 const uint64_t oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
192 const uint64_t oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
193 uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost;
195 unsigned int testPositionX, testPositionY;
198 ocean_assert(x == 0u || (maskRow - 1) == layerMask.
constpixel<uint8_t>(x - 1u, y));
199 if (x > 0u && *(maskRow - 1) != 0xFFu)
201 ocean_assert(layerMapping.
position(x - 1, y));
202 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
205 testPositionX = (positionRow - 1)->x() + 1;
206 testPositionY = (positionRow - 1)->y();
208 if (testPositionX < layerWidth && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
211 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
213 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
215 if (testCost < newCost)
217 newPositionX = testPositionX;
218 newPositionY = testPositionY;
225 ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
226 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu
228 && (positionRow - 1)->northEast() != *(positionRow - layerWidth))
230 ocean_assert(layerMapping.
position(x, y - 1));
231 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
234 testPositionX = (positionRow - layerWidth)->x();
235 testPositionY = (positionRow - layerWidth)->y() + 1;
237 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
240 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
242 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
244 if (testCost < newCost)
246 newPositionX = testPositionX;
247 newPositionY = testPositionY;
257 ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
258 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu)
260 ocean_assert(layerMapping.
position(x, y - 1));
261 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
264 testPositionX = (positionRow - layerWidth)->x();
265 testPositionY = (positionRow - layerWidth)->y() + 1;
267 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
270 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
272 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
274 if (testCost < newCost)
276 newPositionX = testPositionX;
277 newPositionY = testPositionY;
286 for (
unsigned int n = 0; n < radii; ++n)
288 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
290 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
291 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
294 if ((testPositionX == newPositionX && testPositionY == newPositionY)
295 || testPositionX >= layerWidth || testPositionY >= layerHeight
296 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
299 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
300 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
302 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost;
304 if (testCost < newCost)
306 newPositionX = testPositionX;
307 newPositionY = testPositionY;
313 if (tUpdateFrame && foundBetter)
315 ocean_assert(layerMaskData[y * layerWidth + x] != 0xFF);
316 ocean_assert(layerMaskData[newPositionY * layerMaskStrideElements + newPositionX] == 0xFF);
318 positionRow->setPosition(newPositionX, newPositionY);
320 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
332 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
334 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
336 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
339 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
341 bool foundBetter =
false;
343 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
344 if (*maskRow != 0xFF)
346 unsigned int newPositionX = positionRow->x();
347 unsigned int newPositionY = positionRow->y();
349 const uint64_t oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
350 const uint64_t oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
351 uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost;
353 unsigned int testPositionX, testPositionY;
356 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
357 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
359 ocean_assert(layerMapping.
position(x + 1, y));
360 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
363 testPositionX = (positionRow + 1)->x() - 1;
364 testPositionY = (positionRow + 1)->y();
366 if (testPositionX != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
369 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
371 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
373 if (testCost < newCost)
375 newPositionX = testPositionX;
376 newPositionY = testPositionY;
383 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
384 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu
386 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
388 ocean_assert(layerMapping.
position(x, y + 1));
389 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
392 testPositionX = (positionRow + layerWidth)->x();
393 testPositionY = (positionRow + layerWidth)->y() - 1;
395 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
398 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
400 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
402 if (testCost < newCost)
404 newPositionX = testPositionX;
405 newPositionY = testPositionY;
415 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
416 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
418 ocean_assert(layerMapping.
position(x, y + 1));
419 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
422 testPositionX = (positionRow + layerWidth)->x();
423 testPositionY = (positionRow + layerWidth)->y() - 1;
425 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
428 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
430 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
432 if (testCost < newCost)
434 newPositionX = testPositionX;
435 newPositionY = testPositionY;
444 for (
unsigned int n = 0; n < radii; ++n)
446 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
448 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
449 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
451 if ((testPositionX == newPositionX && testPositionY == newPositionY)
452 || testPositionX >= layerWidth || testPositionY >= layerHeight
453 || layerMaskData[testPositionY * layerWidth + testPositionX] != 0xFF)
456 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
457 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
458 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost;
460 if (testCost < newCost)
462 newPositionX = testPositionX;
463 newPositionY = testPositionY;
469 if (tUpdateFrame && foundBetter)
471 ocean_assert(layerMaskData[y * layerWidth + x] != 0xFF);
472 ocean_assert(layerMaskData[newPositionY * layerWidth + newPositionX] == 0xFF);
474 positionRow->setPosition(newPositionX, newPositionY);
476 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
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 pixel accuracy.
Definition: LayerI1.h:41
This class implements the pixel mapping between source and target frames.
Definition: MappingI1.h:49
unsigned int spatialCost4Neighborhood(const unsigned int xTarget, const unsigned int yTarget, const unsigned int xSource, const unsigned int ySource, const uint8_t *targetMask, const unsigned int targetMaskPaddingElements, const unsigned int maxCost) const
Calculates the smallest/cheapest spatial cost for a given point in a four-neighborhood and normalizes...
Definition: MappingI1.h:212
unsigned int appearanceCost5x5(const unsigned int xTarget, const unsigned int yTarget, const unsigned int xSource, const unsigned int ySource, const uint8_t *frame, const uint8_t *mask, const unsigned int framePaddingElements, const unsigned int maskPaddingElements) const
Calculates the appearance cost for a given point in a given frame.
Definition: MappingI1.h:634
const PixelPosition * row(const unsigned int y) const
Returns the pointer to a mapping row.
Definition: MappingI.h:243
const PixelPosition & position(const unsigned int x, const unsigned int y) const
Returns the mapping for a given position.
Definition: MappingI.h:215
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 synthesis optimizers.
Definition: Optimizer.h:30
This class is the base class for all optimizers that use a mapping with integer accuracy.
Definition: OptimizerI.h:29
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
This class implements a generator for random numbers.
Definition: RandomGenerator.h:42
static unsigned int random(const unsigned int maxValue)
Returns one random integer value with specified maximum value.
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
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15