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