129void Optimizer4NeighborhoodAreaConstrainedI1<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
131 const unsigned int layerWidth = layerI1_.width();
132 const unsigned int layerHeight = layerI1_.height();
133 ocean_assert(layerWidth != 0 && layerHeight != 0);
135 const std::vector<int> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
137 Frame& layerFrame = layerI1_.frame();
138 const Frame& layerMask = layerI1_.mask();
139 MappingI1& layerMapping = layerI1_.mapping();
141 ocean_assert(layerFrame.
width() == layerWidth);
142 ocean_assert(layerFrame.
height() == layerHeight);
147 ocean_assert(firstColumn + numberColumns <= layerFrame.
width());
148 ocean_assert(firstRow + numberRows <= layerFrame.
height());
152 uint8_t*
const layerFrameData = layerFrame.
data<uint8_t>();
153 const uint8_t*
const layerMaskData = layerMask.
constdata<uint8_t>();
154 const uint8_t*
const layerFilterData = filter_.constdata<uint8_t>();
156 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
157 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
158 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
159 const unsigned int layerFilterStrideElements = filter_.strideElements();
163 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
164 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
167 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
169 const unsigned int xStart = firstColumn;
170 const unsigned int yStart = firstRow;
171 const unsigned int xEnd = firstColumn + numberColumns;
172 const unsigned int yEnd = firstRow + numberRows;
174 ocean_assert(xEnd - xStart <= layerWidth);
175 ocean_assert(yEnd - yStart <= layerHeight);
180 for (
unsigned int yy = yStart; yy < yEnd; ++yy)
182 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
184 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xStart;
187 for (
unsigned int x = xStart; x < xEnd; ++x)
189 bool foundBetter =
false;
191 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
192 if (*maskRow != 0xFF)
194 unsigned int newPositionX = positionRow->x();
195 unsigned int newPositionY = positionRow->y();
197 const unsigned int oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
198 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
199 unsigned int newCost = tWeightFactor * oldSpatialCost + oldColorCost;
201 unsigned int testPositionX, testPositionY;
204 ocean_assert(x == 0 || maskRow - 1 == layerMask.
constpixel<uint8_t>(x - 1u, y));
205 if (x > 0 && *(maskRow - 1) != 0xFF)
207 ocean_assert(layerMapping.
position(x - 1, y));
208 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
211 testPositionX = (positionRow - 1)->x() + 1;
212 testPositionY = (positionRow - 1)->y();
214 if (testPositionX < layerWidth && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
215 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
218 ocean_assert(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
220 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
222 if (testCost < newCost)
224 newPositionX = testPositionX;
225 newPositionY = testPositionY;
232 ocean_assert(y == 0 || maskRow - layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y - 1u));
233 if (y > 0 && *(maskRow - layerMaskStrideElements) != 0xFFu
235 && (positionRow - 1)->northEast() != *(positionRow - layerWidth))
237 ocean_assert(layerMapping.
position(x, y - 1));
238 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
241 testPositionX = (positionRow - layerWidth)->x();
242 testPositionY = (positionRow - layerWidth)->y() + 1;
244 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
245 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
248 ocean_assert(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
250 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
252 if (testCost < newCost)
254 newPositionX = testPositionX;
255 newPositionY = testPositionY;
266 ocean_assert(y == 0 || maskRow - layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y - 1u));
267 if (y > 0 && *(maskRow - layerMaskStrideElements) != 0xFFu)
269 ocean_assert(layerMapping.
position(x, y - 1));
270 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
273 testPositionX = (positionRow - layerWidth)->x();
274 testPositionY = (positionRow - layerWidth)->y() + 1;
276 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
277 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
280 ocean_assert(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
282 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
284 if (testCost < newCost)
286 newPositionX = testPositionX;
287 newPositionY = testPositionY;
296 for (
unsigned int n = 0; n < radii; ++n)
298 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
300 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
301 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
304 if ((testPositionX == newPositionX && testPositionY == newPositionY)
305 || testPositionX >= layerWidth || testPositionY >= layerHeight
306 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFFu
307 || layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] != 0xFFu)
310 const unsigned int testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
311 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
312 const unsigned int testCost = tWeightFactor * testSpatialCost + testColorCost;
314 if (testCost < newCost)
316 newPositionX = testPositionX;
317 newPositionY = testPositionY;
323 if (tUpdateFrame && foundBetter)
325 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
326 ocean_assert(layerMask.
constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
328 positionRow->setPosition(newPositionX, newPositionY);
330 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
342 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
344 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
346 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
349 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
351 bool foundBetter =
false;
353 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
354 if (*maskRow != 0xFF)
356 unsigned int newPositionX = positionRow->x();
357 unsigned int newPositionY = positionRow->y();
359 const unsigned int oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
360 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
361 unsigned int newCost = tWeightFactor * oldSpatialCost + oldColorCost;
363 unsigned int testPositionX, testPositionY;
366 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
367 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFF)
369 ocean_assert(layerMapping.
position(x + 1u, y));
370 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1u, y));
373 testPositionX = (positionRow + 1)->x() - 1;
374 testPositionY = (positionRow + 1)->y();
376 if (testPositionX != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
377 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
380 ocean_assert(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
382 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
384 if (testCost < newCost)
386 newPositionX = testPositionX;
387 newPositionY = testPositionY;
394 ocean_assert(y == layerHeight - 1 || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
395 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF
397 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
399 ocean_assert(layerMapping.
position(x, y + 1));
400 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
403 testPositionX = (positionRow + layerWidth)->x();
404 testPositionY = (positionRow + layerWidth)->y() - 1u;
406 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
407 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
410 ocean_assert(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
412 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
414 if (testCost < newCost)
416 newPositionX = testPositionX;
417 newPositionY = testPositionY;
427 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
428 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
430 ocean_assert(layerMapping.
position(x, y + 1u));
431 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1u));
434 testPositionX = (positionRow + layerWidth)->x();
435 testPositionY = (positionRow + layerWidth)->y() - 1u;
437 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
438 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
441 ocean_assert(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
443 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
445 if (testCost < newCost)
447 newPositionX = testPositionX;
448 newPositionY = testPositionY;
457 for (
unsigned int n = 0; n < radii; ++n)
459 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
461 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
462 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
464 if ((testPositionX == newPositionX && testPositionY == newPositionY)
465 || testPositionX >= layerWidth || testPositionY >= layerHeight
466 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFFu
467 || layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] != 0xFFu)
470 const unsigned int testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
471 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
472 const unsigned int testCost = tWeightFactor * testSpatialCost + testColorCost;
474 if (testCost < newCost)
476 newPositionX = testPositionX;
477 newPositionY = testPositionY;
483 if (tUpdateFrame && foundBetter)
485 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
486 ocean_assert(layerMask.
constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
488 positionRow->setPosition(newPositionX, newPositionY);
490 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);