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);