Ocean
Optimizer4NeighborhoodStructuralConstrainedI1.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_SYNTHESIS_4_NEIGHBORHOOD_STRUCTURAL_CONSTRAINED_I_1_H
9 #define META_OCEAN_CV_SYNTHESIS_4_NEIGHBORHOOD_STRUCTURAL_CONSTRAINED_I_1_H
10 
17 
18 namespace Ocean
19 {
20 
21 namespace CV
22 {
23 
24 namespace Synthesis
25 {
26 
27 /**
28  * This class implements a constrained mapping optimizer for integer mappings.
29  * @tparam tWeightFactor Spatial weight impact, with range [0, infinity)
30  * @tparam tBorderFactor Weight factor of border pixels, with range [1, infinity)
31  * @tparam tUpdateFrame True, to update the frame pixel whenever a new mapping has been found
32  * @ingroup cvsynthesis
33  */
34 template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
36  virtual public OptimizerI,
37  virtual public OptimizerSubset,
38  virtual public Optimizer1
39 {
40  public:
41 
42  /**
43  * Creates a new optimizer object.
44  * @param layer Synthesis layer that will be optimized
45  * @param randomGenerator Random number generator
46  * @param constraints Structural constraints that are used during the optimization
47  */
48  inline Optimizer4NeighborhoodStructuralConstrainedI1(LayerI1& layer, RandomGenerator& randomGenerator, const Constraints& constraints);
49 
50  private:
51 
52  /**
53  * Optimizes a subset of the synthesis frame.
54  * @see Optimizer1::optimizeSubset().
55  * @see optimizerSubsetChannels().
56  */
57  void optimizeSubset(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 override;
58 
59  /**
60  * Specialization of the default subset optimization function.
61  * The template parameters specified the number of channels the synthesis frame has.
62  * @param radii Number of improvement radii during one optimization iteration for each mapping position
63  * @param maxSpatialCost Maximal spatial cost
64  * @param boundingBoxTop First row of the entire synthesis area
65  * @param boundingBoxHeight Number of rows of the entire synthesis area
66  * @param downIsMain True, if the downwards direction is the main optimization direction (for all subsets with even thread indices)
67  * @param firstColumn First column to be handled in the subset
68  * @param numberColumns Number of columns to be handled in the subset
69  * @param rowOffset Offset within the entire synthesis area (boundingBoxHeight), the subset may be moved by this offset
70  * @param firstRow First row to be handled in the subset
71  * @param numberRows Number of rows to be handled in the subset
72  * @param threadIndex Index of the thread that executes the subset optimization function
73  * @see optimizerSubset().
74  */
75  template <unsigned int tChannels>
76  void 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;
77 
78  protected:
79 
80  /// Specialized layer reference.
82 
83  /// Structural constraints of the optimizer.
85 };
86 
87 template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
89  Optimizer(layer),
90  OptimizerI(layer),
91  OptimizerSubset(layer, randomGenerator),
92  Optimizer1(layer),
93  layerI1_(layer),
94  constraints_(constraints)
95 {
96  if (!constraints_.isEmpty())
97  {
98  constraints_.initializeDecisions(layer.mask().constdata<uint8_t>(), layer.mask().width(), layer.mask().height(), layer.mask().paddingElements());
99  }
100 }
101 
102 template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
103 void Optimizer4NeighborhoodStructuralConstrainedI1<tWeightFactor, tBorderFactor, tUpdateFrame>::optimizeSubset(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
104 {
105  ocean_assert(layerI1_.frame().numberPlanes() == 1u);
106 
107  switch (layerI1_.frame().channels())
108  {
109  case 1u:
110  optimizeSubsetChannels<1u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
111  break;
112 
113  case 2u:
114  optimizeSubsetChannels<2u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
115  break;
116 
117  case 3u:
118  optimizeSubsetChannels<3u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
119  break;
120 
121  case 4u:
122  optimizeSubsetChannels<4u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
123  break;
124 
125  default:
126  ocean_assert(false && "Invalid frame type1");
127  }
128 }
129 
130 template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
131 template <unsigned int tChannels>
132 void Optimizer4NeighborhoodStructuralConstrainedI1<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
133 {
134  const unsigned int layerWidth = layerI1_.width();
135  const unsigned int layerHeight = layerI1_.height();
136  ocean_assert(layerWidth != 0 && layerHeight != 0);
137 
138  const std::vector<int> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
139 
140  Frame& layerFrame = layerI1_.frame();
141  const Frame& layerMask = layerI1_.mask();
142  MappingI1& layerMapping = layerI1_.mapping();
143 
144  ocean_assert(FrameType::formatIsGeneric(layerFrame.pixelFormat(), FrameType::DT_UNSIGNED_INTEGER_8, tChannels));
145  ocean_assert(layerFrame.pixelOrigin() == layerMask.pixelOrigin());
146 
147  ocean_assert(firstColumn + numberColumns <= layerFrame.width());
148  ocean_assert(firstRow + numberRows <= layerFrame.height());
149 
150  RandomGenerator generator(randomGenerator_);
151 
152  uint8_t* const layerFrameData = layerFrame.data<uint8_t>();
153  const uint8_t* const layerMaskData = layerMask.constdata<uint8_t>();
154 
155  const unsigned int layerFramePaddingElements = layerFrame.paddingElements();
156  const unsigned int layerMaskPaddingElements = layerMask.paddingElements();
157  const unsigned int layerMaskStrideElements = layerMask.strideElements();
158 
159 #ifdef OCEAN_DEBUG
160  const PixelBoundingBox& debugLayerBoundingBox = layerI1_.boundingBox();
161  ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.top());
162  ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.bottomEnd());
163 #endif
164 
165  const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
166 
167  const unsigned int xStart = firstColumn;
168  const unsigned int yStart = firstRow;
169  const unsigned int xEnd = firstColumn + numberColumns;
170  const unsigned int yEnd = firstRow + numberRows;
171 
172  ocean_assert(xEnd - xStart <= layerWidth);
173  ocean_assert(yEnd - yStart <= layerHeight);
174 
175  const unsigned int constraintWeightFactor = 180u;
176 
177  if (down)
178  {
179  // find better positions for each mask pixel (top left to bottom right)
180  for (unsigned int yy = yStart; yy < yEnd; ++yy)
181  {
182  const unsigned int y = modulo(int(yy + rowOffset - boundingBoxTop), int(boundingBoxHeight)) + boundingBoxTop;
183 
184  const uint8_t* maskRow = layerMask.constrow<uint8_t>(y) + xStart;
185  PixelPosition* positionRow = layerMapping.row(y) + xStart;
186 
187  for (unsigned int x = xStart; x < xEnd; ++x)
188  {
189  bool foundBetter = false;
190 
191  ocean_assert(maskRow == layerMask.constpixel<uint8_t>(x, y));
192  if (*maskRow != 0xFFu)
193  {
194  unsigned int newPositionX = positionRow->x();
195  unsigned int newPositionY = positionRow->y();
196 
197  const uint64_t oldSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
198  const uint64_t oldColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
199  const uint64_t oldConstraintCost = uint64_t(constraints_.cost(x, y, newPositionX, newPositionY) * Scalar(constraintWeightFactor));
200  uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost + oldConstraintCost;
201 
202  unsigned int testPositionX, testPositionY;
203 
204  // first propagation from left to right
205  ocean_assert(x == 0u || (maskRow - 1) == layerMask.constpixel<uint8_t>(x - 1u, y));
206  if (x > 0u && *(maskRow - 1) != 0xFF)
207  {
208  ocean_assert(layerMapping.position(x - 1, y));
209  ocean_assert(*(positionRow - 1) == layerMapping.position(x - 1, y));
210 
211  // take the position to the left (of the current position)
212  testPositionX = (positionRow - 1)->x() + 1;
213  testPositionY = (positionRow - 1)->y();
214 
215  if (testPositionX < layerWidth && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
216  {
217  // the structure cost is 0 due to the neighbor condition
218  const uint64_t testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
219  + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
220 
221  if (testCost < newCost)
222  {
223  newPositionX = testPositionX;
224  newPositionY = testPositionY;
225  newCost = testCost;
226  foundBetter = true;
227  }
228  }
229 
230  // second propagation from top to bottom
231  ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.constpixel<uint8_t>(x, y - 1u));
232  if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu
233  // test only if the mapping of the left position does not match (shifted) to the mapping of the top position
234  && (positionRow - 1)->northEast() != *(positionRow - layerWidth))
235  {
236  ocean_assert(layerMapping.position(x, y - 1));
237  ocean_assert(*(positionRow - layerWidth) == layerMapping.position(x, y - 1));
238 
239  // take the next position to the top (of the current position)
240  testPositionX = (positionRow - layerWidth)->x();
241  testPositionY = (positionRow - layerWidth)->y() + 1;
242 
243  if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
244  {
245  // the structure cost is 0 due to the neighbor condition
246  const uint64_t testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
247  + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
248 
249  if (testCost < newCost)
250  {
251  newPositionX = testPositionX;
252  newPositionY = testPositionY;
253  newCost = testCost;
254  foundBetter = true;
255  }
256  }
257  }
258  }
259  else
260  {
261  // second propagation from top to bottom
262  ocean_assert(y == 0u || (maskRow - layerMaskStrideElements) == layerMask.constpixel<uint8_t>(x, y - 1u));
263  if (y > 0u && *(maskRow - layerMaskStrideElements) != 0xFFu)
264  {
265  ocean_assert(layerMapping.position(x, y - 1));
266  ocean_assert(*(positionRow - layerWidth) == layerMapping.position(x, y - 1));
267 
268  // take the next position to the top (of the current position)
269  testPositionX = (positionRow - layerWidth)->x();
270  testPositionY = (positionRow - layerWidth)->y() + 1;
271 
272  if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
273  {
274  // the structure cost is 0 due to the neighbor condition
275  const uint64_t testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
276  + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
277 
278  if (testCost < newCost)
279  {
280  newPositionX = testPositionX;
281  newPositionY = testPositionY;
282  newCost = testCost;
283  foundBetter = true;
284  }
285  }
286  }
287  }
288 
289  // find a better position of the current mask pixel
290  for (unsigned int n = 0; n < radii; ++n)
291  {
292  ocean_assert(newPositionX != (unsigned int)(-1) && newPositionY != (unsigned int)(-1));
293 
294  testPositionX = newPositionX + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
295  testPositionY = newPositionY + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
296 
297  // the test position must lie inside the
298  if ((testPositionX == newPositionX && testPositionY == newPositionY)
299  || testPositionX >= layerWidth || testPositionY >= layerHeight
300  || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
301  continue;
302 
303  const uint64_t testSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
304  const uint64_t testColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
305  const uint64_t testConstraintCost = uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
306 
307  const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost + testConstraintCost;
308 
309  if (testCost < newCost)
310  {
311  newPositionX = testPositionX;
312  newPositionY = testPositionY;
313  newCost = testCost;
314  foundBetter = true;
315  }
316  }
317 
318  if (tUpdateFrame && foundBetter)
319  {
320  ocean_assert(layerMask.constpixel<uint8_t>(x, y)[0] != 0xFFu);
321  ocean_assert(layerMask.constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
322 
323  positionRow->setPosition(newPositionX, newPositionY);
324 
325  CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
326  }
327  }
328 
329  ++maskRow;
330  ++positionRow;
331  }
332  }
333  }
334  else // up
335  {
336  // find better positions for each mask pixel (bottom right to top left)
337  for (unsigned int yy = yEnd - 1; yy != yStart - 1; --yy)
338  {
339  const unsigned int y = modulo(int(yy + rowOffset - boundingBoxTop), int(boundingBoxHeight)) + boundingBoxTop;
340 
341  const uint8_t* maskRow = layerMask.constrow<uint8_t>(y) + xEnd - 1u;
342  PixelPosition* positionRow = layerMapping.row(y) + xEnd - 1u;
343 
344  for (unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
345  {
346  bool foundBetter = false;
347 
348  ocean_assert(maskRow == layerMask.constpixel<uint8_t>(x, y));
349  if (*maskRow != 0xFFu)
350  {
351  unsigned int newPositionX = positionRow->x();
352  unsigned int newPositionY = positionRow->y();
353 
354  const uint64_t oldSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
355  const uint64_t oldColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
356  const uint64_t oldConstraintCost = uint64_t(constraints_.cost(x, y, newPositionX, newPositionY) * Scalar(constraintWeightFactor));
357 
358  uint64_t newCost = uint64_t(tWeightFactor) * oldSpatialCost + oldColorCost + oldConstraintCost;
359 
360  unsigned int testPositionX, testPositionY;
361 
362  // first propagation from right to left
363  ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.constpixel<uint8_t>(x + 1u, y));
364  if (x < layerWidth - 1u && *(maskRow + 1) != 0xFFu)
365  {
366  ocean_assert(layerMapping.position(x + 1, y));
367  ocean_assert(*(positionRow + 1) == layerMapping.position(x + 1, y));
368 
369  // take the position to the right (of the current position)
370  testPositionX = (positionRow + 1)->x() - 1;
371  testPositionY = (positionRow + 1)->y();
372 
373  if (testPositionX != (unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
374  {
375  // the structure cost is 0 due to the neighbor condition
376  const uint64_t testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
377  + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
378 
379  if (testCost < newCost)
380  {
381  newPositionX = testPositionX;
382  newPositionY = testPositionY;
383  newCost = testCost;
384  foundBetter = true;
385  }
386  }
387 
388  // second propagation from bottom to top
389  ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.constpixel<uint8_t>(x, y + 1u));
390  if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu
391  // test only if the mapping of the right position does not match (shifted) to the mapping of the bottom position
392  && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
393  {
394  ocean_assert(layerMapping.position(x, y + 1));
395  ocean_assert(*(positionRow + layerWidth) == layerMapping.position(x, y + 1));
396 
397  // take the next position towards the bottom (of the current position)
398  testPositionX = (positionRow + layerWidth)->x();
399  testPositionY = (positionRow + layerWidth)->y() - 1;
400 
401  if (testPositionY != (unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu)
402  {
403  // the structure cost is 0 due to the neighbor condition
404  const uint64_t testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
405  + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
406 
407  if (testCost < newCost)
408  {
409  newPositionX = testPositionX;
410  newPositionY = testPositionY;
411  newCost = testCost;
412  foundBetter = true;
413  }
414  }
415  }
416  }
417  else
418  {
419  // second propagation from bottom to top
420  ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.constpixel<uint8_t>(x, y + 1u));
421  if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
422  {
423  ocean_assert(layerMapping.position(x, y + 1));
424  ocean_assert(*(positionRow + layerWidth) == layerMapping.position(x, y + 1));
425 
426  // take the next position towards the bottom (of the current position)
427  testPositionX = (positionRow + layerWidth)->x();
428  testPositionY = (positionRow + layerWidth)->y() - 1;
429 
430  if (testPositionY != (unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFF)
431  {
432  // the structure cost is 0 due to the neighbor condition
433  const uint64_t testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements)
434  + uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
435 
436  if (testCost < newCost)
437  {
438  newPositionX = testPositionX;
439  newPositionY = testPositionY;
440  newCost = testCost;
441  foundBetter = true;
442  }
443  }
444  }
445  }
446 
447  // find a better position of the current mask pixel
448  for (unsigned int n = 0; n < radii; ++n)
449  {
450  ocean_assert(newPositionX != (unsigned int)(-1) && newPositionY != (unsigned int)(-1));
451 
452  testPositionX = newPositionX + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
453  testPositionY = newPositionY + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
454 
455  if ((testPositionX == newPositionX && testPositionY == newPositionY)
456  || testPositionX >= layerWidth || testPositionY >= layerHeight
457  || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFF)
458  continue;
459 
460  const uint64_t testSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
461  const uint64_t testColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
462  const uint64_t testConstraintCost = uint64_t(constraints_.cost(x, y, testPositionX, testPositionY) * Scalar(constraintWeightFactor));
463 
464  const uint64_t testCost = uint64_t(tWeightFactor) * testSpatialCost + testColorCost + testConstraintCost;
465 
466  if (testCost < newCost)
467  {
468  newPositionX = testPositionX;
469  newPositionY = testPositionY;
470  newCost = testCost;
471  foundBetter = true;
472  }
473  }
474 
475  if (tUpdateFrame && foundBetter)
476  {
477  ocean_assert(layerMask.constpixel<uint8_t>(x, y)[0] != 0xFFu);
478  ocean_assert(layerMask.constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFF);
479 
480  positionRow->setPosition(newPositionX, newPositionY);
481 
482  CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
483  }
484  }
485 
486  --maskRow;
487  --positionRow;
488  }
489  }
490  }
491 }
492 
493 }
494 
495 }
496 
497 }
498 
499 #endif // META_OCEAN_CV_SYNTHESIS_4_NEIGHBORHOOD_STRUCTURAL_CONSTRAINED_I_1_H
T bottomEnd() const
Returns the bottom (excluding) pixel position of this bounding box.
Definition: PixelBoundingBox.h:451
T top() const
Returns the top (including) pixel position of this bounding box.
Definition: PixelBoundingBox.h:423
This class implements a container holding constraints.
Definition: Constraint.h:304
void initializeDecisions(const uint8_t *mask, const unsigned int width, const unsigned int height, const unsigned int maskPaddingElements) const
Initializes the constraint decisions.
bool isEmpty() const
Returns whether this container does not hold any constraint.
Definition: Constraint.h:591
const Frame & mask() const
Returns the mask of this layer.
Definition: Layer.h:184
This class implements a single layer for pixel synthesis within one frame and pixel accuracy.
Definition: LayerI1.h:41
This class implements the pixel mapping between source and target frames.
Definition: MappingI1.h:49
unsigned int spatialCost4Neighborhood(const unsigned int xTarget, const unsigned int yTarget, const unsigned int xSource, const unsigned int ySource, const uint8_t *targetMask, const unsigned int targetMaskPaddingElements, const unsigned int maxCost) const
Calculates the smallest/cheapest spatial cost for a given point in a four-neighborhood and normalizes...
Definition: MappingI1.h:212
unsigned int appearanceCost5x5(const unsigned int xTarget, const unsigned int yTarget, const unsigned int xSource, const unsigned int ySource, const uint8_t *frame, const uint8_t *mask, const unsigned int framePaddingElements, const unsigned int maskPaddingElements) const
Calculates the appearance cost for a given point in a given frame.
Definition: MappingI1.h:634
const PixelPosition * row(const unsigned int y) const
Returns the pointer to a mapping row.
Definition: MappingI.h:243
const PixelPosition & position(const unsigned int x, const unsigned int y) const
Returns the mapping for a given position.
Definition: MappingI.h:215
This class implements the base class for all synthesis optimizers that use one single frame.
Definition: Optimizer1.h:28
This class implements a constrained mapping optimizer for integer mappings.
Definition: Optimizer4NeighborhoodStructuralConstrainedI1.h:39
void optimizeSubset(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 override
Optimizes a subset of the synthesis frame.
Definition: Optimizer4NeighborhoodStructuralConstrainedI1.h:103
Optimizer4NeighborhoodStructuralConstrainedI1(LayerI1 &layer, RandomGenerator &randomGenerator, const Constraints &constraints)
Creates a new optimizer object.
Definition: Optimizer4NeighborhoodStructuralConstrainedI1.h:88
void 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
Specialization of the default subset optimization function.
Definition: Optimizer4NeighborhoodStructuralConstrainedI1.h:132
LayerI1 & layerI1_
Specialized layer reference.
Definition: Optimizer4NeighborhoodStructuralConstrainedI1.h:81
const Constraints & constraints_
Structural constraints of the optimizer.
Definition: Optimizer4NeighborhoodStructuralConstrainedI1.h:84
This class is the base class for all synthesis optimizers.
Definition: Optimizer.h:30
This class is the base class for all optimizers that use a mapping with integer accuracy.
Definition: OptimizerI.h:29
This class is the base class for all optimizers that are able to optimize seperate subsets of the syn...
Definition: OptimizerSubset.h:30
This class implements Ocean's image class.
Definition: Frame.h:1792
unsigned int strideElements(const unsigned int planeIndex=0u) const
Returns the number of elements within one row, including optional padding at the end of a row for a s...
Definition: Frame.h:4058
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4168
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition: Frame.h:4159
const T * constpixel(const unsigned int x, const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific pixel.
Definition: Frame.h:4250
const T * constrow(const unsigned int y, const unsigned int planeIndex=0u) const
Returns the pointer to the constant data of a specific row.
Definition: Frame.h:4193
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition: Frame.h:4042
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3143
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition: Frame.h:3188
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition: Frame.h:3153
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition: Frame.h:41
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3148
static bool formatIsGeneric(const PixelFormat pixelFormat, const DataType dataType, const uint32_t channels, const uint32_t planes=1u, const uint32_t widthMultiple=1u, const uint32_t heightMultiple=1u)
Checks whether a given pixel format is a specific layout regarding data channels and data type.
Definition: Frame.h:3406
This class implements a generator for random numbers.
Definition: RandomGenerator.h:42
static unsigned int random(const unsigned int maxValue)
Returns one random integer value with specified maximum value.
T modulo(const T &value, const T &ring)
Returns the modulo value of a given parameter within a ring allowing positive and negative parameters...
Definition: base/Utilities.h:924
float Scalar
Definition of a scalar type.
Definition: Math.h:128
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15