Ocean
Loading...
Searching...
No Matches
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
18namespace Ocean
19{
20
21namespace CV
22{
23
24namespace 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 */
34template <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
87template <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
102template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
103void 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
130template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
131template <unsigned int tChannels>
132void 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:1808
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:4138
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:4248
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4239
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:4330
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:4273
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:4122
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3170
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition Frame.h:3215
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition Frame.h:3180
@ 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:3175
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:3435
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:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15