130void Optimizer4NeighborhoodReferenceFrameF1<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
132 const unsigned int layerWidth = layerF1_.width();
133 const unsigned int layerHeight = layerF1_.height();
135 ocean_assert(layerWidth != 0u && layerHeight != 0u);
137 const std::vector<Scalar> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
139 Frame& layerFrame = layerF1_.frame();
140 const Frame& layerMask = layerF1_.mask();
141 MappingF1& layerMapping = layerF1_.mapping();
143 ocean_assert(layerWidth != 0u && layerHeight != 0u);
147 ocean_assert(referenceFrame_.width() == layerWidth);
148 ocean_assert(referenceFrame_.height() == layerHeight);
149 ocean_assert(referenceFrame_.pixelOrigin() == layerFrame.
pixelOrigin());
151 ocean_assert(firstColumn + numberColumns <= layerFrame.
width());
152 ocean_assert(firstRow + numberRows <= layerFrame.
height());
156 uint8_t*
const layerFrameData = layerFrame.
data<uint8_t>();
157 const uint8_t*
const layerMaskData = layerMask.
constdata<uint8_t>();
158 const uint8_t*
const referenceData = referenceFrame_.constdata<uint8_t>();
160 const unsigned int layerFramePaddingElements = layerFrame.
paddingElements();
161 const unsigned int layerFrameStrideElements = layerFrame.
strideElements();
162 const unsigned int layerMaskPaddingElements = layerMask.
paddingElements();
163 const unsigned int layerMaskStrideElements = layerMask.
strideElements();
164 const unsigned int referencePaddingElements = referenceFrame_.paddingElements();
168 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.
top());
169 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.
bottomEnd());
172 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
174 const unsigned int xStart = firstColumn;
175 const unsigned int yStart = firstRow;
176 const unsigned int xEnd = firstColumn + numberColumns;
177 const unsigned int yEnd = firstRow + numberRows;
179 ocean_assert(xEnd - xStart <= layerWidth);
180 ocean_assert(yEnd - yStart <= layerHeight);
185 for (
unsigned int yy = yStart; yy < yEnd; ++yy)
187 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
189 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xStart;
190 Vector2* positionRow = layerMapping.
row(y) + xStart;
192 for (
unsigned int x = xStart; x < xEnd; ++x)
194 bool foundBetter =
false;
196 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
197 if (*maskRow != 0xFF)
199 Scalar newPositionX = positionRow->x();
200 Scalar newPositionY = positionRow->y();
202 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
203 const unsigned int oldColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
206 Scalar testPositionX, testPositionY;
209 ocean_assert((maskRow - 1) == layerMask.
constpixel<uint8_t>(x - 1u, y));
210 if (x > 0u && *(maskRow - 1) != 0xFFu)
212 ocean_assert(layerMapping.
position(x - 1u, y).
x() > 0);
213 ocean_assert(*(positionRow - 1) == layerMapping.
position(x - 1, y));
216 testPositionX = (positionRow - 1)->x() + 1;
217 testPositionY = (positionRow - 1)->y();
222 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
224 if (
Scalar(testCost) < newCost)
226 newPositionX = testPositionX;
227 newPositionY = testPositionY;
228 newCost =
Scalar(testCost);
235 ocean_assert((maskRow - layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y - 1u));
236 if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu)
238 ocean_assert(layerMapping.
position(x, y - 1).
x() > 0);
239 ocean_assert(*(positionRow - layerWidth) == layerMapping.
position(x, y - 1));
242 testPositionX = (positionRow - layerWidth)->x();
243 testPositionY = (positionRow - layerWidth)->y() + 1;
248 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
250 if (
Scalar(testCost) < newCost)
252 newPositionX = testPositionX;
253 newPositionY = testPositionY;
254 newCost =
Scalar(testCost);
261 for (
unsigned int n = 0; n < radii; ++n)
263 ocean_assert(newPositionX != -1 && newPositionY != -1);
265 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
266 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
269 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
270 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
274 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
275 const unsigned int testColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
276 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
278 if (testCost < newCost)
280 newPositionX = testPositionX;
281 newPositionY = testPositionY;
282 newCost =
Scalar(testCost);
287 if (tUpdateFrame && foundBetter)
289 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
292 *positionRow =
Vector2(newPositionX, newPositionY);
294 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);
306 for (
unsigned int yy = yEnd - 1; yy != yStart - 1; --yy)
308 const unsigned int y =
modulo(
int(yy + rowOffset - boundingBoxTop),
int(boundingBoxHeight)) + boundingBoxTop;
310 const uint8_t* maskRow = layerMask.
constrow<uint8_t>(y) + xEnd - 1u;
311 Vector2* positionRow = layerMapping.
row(y) + xEnd - 1u;
313 for (
unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
315 bool foundBetter =
false;
317 ocean_assert(maskRow == layerMask.
constpixel<uint8_t>(x, y));
318 if (*maskRow != 0xFFu)
320 Scalar newPositionX = positionRow->x();
321 Scalar newPositionY = positionRow->y();
323 const Scalar oldSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
324 const unsigned int oldColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
327 Scalar testPositionX, testPositionY;
330 ocean_assert((maskRow + 1) == layerMask.
constpixel<uint8_t>(x + 1u, y));
331 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
333 ocean_assert(layerMapping.
position(x + 1, y).
x() > 0);
334 ocean_assert(*(positionRow + 1) == layerMapping.
position(x + 1, y));
337 testPositionX = (positionRow + 1)->x() - 1;
338 testPositionY = (positionRow + 1)->y();
343 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
345 if (
Scalar(testCost) < newCost)
347 newPositionX = testPositionX;
348 newPositionY = testPositionY;
349 newCost =
Scalar(testCost);
356 ocean_assert((maskRow + layerMaskStrideElements) == layerMask.
constpixel<uint8_t>(x, y + 1u));
357 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
359 ocean_assert(layerMapping.
position(x, y + 1).
x() > 0);
360 ocean_assert(*(positionRow + layerWidth) == layerMapping.
position(x, y + 1));
363 testPositionX = (positionRow + layerWidth)->x();
364 testPositionY = (positionRow + layerWidth)->y() - 1;
369 const unsigned int testCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
371 if (
Scalar(testCost) < newCost)
373 newPositionX = testPositionX;
374 newPositionY = testPositionY;
375 newCost =
Scalar(testCost);
382 for (
unsigned int n = 0; n < radii; ++n)
384 ocean_assert(newPositionX != -1 && newPositionY != -1);
386 testPositionX = newPositionX +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
387 testPositionY = newPositionY +
Random::scalar(generator, -searchRadii[n], searchRadii[n]);
389 if ((testPositionX == newPositionX && testPositionY == newPositionY) || testPositionX <
Scalar(2) || testPositionX >=
Scalar(layerWidth - 3u)
390 || testPositionY <
Scalar(2) || testPositionY >=
Scalar(layerHeight - 3u)
394 const Scalar testSpatialCost = layerMapping.
spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements,
Scalar(maxSpatialCost));
395 const unsigned int testColorCost = layerMapping.
appearanceReferenceCost5x5<tChannels>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, referenceData, layerFramePaddingElements, layerMaskPaddingElements, referencePaddingElements, tBorderFactor);
396 const Scalar testCost =
Scalar(tWeightFactor) * testSpatialCost +
Scalar(testColorCost);
398 if (testCost < newCost)
400 newPositionX = testPositionX;
401 newPositionY = testPositionY;
402 newCost =
Scalar(testCost);
407 if (tUpdateFrame && foundBetter)
409 ocean_assert(layerMask.
constpixel<uint8_t>(x, y)[0] != 0xFFu);
412 *positionRow =
Vector2(newPositionX, newPositionY);
414 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(layerFrameData, layerWidth, layerHeight, layerFramePaddingElements,
Vector2(newPositionX, newPositionY), layerFrameData + y * layerFrameStrideElements + x * tChannels);