132void Optimizer4NeighborhoodStructuralConstrainedI1<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
134 const unsigned int layerWidth = layerI1_.width();
135 const unsigned int layerHeight = layerI1_.height();
136 ocean_assert(layerWidth != 0 && layerHeight != 0);
138 const std::vector<int> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
140 Frame& layerFrame = layerI1_.frame();
141 const Frame& layerMask = layerI1_.mask();
142 MappingI1& layerMapping = layerI1_.mapping();
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>();
155 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
156 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
157 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
161 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
162 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
165 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
167 const unsigned int xStart = firstColumn;
168 const unsigned int yStart = firstRow;
169 const unsigned int xEnd = firstColumn + numberColumns;
170 const unsigned int yEnd = firstRow + numberRows;
172 ocean_assert(xEnd - xStart <= layerWidth);
173 ocean_assert(yEnd - yStart <= layerHeight);
175 const unsigned int constraintWeightFactor = 180u;
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 != 0xFFu)
194 unsigned int newPositionX = positionRow->x();
195 unsigned int newPositionY = positionRow->y();
197 const uint64_t oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
198 const uint64_t oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
199 const uint64_t oldConstraintCost = uint64_t(constraints_.cost(x, y, newPositionX, newPositionY) *
Scalar(constraintWeightFactor));
200 uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost + oldConstraintCost;
202 unsigned int testPositionX, testPositionY;
205 ocean_assert(x == 0u || (maskRow - 1) == layerMask.
constpixel<uint8_t>(x - 1u, y));
206 if (x > 0u && *(maskRow - 1) != 0xFF)
208 ocean_assert(layerMapping.
position(x - 1, y));
209 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
212 testPositionX = (positionRow - 1)->x() + 1;
213 testPositionY = (positionRow - 1)->y();
215 if (testPositionX < layerWidth && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
218 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
219 + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
221 if (testCost < newCost)
223 newPositionX = testPositionX;
224 newPositionY = testPositionY;
231 ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
232 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu
234 && (positionRow - 1)->northEast() != *(positionRow - layerWidth))
236 ocean_assert(layerMapping.
position(x, y - 1));
237 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
240 testPositionX = (positionRow - layerWidth)->x();
241 testPositionY = (positionRow - layerWidth)->y() + 1;
243 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
246 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
247 + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
249 if (testCost < newCost)
251 newPositionX = testPositionX;
252 newPositionY = testPositionY;
262 ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
263 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu)
265 ocean_assert(layerMapping.
position(x, y - 1));
266 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
269 testPositionX = (positionRow - layerWidth)->x();
270 testPositionY = (positionRow - layerWidth)->y() + 1;
272 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
275 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
276 + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
278 if (testCost < newCost)
280 newPositionX = testPositionX;
281 newPositionY = testPositionY;
290 for (
unsigned int n = 0; n < radii; ++n)
292 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
294 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
295 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
298 if ((testPositionX == newPositionX && testPositionY == newPositionY)
299 || testPositionX >= layerWidth || testPositionY >= layerHeight
300 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
303 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
304 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
305 const uint64_t testConstraintCost = uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
307 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost + testConstraintCost;
309 if (testCost < newCost)
311 newPositionX = testPositionX;
312 newPositionY = testPositionY;
318 if (tUpdateFrame && foundBetter)
320 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
321 ocean_assert(layerMask.
constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
323 positionRow->setPosition(newPositionX, newPositionY);
325 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
337 for (
unsigned int yy = yEnd - 1; yy != yStart - 1; --yy)
339 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
341 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
344 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
346 bool foundBetter =
false;
348 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
349 if (*maskRow != 0xFFu)
351 unsigned int newPositionX = positionRow->x();
352 unsigned int newPositionY = positionRow->y();
354 const uint64_t oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
355 const uint64_t oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
356 const uint64_t oldConstraintCost = uint64_t(constraints_.cost(x, y, newPositionX, newPositionY) *
Scalar(constraintWeightFactor));
358 uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost + oldConstraintCost;
360 unsigned int testPositionX, testPositionY;
363 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
364 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
366 ocean_assert(layerMapping.
position(x + 1, y));
367 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
370 testPositionX = (positionRow + 1)->x() - 1;
371 testPositionY = (positionRow + 1)->y();
373 if (testPositionX != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
376 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
377 + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
379 if (testCost < newCost)
381 newPositionX = testPositionX;
382 newPositionY = testPositionY;
389 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
390 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu
392 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
394 ocean_assert(layerMapping.
position(x, y + 1));
395 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
398 testPositionX = (positionRow + layerWidth)->x();
399 testPositionY = (positionRow + layerWidth)->y() - 1;
401 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu)
404 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
405 + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
407 if (testCost < newCost)
409 newPositionX = testPositionX;
410 newPositionY = testPositionY;
420 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
421 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
423 ocean_assert(layerMapping.
position(x, y + 1));
424 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
427 testPositionX = (positionRow + layerWidth)->x();
428 testPositionY = (positionRow + layerWidth)->y() - 1;
430 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
433 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
434 + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
436 if (testCost < newCost)
438 newPositionX = testPositionX;
439 newPositionY = testPositionY;
448 for (
unsigned int n = 0; n < radii; ++n)
450 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
452 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
453 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
455 if ((testPositionX == newPositionX && testPositionY == newPositionY)
456 || testPositionX >= layerWidth || testPositionY >= layerHeight
457 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
460 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
461 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
462 const uint64_t testConstraintCost = uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) *
Scalar(constraintWeightFactor));
464 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost + testConstraintCost;
466 if (testCost < newCost)
468 newPositionX = testPositionX;
469 newPositionY = testPositionY;
475 if (tUpdateFrame && foundBetter)
477 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
478 ocean_assert(layerMask.
constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFF);
480 positionRow->setPosition(newPositionX, newPositionY);
482 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);