128void 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);