8 #ifndef META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_HIGH_PERFORMANCE_SKIPPING_I_H
9 #define META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_HIGH_PERFORMANCE_SKIPPING_I_H
36 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;
77 template <
unsigned int tChannels>
78 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;
86 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
97 template <
unsigned int tWeightFactor,
unsigned int tBorderFactor,
bool tUpdateFrame>
98 void Optimizer4NeighborhoodHighPerformanceSkippingI1<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
100 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 Optimizer4NeighborhoodHighPerformanceSkippingI1<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 != 0xFFu && (x == 0u || y == 0u || (positionRow - 1)->east() != *positionRow || (positionRow - layerWidth)->south() != *positionRow))
188 unsigned int newPositionX = positionRow->x();
189 unsigned int newPositionY = positionRow->y();
191 const unsigned int oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
192 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
193 unsigned int newCost = 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 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
213 if (testCost < newCost)
215 newPositionX = testPositionX;
216 newPositionY = testPositionY;
223 ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
224 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFF
226 && (positionRow - 1)->northEast() != *(positionRow - layerWidth))
228 ocean_assert(layerMapping.
position(x, y - 1));
229 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
232 testPositionX = (positionRow - layerWidth)->x();
233 testPositionY = (positionRow - layerWidth)->y() + 1;
235 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
238 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
240 if (testCost < newCost)
242 newPositionX = testPositionX;
243 newPositionY = testPositionY;
253 ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
254 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu)
256 ocean_assert(layerMapping.
position(x, y - 1));
257 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
260 testPositionX = (positionRow - layerWidth)->x();
261 testPositionY = (positionRow - layerWidth)->y() + 1;
263 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
266 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
268 if (testCost < newCost)
270 newPositionX = testPositionX;
271 newPositionY = testPositionY;
280 for (
unsigned int n = 0; n < radii; ++n)
282 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
284 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
285 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
288 if ((testPositionX == newPositionX && testPositionY == newPositionY)
289 || testPositionX >= layerWidth || testPositionY >= layerHeight
290 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
293 const unsigned int testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
294 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
296 const unsigned int testCost = tWeightFactor * testSpatialCost + testColorCost;
298 if (testCost < newCost)
300 newPositionX = testPositionX;
301 newPositionY = testPositionY;
307 if (tUpdateFrame && foundBetter)
309 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
310 ocean_assert(layerMask.
constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
312 positionRow->setPosition(newPositionX, newPositionY);
313 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
325 for (
unsigned int yy = yEnd - 1; yy != yStart - 1; --yy)
327 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
329 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
332 for (
unsigned int x = xEnd - 1; x != xStart - 1 ; --x)
334 bool foundBetter =
false;
336 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
337 if (*maskRow != 0xFFu && (x == layerWidth - 1u || y == layerHeight - 1u || (positionRow + 1)->west() != *positionRow || (positionRow + layerWidth)->north() != *positionRow))
339 unsigned int newPositionX = positionRow->x();
340 unsigned int newPositionY = positionRow->y();
342 const unsigned int oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
343 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
344 unsigned int newCost = tWeightFactor * oldSpatialCost + oldColorCost;
346 unsigned int testPositionX, testPositionY;
349 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
350 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
352 ocean_assert(layerMapping.
position(x + 1, y));
353 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
356 testPositionX = (positionRow + 1)->x() - 1;
357 testPositionY = (positionRow + 1)->y();
359 if (testPositionX != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
362 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
364 if (testCost < newCost)
366 newPositionX = testPositionX;
367 newPositionY = testPositionY;
374 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
375 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu
377 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
379 ocean_assert(layerMapping.
position(x, y + 1));
380 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
383 testPositionX = (positionRow + layerWidth)->x();
384 testPositionY = (positionRow + layerWidth)->y() - 1;
386 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
389 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
391 if (testCost < newCost)
393 newPositionX = testPositionX;
394 newPositionY = testPositionY;
404 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
405 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF)
407 ocean_assert(layerMapping.
position(x, y + 1));
408 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
411 testPositionX = (positionRow + layerWidth)->x();
412 testPositionY = (positionRow + layerWidth)->y() - 1;
414 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
417 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
419 if (testCost < newCost)
421 newPositionX = testPositionX;
422 newPositionY = testPositionY;
431 for (
unsigned int n = 0; n < radii; ++n)
433 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
435 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
436 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
438 if ((testPositionX == newPositionX && testPositionY == newPositionY)
439 || testPositionX >= layerWidth || testPositionY >= layerHeight
440 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
443 const unsigned int testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
444 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
446 const unsigned int testCost = tWeightFactor * testSpatialCost + testColorCost;
448 if (testCost < newCost)
450 newPositionX = testPositionX;
451 newPositionY = testPositionY;
457 if (tUpdateFrame && foundBetter)
459 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
460 ocean_assert(layerMask.
constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
462 positionRow->setPosition(newPositionX, newPositionY);
463 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