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)
301 const uint64_t testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
302 const uint64_t testColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
304 const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost;
306 if (testCost < newCost)
308 newPositionX = testPositionX;
309 newPositionY = testPositionY;
315 if (tUpdateFrame && foundBetter)
317 ocean_assert(layerMaskData[y * layerWidth + x] != 0xFF);
318 ocean_assert(layerMaskData[newPositionY * layerMaskStrideElements + newPositionX] == 0xFF);
320 positionRow->setPosition(newPositionX, newPositionY);
322 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
334 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
336 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
338 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
341 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
343 bool foundBetter =
false;
345 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
346 if (*maskRow != 0xFF)
348 unsigned int newPositionX = positionRow->x();
349 unsigned int newPositionY = positionRow->y();
351 const uint64_t oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
352 const uint64_t oldColorCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
353 uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost;
355 unsigned int testPositionX, testPositionY;
358 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
359 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
361 ocean_assert(layerMapping.
position(x + 1, y));
362 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
365 testPositionX = (positionRow + 1)->x() - 1;
366 testPositionY = (positionRow + 1)->y();
368 if (testPositionX != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
371 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
373 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
375 if (testCost < newCost)
377 newPositionX = testPositionX;
378 newPositionY = testPositionY;
385 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
386 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu
388 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
390 ocean_assert(layerMapping.
position(x, y + 1));
391 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
394 testPositionX = (positionRow + layerWidth)->x();
395 testPositionY = (positionRow + layerWidth)->y() - 1;
397 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
400 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
402 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
404 if (testCost < newCost)
406 newPositionX = testPositionX;
407 newPositionY = testPositionY;
417 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
418 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
420 ocean_assert(layerMapping.
position(x, y + 1));
421 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
424 testPositionX = (positionRow + layerWidth)->x();
425 testPositionY = (positionRow + layerWidth)->y() - 1;
427 if (testPositionY != (
unsigned int)(-1) && layerMaskData[testPositionY * layerWidth + testPositionX] == 0xFF)
430 ocean_assert_accuracy(layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
432 const uint64_t testCost = layerMapping.
appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
434 if (testCost < newCost)
436 newPositionX = testPositionX;
437 newPositionY = testPositionY;
446 for (
unsigned int n = 0; n < radii; ++n)
448 ocean_assert(newPositionX != (
unsigned int)(-1) && newPositionY != (
unsigned int)(-1));
450 testPositionX = newPositionX +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
451 testPositionY = newPositionY +
RandomI::random(generator, -searchRadii[n], searchRadii[n]);
453 if ((testPositionX == newPositionX && testPositionY == newPositionY)
454 || testPositionX >= layerWidth || testPositionY >= layerHeight
455 || layerMaskData[testPositionY * layerWidth + 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 testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost;
464 if (testCost < newCost)
466 newPositionX = testPositionX;
467 newPositionY = testPositionY;
473 if (tUpdateFrame && foundBetter)
475 ocean_assert(layerMaskData[y * layerWidth + x] != 0xFF);
476 ocean_assert(layerMaskData[newPositionY * layerWidth + newPositionX] == 0xFF);
478 positionRow->setPosition(newPositionX, newPositionY);
480 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);