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)
262 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
263 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
264 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
266 if (testCost < newCost)
268 newPositionX = testPositionX;
269 newPositionY = testPositionY;
270 newCost =
Scalar(testCost);
275 if (tUpdateFrame && foundBetter)
277 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
280 *positionRow =
Vector2(newPositionX, newPositionY);
282 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
294 for (
unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
296 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
298 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
299 Vector2* positionRow = layerMapping.
row(y) + xEnd - 1u;
301 for (
unsigned int x = xEnd - 1u; x != xStart - 1u ; --x)
303 bool foundBetter =
false;
305 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
306 if (*maskRow != 0xFF)
308 Scalar newPositionX = positionRow->x();
309 Scalar newPositionY = positionRow->y();
311 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
312 const unsigned int oldColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
315 Scalar testPositionX, testPositionY;
318 ocean_assert(maskRow + 1 == layerMask.
constpixel<uint8_t>(x + 1u, y));
319 if (x < layerWidth - 1 && *(maskRow + 1) != 0xFF)
321 ocean_assert(layerMapping.
position(x + 1, y).
x() > 0);
322 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
325 testPositionX = (positionRow + 1)->x() - 1;
326 testPositionY = (positionRow + 1)->y();
331 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
333 if (
Scalar(testCost) < newCost)
335 newPositionX = testPositionX;
336 newPositionY = testPositionY;
337 newCost =
Scalar(testCost);
344 ocean_assert(maskRow + layerMaskStrideElements == layerMask.
constpixel<uint8_t>(x, y + 1u));
345 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF)
347 ocean_assert(layerMapping.
position(x, y + 1).
x() > 0);
348 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
351 testPositionX = (positionRow + layerWidth)->x();
352 testPositionY = (positionRow + layerWidth)->y() - 1;
357 const unsigned int testCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
359 if (
Scalar(testCost) < newCost)
361 newPositionX = testPositionX;
362 newPositionY = testPositionY;
363 newCost =
Scalar(testCost);
370 for (
unsigned int n = 0; n < radii; ++n)
372 ocean_assert(newPositionX != -1 && newPositionY != -1);
374 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
375 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
377 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
378 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
382 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
383 const unsigned int testColorCost = layerMapping.
appearanceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements, tBorderFactor);
384 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
386 if (testCost < newCost)
388 newPositionX = testPositionX;
389 newPositionY = testPositionY;
390 newCost =
Scalar(testCost);
395 if (tUpdateFrame && foundBetter)
397 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFF);
400 *positionRow =
Vector2(newPositionX, newPositionY);
402 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);