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)
264 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
265 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
266 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
268 if (testCost < newCost)
270 newPositionX = testPositionX;
271 newPositionY = testPositionY;
272 newCost =
Scalar(testCost);
277 if (tUpdateFrame && foundBetter)
279 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
282 *positionRow =
Vector2(newPositionX, newPositionY);
284 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
296 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
298 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
300 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
301 Vector2* positionRow = layerMapping.
row(y) + xEnd - 1u;
303 for (
unsigned int x = xEnd - 1u; x != xStart - 1u ; --x)
305 bool foundBetter =
false;
307 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
308 if (*maskRow != 0xFF)
310 Scalar newPositionX = positionRow->x();
311 Scalar newPositionY = positionRow->y();
313 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
314 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
317 Scalar testPositionX, testPositionY;
320 ocean_assert(maskRow + 1 == layerMask.
constpixel<uint8_t>(x + 1u, y));
321 if (x < layerWidth - 1 && *(maskRow + 1) != 0xFF)
323 ocean_assert(layerMapping.
position(x + 1, y).
x() > 0);
324 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
327 testPositionX = (positionRow + 1)->x() - 1;
328 testPositionY = (positionRow + 1)->y();
333 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
335 if (
Scalar(testCost) < newCost)
337 newPositionX = testPositionX;
338 newPositionY = testPositionY;
339 newCost =
Scalar(testCost);
346 ocean_assert(maskRow + layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y + 1u));
347 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF)
349 ocean_assert(layerMapping.
position(x, y + 1).
x() > 0);
350 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
353 testPositionX = (positionRow + layerWidth)->x();
354 testPositionY = (positionRow + layerWidth)->y() - 1;
359 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
361 if (
Scalar(testCost) < newCost)
363 newPositionX = testPositionX;
364 newPositionY = testPositionY;
365 newCost =
Scalar(testCost);
372 for (
unsigned int n = 0; n < radii; ++n)
374 ocean_assert(newPositionX != -1 && newPositionY != -1);
376 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
377 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
379 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
380 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
386 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
387 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
388 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
390 if (testCost < newCost)
392 newPositionX = testPositionX;
393 newPositionY = testPositionY;
394 newCost =
Scalar(testCost);
399 if (tUpdateFrame && foundBetter)
401 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
404 *positionRow =
Vector2(newPositionX, newPositionY);
406 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);