Ocean
Loading...
Searching...
No Matches
Optimizer4NeighborhoodAreaConstrainedI1.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_OPTIMIZER_4_NEIGHBORHOOD_AREA_CONSTRAINED_I_1_H
9#define META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_AREA_CONSTRAINED_I_1_H
10
16
17namespace Ocean
18{
19
20namespace CV
21{
22
23namespace Synthesis
24{
25
26/**
27 * This optimizer uses a frame that defines undesired source elements that are avoided during the optimization.
28 * @tparam tWeightFactor Spatial weight impact, with range [0, infinity)
29 * @tparam tBorderFactor Weight factor of border pixels, with range [1, infinity)
30 * @tparam tUpdateFrame True, to update the frame pixel whenever a new mapping has been found
31 * @ingroup cvsynthesis
32 */
33template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
35 virtual public OptimizerI,
36 virtual public OptimizerSubset,
37 virtual public Optimizer1
38{
39 public:
40
41 /**
42 * Creates a new optimizer object.
43 * @param layer Synthesis layer that will be optimized
44 * @param randomGenerator Random number generator
45 * @param filter The filter frame that is used during the optimization
46 */
47 inline Optimizer4NeighborhoodAreaConstrainedI1(LayerI1& layer, RandomGenerator& randomGenerator, const Frame& filter);
48
49 private:
50
51 /**
52 * Optimizes a subset of the synthesis frame.
53 * @see Optimizer1::optimizeSubset().
54 * @see optimizerSubsetChannels().
55 */
56 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;
57
58 /**
59 * Specialization of the default subset optimization function.
60 * The template parameters specified the number of channels the synthesis frame has.<br>
61 * @param radii Number of improvement radii during one optimization iteration for each mapping position
62 * @param maxSpatialCost Maximal spatial cost
63 * @param boundingBoxTop First row of the entire synthesis area
64 * @param boundingBoxHeight Number of rows of the entire synthesis area
65 * @param downIsMain True, if the downwards direction is the main optimization direction (for all subsets with even thread indices)
66 * @param firstColumn First column to be handled in the subset
67 * @param numberColumns Number of columns to be handled in the subset
68 * @param rowOffset Offset within the entire synthesis area (boundingBoxHeight), the subset may be moved by this offset
69 * @param firstRow First row to be handled in the subset
70 * @param numberRows Number of rows to be handled in the subset
71 * @param threadIndex Index of the thread that executes the subset optimization function
72 * @tparam tChannels Number of data channels of the frame
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 /// Filter frame that is used during the optimization.
84 const Frame& filter_;
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 filter_(filter)
95{
96 // nothing to do here
97}
98
99template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
100void Optimizer4NeighborhoodAreaConstrainedI1<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
101{
102 ocean_assert(layerI1_.frame().numberPlanes() == 1u);
103
104 switch (layerI1_.frame().channels())
105 {
106 case 1u:
107 optimizeSubsetChannels<1u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
108 break;
109
110 case 2u:
111 optimizeSubsetChannels<2u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
112 break;
113
114 case 3u:
115 optimizeSubsetChannels<3u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
116 break;
117
118 case 4u:
119 optimizeSubsetChannels<4u>(radii, maxSpatialCost, boundingBoxTop, boundingBoxHeight, downIsMain, firstColumn, numberColumns, rowOffset, firstRow, numberRows, threadIndex);
120 break;
121
122 default:
123 ocean_assert(false && "Invalid frame type.");
124 }
125}
126
127template <unsigned int tWeightFactor, unsigned int tBorderFactor, bool tUpdateFrame>
128template <unsigned int tChannels>
129void Optimizer4NeighborhoodAreaConstrainedI1<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
130{
131 const unsigned int layerWidth = layerI1_.width();
132 const unsigned int layerHeight = layerI1_.height();
133 ocean_assert(layerWidth != 0 && layerHeight != 0);
134
135 const std::vector<int> searchRadii(calculateSearchRadii(radii, layerWidth, layerHeight));
136
137 Frame& layerFrame = layerI1_.frame();
138 const Frame& layerMask = layerI1_.mask();
139 MappingI1& layerMapping = layerI1_.mapping();
140
141 ocean_assert(layerFrame.width() == layerWidth);
142 ocean_assert(layerFrame.height() == layerHeight);
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 const uint8_t* const layerFilterData = filter_.constdata<uint8_t>();
155
156 const unsigned int layerFramePaddingElements = layerFrame.paddingElements();
157 const unsigned int layerMaskPaddingElements = layerMask.paddingElements();
158 const unsigned int layerMaskStrideElements = layerMask.strideElements();
159 const unsigned int layerFilterStrideElements = filter_.strideElements();
160
161#ifdef OCEAN_DEBUG
162 const PixelBoundingBox& debugLayerBoundingBox = layerI1_.boundingBox();
163 ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.top());
164 ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.bottomEnd());
165#endif
166
167 const bool down = (downIsMain && (threadIndex % 2u) == 0u) || (!downIsMain && (threadIndex % 2u) == 1u);
168
169 const unsigned int xStart = firstColumn;
170 const unsigned int yStart = firstRow;
171 const unsigned int xEnd = firstColumn + numberColumns;
172 const unsigned int yEnd = firstRow + numberRows;
173
174 ocean_assert(xEnd - xStart <= layerWidth);
175 ocean_assert(yEnd - yStart <= layerHeight);
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 != 0xFF)
193 {
194 unsigned int newPositionX = positionRow->x();
195 unsigned int newPositionY = positionRow->y();
196
197 const unsigned int oldSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
198 const unsigned int oldColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
199 unsigned int newCost = tWeightFactor * oldSpatialCost + oldColorCost;
200
201 unsigned int testPositionX, testPositionY;
202
203 // first propagation from left to right
204 ocean_assert(x == 0 || maskRow - 1 == layerMask.constpixel<uint8_t>(x - 1u, y));
205 if (x > 0 && *(maskRow - 1) != 0xFF)
206 {
207 ocean_assert(layerMapping.position(x - 1, y));
208 ocean_assert(*(positionRow - 1) == layerMapping.position(x - 1, y));
209
210 // take the position to the left (of the current position)
211 testPositionX = (positionRow - 1)->x() + 1;
212 testPositionY = (positionRow - 1)->y();
213
214 if (testPositionX < layerWidth && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
215 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
216 {
217 // the structure cost is 0 due to the neighbor condition
218 ocean_assert(layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
219
220 const unsigned int testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
221
222 if (testCost < newCost)
223 {
224 newPositionX = testPositionX;
225 newPositionY = testPositionY;
226 newCost = testCost;
227 foundBetter = true;
228 }
229 }
230
231 // second propagation from top to bottom
232 ocean_assert(y == 0 || maskRow - layerMaskStrideElements == layerMask.constpixel<uint8_t>(x, y - 1u));
233 if (y > 0 && *(maskRow - layerMaskStrideElements) != 0xFFu
234 // test only if the mapping of the left position does not match (shifted) to the mapping of the top position
235 && (positionRow - 1)->northEast() != *(positionRow - layerWidth))
236 {
237 ocean_assert(layerMapping.position(x, y - 1));
238 ocean_assert(*(positionRow - layerWidth) == layerMapping.position(x, y - 1));
239
240 // take the next position to the top (of the current position)
241 testPositionX = (positionRow - layerWidth)->x();
242 testPositionY = (positionRow - layerWidth)->y() + 1;
243
244 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
245 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
246 {
247 // the structure cost is 0 due to the neighbor condition
248 ocean_assert(layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
249
250 const unsigned int testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
251
252 if (testCost < newCost)
253 {
254 newPositionX = testPositionX;
255 newPositionY = testPositionY;
256 newCost = testCost;
257 foundBetter = true;
258 }
259 }
260 }
261
262 }
263 else
264 {
265 // second propagation from top to bottom
266 ocean_assert(y == 0 || maskRow - layerMaskStrideElements == layerMask.constpixel<uint8_t>(x, y - 1u));
267 if (y > 0 && *(maskRow - layerMaskStrideElements) != 0xFFu)
268 {
269 ocean_assert(layerMapping.position(x, y - 1));
270 ocean_assert(*(positionRow - layerWidth) == layerMapping.position(x, y - 1));
271
272 // take the next position to the top (of the current position)
273 testPositionX = (positionRow - layerWidth)->x();
274 testPositionY = (positionRow - layerWidth)->y() + 1;
275
276 if (testPositionY < layerHeight && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
277 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
278 {
279 // the structure cost is 0 due to the neighbor condition
280 ocean_assert(layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
281
282 const unsigned int testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
283
284 if (testCost < newCost)
285 {
286 newPositionX = testPositionX;
287 newPositionY = testPositionY;
288 newCost = testCost;
289 foundBetter = true;
290 }
291 }
292 }
293 }
294
295 // find a better position of the current mask pixel
296 for (unsigned int n = 0; n < radii; ++n)
297 {
298 ocean_assert(newPositionX != (unsigned int)(-1) && newPositionY != (unsigned int)(-1));
299
300 testPositionX = newPositionX + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
301 testPositionY = newPositionY + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
302
303 // the test position must not lie inside the mask
304 if ((testPositionX == newPositionX && testPositionY == newPositionY)
305 || testPositionX >= layerWidth || testPositionY >= layerHeight
306 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFFu
307 || layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] != 0xFFu)
308 {
309 continue;
310 }
311
312 const unsigned int testSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
313 const unsigned int testColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
314 const unsigned int testCost = tWeightFactor * testSpatialCost + testColorCost;
315
316 if (testCost < newCost)
317 {
318 newPositionX = testPositionX;
319 newPositionY = testPositionY;
320 newCost = testCost;
321 foundBetter = true;
322 }
323 }
324
325 if (tUpdateFrame && foundBetter)
326 {
327 ocean_assert(layerMask.constpixel<uint8_t>(x, y)[0] != 0xFFu);
328 ocean_assert(layerMask.constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
329
330 positionRow->setPosition(newPositionX, newPositionY);
331
332 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
333 }
334 }
335
336 ++maskRow;
337 ++positionRow;
338 }
339 }
340 }
341 else // up
342 {
343 // find better positions for each mask pixel (bottom right to top left)
344 for (unsigned int yy = yEnd - 1u; yy != yStart - 1u; --yy)
345 {
346 const unsigned int y = modulo(int(yy + rowOffset - boundingBoxTop), int(boundingBoxHeight)) + boundingBoxTop;
347
348 const uint8_t* maskRow = layerMask.constrow<uint8_t>(y) + xEnd - 1u;
349 PixelPosition* positionRow = layerMapping.row(y) + xEnd - 1u;
350
351 for (unsigned int x = xEnd - 1u; x != xStart - 1u; --x)
352 {
353 bool foundBetter = false;
354
355 ocean_assert(maskRow == layerMask.constpixel<uint8_t>(x, y));
356 if (*maskRow != 0xFF)
357 {
358 unsigned int newPositionX = positionRow->x();
359 unsigned int newPositionY = positionRow->y();
360
361 const unsigned int oldSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, newPositionX, newPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
362 const unsigned int oldColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, newPositionX, newPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
363 unsigned int newCost = tWeightFactor * oldSpatialCost + oldColorCost;
364
365 unsigned int testPositionX, testPositionY;
366
367 // first propagation from right to left
368 ocean_assert(x == layerWidth - 1u || (maskRow + 1) == layerMask.constpixel<uint8_t>(x + 1u, y));
369 if (x < layerWidth - 1u && *(maskRow + 1) != 0xFF)
370 {
371 ocean_assert(layerMapping.position(x + 1u, y));
372 ocean_assert(*(positionRow + 1) == layerMapping.position(x + 1u, y));
373
374 // take the position to the right (of the current position)
375 testPositionX = (positionRow + 1)->x() - 1;
376 testPositionY = (positionRow + 1)->y();
377
378 if (testPositionX != (unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
379 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
380 {
381 // the structure cost is 0 due to the neighbor condition
382 ocean_assert(layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
383
384 const unsigned int testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
385
386 if (testCost < newCost)
387 {
388 newPositionX = testPositionX;
389 newPositionY = testPositionY;
390 newCost = testCost;
391 foundBetter = true;
392 }
393 }
394
395 // second propagation from bottom to top
396 ocean_assert(y == layerHeight - 1 || (maskRow + layerMaskStrideElements) == layerMask.constpixel<uint8_t>(x, y + 1u));
397 if (y < layerHeight - 1 && *(maskRow + layerMaskStrideElements) != 0xFF
398 // test only if the mapping of the right position does not match (shifted) to the mapping of the bottom position
399 && (positionRow + 1)->southWest() != *(positionRow + layerWidth))
400 {
401 ocean_assert(layerMapping.position(x, y + 1));
402 ocean_assert(*(positionRow + layerWidth) == layerMapping.position(x, y + 1));
403
404 // take the next position towards the bottom (of the current position)
405 testPositionX = (positionRow + layerWidth)->x();
406 testPositionY = (positionRow + layerWidth)->y() - 1u;
407
408 if (testPositionY != (unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
409 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
410 {
411 // the structure cost is 0 due to the neighbor condition
412 ocean_assert(layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
413
414 const unsigned int testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
415
416 if (testCost < newCost)
417 {
418 newPositionX = testPositionX;
419 newPositionY = testPositionY;
420 newCost = testCost;
421 foundBetter = true;
422 }
423 }
424 }
425 }
426 else
427 {
428 // second propagation from bottom to top
429 ocean_assert(y == layerHeight - 1u || (maskRow + layerMaskStrideElements) == layerMask.constpixel<uint8_t>(x, y + 1u));
430 if (y < layerHeight - 1u && *(maskRow + layerMaskStrideElements) != 0xFFu)
431 {
432 ocean_assert(layerMapping.position(x, y + 1u));
433 ocean_assert(*(positionRow + layerWidth) == layerMapping.position(x, y + 1u));
434
435 // take the next position towards the bottom (of the current position)
436 testPositionX = (positionRow + layerWidth)->x();
437 testPositionY = (positionRow + layerWidth)->y() - 1u;
438
439 if (testPositionY != (unsigned int)(-1) && layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] == 0xFFu
440 && layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] == 0xFFu)
441 {
442 // the structure cost is 0 due to the neighbor condition
443 ocean_assert(layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost) == 0u);
444
445 const unsigned int testCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
446
447 if (testCost < newCost)
448 {
449 newPositionX = testPositionX;
450 newPositionY = testPositionY;
451 newCost = testCost;
452 foundBetter = true;
453 }
454 }
455 }
456 }
457
458 // find a better position of the current mask pixel
459 for (unsigned int n = 0; n < radii; ++n)
460 {
461 ocean_assert(newPositionX != (unsigned int)(-1) && newPositionY != (unsigned int)(-1));
462
463 testPositionX = newPositionX + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
464 testPositionY = newPositionY + RandomI::random(generator, -searchRadii[n], searchRadii[n]);
465
466 if ((testPositionX == newPositionX && testPositionY == newPositionY)
467 || testPositionX >= layerWidth || testPositionY >= layerHeight
468 || layerMaskData[testPositionY * layerMaskStrideElements + testPositionX] != 0xFFu
469 || layerFilterData[testPositionY * layerFilterStrideElements + testPositionX] != 0xFFu)
470 {
471 continue;
472 }
473
474 const unsigned int testSpatialCost = layerMapping.spatialCost4Neighborhood<tChannels>(x, y, testPositionX, testPositionY, layerMaskData, layerMaskPaddingElements, maxSpatialCost);
475 const unsigned int testColorCost = layerMapping.appearanceCost5x5<tChannels, tBorderFactor>(x, y, testPositionX, testPositionY, layerFrameData, layerMaskData, layerFramePaddingElements, layerMaskPaddingElements);
476 const unsigned int testCost = tWeightFactor * testSpatialCost + testColorCost;
477
478 if (testCost < newCost)
479 {
480 newPositionX = testPositionX;
481 newPositionY = testPositionY;
482 newCost = testCost;
483 foundBetter = true;
484 }
485 }
486
487 if (tUpdateFrame && foundBetter)
488 {
489 ocean_assert(layerMask.constpixel<uint8_t>(x, y)[0] != 0xFFu);
490 ocean_assert(layerMask.constpixel<uint8_t>(newPositionX, newPositionY)[0] == 0xFFu);
491
492 positionRow->setPosition(newPositionX, newPositionY);
493
494 CV::CVUtilities::copyPixel<tChannels>(layerFrameData, layerFrameData, x, y, newPositionX, newPositionY, layerWidth, layerWidth, layerFramePaddingElements, layerFramePaddingElements);
495 }
496 }
497
498 --maskRow;
499 --positionRow;
500 }
501 }
502 }
503}
504
505}
506
507}
508
509}
510
511#endif // META_OCEAN_CV_SYNTHESIS_OPTIMIZER_4_NEIGHBORHOOD_AREA_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 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:666
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 optimizer uses a frame that defines undesired source elements that are avoided during the optimi...
Definition Optimizer4NeighborhoodAreaConstrainedI1.h:38
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 Optimizer4NeighborhoodAreaConstrainedI1.h:129
Optimizer4NeighborhoodAreaConstrainedI1(LayerI1 &layer, RandomGenerator &randomGenerator, const Frame &filter)
Creates a new optimizer object.
Definition Optimizer4NeighborhoodAreaConstrainedI1.h:88
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 Optimizer4NeighborhoodAreaConstrainedI1.h:100
const Frame & filter_
Filter frame that is used during the optimization.
Definition Optimizer4NeighborhoodAreaConstrainedI1.h:84
LayerI1 & layerI1_
Specialized layer reference.
Definition Optimizer4NeighborhoodAreaConstrainedI1.h:81
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:4141
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:4251
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4242
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:4333
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:4276
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:4125
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:948
The namespace covering the entire Ocean framework.
Definition Accessor.h:15