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) {
300 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
301 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
303 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost;
305 if (testCost < newCost)
307 newPositionX = testPositionX;
308 newPositionY = testPositionY;
314 if (tUpdateFrame && foundBetter)
316 ocean_assert(layerMaskData[y * layerWidth + x] != 0xFF);
317 ocean_assert(layerMaskData[newPositionY * layerMaskStrideElements + newPositionX] == 0xFF);
319 positionRow->setPosition(newPositionX, newPositionY);
321 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
333 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
335 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
337 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
340 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
342 bool foundBetter =
false;
344 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
345 if (*maskRow != 0xFF)
347 unsigned int newPositionX = positionRow->x();
348 unsigned int newPositionY = positionRow->y();
350 const uint64_t oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
351 const uint64_t oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
352 uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost;
354 unsigned int testPositionX, testPositionY;
357 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
358 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
360 ocean_assert(layerMapping.
position(x + 1, y));
361 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
364 testPositionX = (positionRow + 1)->x() - 1;
365 testPositionY = (positionRow + 1)->y();
367 if (testPositionX != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
370 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
372 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
374 if (testCost < newCost)
376 newPositionX = testPositionX;
377 newPositionY = testPositionY;
384 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
385 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu
387 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
389 ocean_assert(layerMapping.
position(x, y + 1));
390 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
393 testPositionX = (positionRow + layerWidth)->x();
394 testPositionY = (positionRow + layerWidth)->y() - 1;
396 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
399 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
401 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
403 if (testCost < newCost)
405 newPositionX = testPositionX;
406 newPositionY = testPositionY;
416 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
417 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
419 ocean_assert(layerMapping.
position(x, y + 1));
420 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
423 testPositionX = (positionRow + layerWidth)->x();
424 testPositionY = (positionRow + layerWidth)->y() - 1;
426 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
429 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
431 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
433 if (testCost < newCost)
435 newPositionX = testPositionX;
436 newPositionY = testPositionY;
445 for (
unsigned int n = 0; n < radii; ++n)
447 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
449 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
450 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
452 if ((testPositionX == newPositionX && testPositionY == newPositionY)
453 || testPositionX >= layerWidth || testPositionY >= layerHeight
454 || layerMaskData[testPositionY * layerWidth + testPositionX] != 0xFF) {
458 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
459 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
460 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost;
462 if (testCost < newCost)
464 newPositionX = testPositionX;
465 newPositionY = testPositionY;
471 if (tUpdateFrame && foundBetter)
473 ocean_assert(layerMaskData[y * layerWidth + x] != 0xFF);
474 ocean_assert(layerMaskData[newPositionY * layerWidth + newPositionX] == 0xFF);
476 positionRow->setPosition(newPositionX, newPositionY);
478 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);