124void Optimizer4NeighborhoodHighPerformanceF1<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
126 const unsigned int layerWidth = layerF1_.width();
127 const unsigned int layerHeight = layerF1_.height();
129 ocean_assert(layerWidth != 0u && layerHeight != 0u);
131 const std::vector<Scalar> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
133 Frame& layerFrame = layerF1_.frame();
134 const Frame& layerMask = layerF1_.mask();
135 MappingF1& layerMapping = layerF1_.mapping();
140 ocean_assert(firstColumn + numberColumns <= layerFrame.
width());
141 ocean_assert(firstRow + numberRows <= layerFrame.
height());
145 uint8_t*
const layerFrameData = layerFrame.
data<uint8_t>();
146 const uint8_t*
const layerMaskData = layerMask.
constdata<uint8_t>();
148 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
149 const unsigned int layerFrameStrideElements = layerFrame.
strideElements();
151 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
152 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
156 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
157 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
160 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
162 const unsigned int xStart = firstColumn;
163 const unsigned int yStart = firstRow;
164 const unsigned int xEnd = firstColumn + numberColumns;
165 const unsigned int yEnd = firstRow + numberRows;
167 ocean_assert(xEnd - xStart <= layerWidth);
168 ocean_assert(yEnd - yStart <= layerHeight);
173 for (
unsigned int yy = yStart; yy < yEnd; ++yy)
175 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
177 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xStart;
178 Vector2* positionRow = layerMapping.
row(y) + xStart;
180 for (
unsigned int x = xStart; x < xEnd; ++x)
182 bool foundBetter =
false;
184 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
185 if (*maskRow != 0xFF)
187 Scalar newPositionX = positionRow->x();
188 Scalar newPositionY = positionRow->y();
190 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
191 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
194 Scalar testPositionX, testPositionY;
197 ocean_assert(maskRow - 1 == layerMask.
constpixel<uint8_t>(x - 1u, y));
198 if (x > 0 && *(maskRow - 1) != 0xFF)
200 ocean_assert(layerMapping.
position(x - 1, y).
x() > 0);
201 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
204 testPositionX = (positionRow - 1)->x() + 1;
205 testPositionY = (positionRow - 1)->y();
210 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
212 if (
Scalar(testCost) < newCost)
214 newPositionX = testPositionX;
215 newPositionY = testPositionY;
216 newCost =
Scalar(testCost);
223 ocean_assert(maskRow - layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y - 1u));
224 if (y > 0 && *(maskRow - layerMaskStrideElements) != 0xFF)
226 ocean_assert(layerMapping.
position(x, y - 1).
x() > 0);
227 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
230 testPositionX = (positionRow - layerWidth)->x();
231 testPositionY = (positionRow - layerWidth)->y() + 1;
236 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
238 if (
Scalar(testCost) < newCost)
240 newPositionX = testPositionX;
241 newPositionY = testPositionY;
242 newCost =
Scalar(testCost);
249 for (
unsigned int n = 0; n < radii; ++n)
251 ocean_assert(newPositionX != -1 && newPositionY != -1);
253 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
254 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
257 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
258 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
263 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
264 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
265 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
267 if (testCost < newCost)
269 newPositionX = testPositionX;
270 newPositionY = testPositionY;
271 newCost =
Scalar(testCost);
276 if (tUpdateFrame && foundBetter)
278 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
281 *positionRow =
Vector2(newPositionX, newPositionY);
283 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
295 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
297 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
299 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
300 Vector2* positionRow = layerMapping.
row(y) + xEnd - 1u;
302 for (
unsigned int x = xEnd - 1u; x != xStart - 1u ; --x)
304 bool foundBetter =
false;
306 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
307 if (*maskRow != 0xFF)
309 Scalar newPositionX = positionRow->x();
310 Scalar newPositionY = positionRow->y();
312 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
313 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
316 Scalar testPositionX, testPositionY;
319 ocean_assert(maskRow + 1 == layerMask.
constpixel<uint8_t>(x + 1u, y));
320 if (x < layerWidth - 1 && *(maskRow + 1) != 0xFF)
322 ocean_assert(layerMapping.
position(x + 1, y).
x() > 0);
323 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
326 testPositionX = (positionRow + 1)->x() - 1;
327 testPositionY = (positionRow + 1)->y();
332 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
334 if (
Scalar(testCost) < newCost)
336 newPositionX = testPositionX;
337 newPositionY = testPositionY;
338 newCost =
Scalar(testCost);
345 ocean_assert(maskRow + layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y + 1u));
346 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF)
348 ocean_assert(layerMapping.
position(x, y + 1).
x() > 0);
349 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
352 testPositionX = (positionRow + layerWidth)->x();
353 testPositionY = (positionRow + layerWidth)->y() - 1;
358 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
360 if (
Scalar(testCost) < newCost)
362 newPositionX = testPositionX;
363 newPositionY = testPositionY;
364 newCost =
Scalar(testCost);
371 for (
unsigned int n = 0; n < radii; ++n)
373 ocean_assert(newPositionX != -1 && newPositionY != -1);
375 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
376 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
378 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
379 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
384 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
385 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
386 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
388 if (testCost < newCost)
390 newPositionX = testPositionX;
391 newPositionY = testPositionY;
392 newCost =
Scalar(testCost);
397 if (tUpdateFrame && foundBetter)
399 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
402 *positionRow =
Vector2(newPositionX, newPositionY);
404 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);