Ocean
InitializerAppearanceMappingAreaConstrainedI1.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_INITIALIZER_APPEARANCE_MAPPING_AREA_CONSTRAINED_I_1_H
9 #define META_OCEAN_CV_SYNTHESIS_INITIALIZER_APPEARANCE_MAPPING_AREA_CONSTRAINED_I_1_H
10 
19 
20 namespace Ocean
21 {
22 
23 namespace CV
24 {
25 
26 namespace Synthesis
27 {
28 
29 /**
30  * This class implements an initializer that uses appearance constraints for the mapping and further respects a filter that defines undesired source elements.
31  * The initializer is comparable to the standard appearance mapping initializer (InitializerAppearanceMappingI1, InitializerAppearanceMappingF1) while allows for the explicit filtering of source elements.<br>
32  * The matching is provided by a randomized test of best matching positions.
33  * @tparam tPatchSize Defines the patch size for the matching, must be 1
34  * @tparam tIterations Defines the number of random seek iterations for each pixel inside the synthesis mask, with range [1, infinity)
35  * @see InitializerAppearanceMappingI1, InitializerAppearanceMappingF1.
36  * @ingroup cvsynthesis
37  */
38 template <unsigned int tPatchSize, unsigned int tIterations>
40  virtual public InitializerAppearanceMapping,
41  virtual public InitializerAreaConstrained,
42  virtual public InitializerI,
43  virtual public InitializerRandomized,
44  virtual public InitializerSubset,
45  virtual public Initializer1
46 {
47  public:
48 
49  /**
50  * Creates a new initializer object.
51  * The provided filter frame must have the same dimension as the given synthesis layer.<br>
52  * @param layer The layer for that the initial mapping has to be provided
53  * @param randomGenerator Random number generator
54  * @param filter The filter mask that divides the target region into desired and undesired target content
55  */
56  inline InitializerAppearanceMappingAreaConstrainedI1(LayerI1& layer, RandomGenerator& randomGenerator, const Frame& filter);
57 
58  private:
59 
60  /**
61  * Initializes a subset of the entire mapping area.
62  * @see InitializerSubset::initializeSubset().
63  * @see initializeSubsetChannels().
64  */
65  void initializeSubset(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const override;
66 
67  /**
68  * This function is the specialization of the default initializeSubset() function.
69  * @param firstColumn First column of the mapping area to be initialized
70  * @param numberColumns Number of columns of the mapping area to be handled
71  * @param firstRow First row of the mapping area to be initialized
72  * @param numberRows Number of rows of the mapping area to be handled
73  * @tparam tChannels Defines the number of channels the frame has, with range [1, infinity)
74  * @see initializeSubset().
75  */
76  template <unsigned int tChannels>
77  void initializeSubsetChannels(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const;
78 };
79 
80 template <unsigned int tPatchSize, unsigned int tIterations>
82  Initializer(layer),
84  InitializerAreaConstrained(layer, filter),
85  InitializerI(layer),
86  InitializerRandomized(layer, randomGenerator),
87  InitializerSubset(layer),
88  Initializer1(layer)
89 {
90  // nothing to do here
91 }
92 
93 template <unsigned int tPatchSize, unsigned int tIterations>
94 void InitializerAppearanceMappingAreaConstrainedI1<tPatchSize, tIterations>::initializeSubset(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const
95 {
96  static_assert(tPatchSize == 1u, "Invalid patch size!");
97 
98  ocean_assert(layerI_.frame().numberPlanes() == 1u);
99  ocean_assert(layerI_.frame().dataType() == FrameType::DT_UNSIGNED_INTEGER_8);
100 
101  switch (layerI_.frame().channels())
102  {
103  case 1u:
104  initializeSubsetChannels<1u>(firstColumn, numberColumns, firstRow, numberRows);
105  break;
106 
107  case 2u:
108  initializeSubsetChannels<2u>(firstColumn, numberColumns, firstRow, numberRows);
109  break;
110 
111  case 3u:
112  initializeSubsetChannels<3u>(firstColumn, numberColumns, firstRow, numberRows);
113  break;
114 
115  case 4u:
116  initializeSubsetChannels<4u>(firstColumn, numberColumns, firstRow, numberRows);
117  break;
118 
119  default:
120  ocean_assert(false && "Invalid frame type.");
121  }
122 }
123 
124 template <unsigned int tPatchSize, unsigned int tIterations>
125 template <unsigned int tChannels>
126 void InitializerAppearanceMappingAreaConstrainedI1<tPatchSize, tIterations>::initializeSubsetChannels(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const
127 {
128  static_assert(tPatchSize == 1u, "Invalid patch size!");
129  static_assert(tChannels >= 1u, "Invalid channel number!");
130 
131  const unsigned int tPatchSize_2 = tPatchSize / 2u;
132 
133  const unsigned int width = layerI_.width();
134  const unsigned int height = layerI_.height();
135 
136  MappingI& layerMapping = layerI_.mapping();
137 
138  const Frame& frame = layerI_.frame();
139  const Frame& mask = layerI_.mask();
140 
141  ocean_assert(frame.isValid() && mask.isValid());
142 
143  ocean_assert(frame.numberPlanes() == 1u && frame.dataType() == FrameType::DT_UNSIGNED_INTEGER_8);
144  ocean_assert(frame.width() == width);
145  ocean_assert(frame.height() == height);
146 
147  ocean_assert(frame.isFrameTypeCompatible(FrameType(mask, frame.pixelFormat()), false));
148  ocean_assert(mask.isFrameTypeCompatible(filter_, false));
149 
150  RandomGenerator randomGenerator(randomGenerator_);
151 
152  const uint8_t* const frameData = frame.constdata<uint8_t>();
153  const uint8_t* const maskData = mask.constdata<uint8_t>();
154  const uint8_t* const filterData = filter_.template constdata<uint8_t>();
155 
156  const unsigned int framePaddingElements = frame.paddingElements();
157 
158  const unsigned int maskStrideElements = mask.strideElements();
159  const unsigned int filterStrideElements = filter_.strideElements();
160 
161 #ifdef OCEAN_DEBUG
162  const PixelBoundingBox& debugLayerBoundingBox = layerI_.boundingBox();
163  ocean_assert(!debugLayerBoundingBox || firstColumn >= debugLayerBoundingBox.left());
164  ocean_assert(!debugLayerBoundingBox || firstColumn + numberColumns <= debugLayerBoundingBox.rightEnd());
165  ocean_assert(!debugLayerBoundingBox || firstRow >= debugLayerBoundingBox.top());
166  ocean_assert(!debugLayerBoundingBox || firstRow + numberRows <= debugLayerBoundingBox.bottomEnd());
167 #endif
168 
169  ocean_assert(firstColumn + numberColumns <= width);
170  ocean_assert(firstRow + numberRows <= height);
171 
172  for (unsigned int y = firstRow; y < firstRow + numberRows; ++y)
173  {
174  const uint8_t* maskRow = maskData + y * maskStrideElements + firstColumn;
175  PixelPosition* position = layerMapping.row(y) + firstColumn;
176 
177  for (unsigned int x = firstColumn; x < firstColumn + numberColumns; ++x)
178  {
179  if (*maskRow++ != 0xFF)
180  {
181  unsigned int bestX, bestY;
182 
183  do
184  {
185  bestX = RandomI::random(randomGenerator, tPatchSize_2, width - tPatchSize_2 - 1u);
186  bestY = RandomI::random(randomGenerator, tPatchSize_2, height - tPatchSize_2 - 1u);
187  }
188  while (maskData[bestY * maskStrideElements + bestX] != 0xFF || filterData[bestY * filterStrideElements + bestX] != 0xFF);
189 
190  unsigned int bestSSD = CV::SumSquareDifferences::patch8BitPerChannel<tChannels, tPatchSize>(frameData, frameData, width, width, x, y, bestX, bestY, framePaddingElements, framePaddingElements);
191 
192  for (unsigned int n = 1u; n < tIterations; ++n)
193  {
194  const unsigned int candidateX = RandomI::random(randomGenerator, tPatchSize_2, width - tPatchSize_2 - 1u);
195  const unsigned int candidateY = RandomI::random(randomGenerator, tPatchSize_2, height - tPatchSize_2 - 1u);
196 
197  if (maskData[candidateY * maskStrideElements + candidateX] != 0xFF || filterData[candidateY * filterStrideElements + candidateX] != 0xFF)
198  {
199  continue;
200  }
201 
202  const unsigned int candidateSSD = CV::SumSquareDifferences::patch8BitPerChannel<tChannels, tPatchSize>(frameData, frameData, width, width, x, y, candidateX, candidateY, framePaddingElements, framePaddingElements);
203 
204  if (candidateSSD < bestSSD)
205  {
206  bestX = candidateX;
207  bestY = candidateY;
208  bestSSD = candidateSSD;
209  }
210  }
211 
212  position->setPosition(bestX, bestY);
213  }
214 
215  ++position;
216  }
217  }
218 }
219 
220 }
221 
222 }
223 
224 }
225 
226 #endif // META_OCEAN_CV_SYNTHESIS_INITIALIZER_APPEARANCE_MAPPING_AREA_CONSTRAINED_I_1_H
T left() const
Returns the left (including) pixel position of this bounding box.
Definition: PixelBoundingBox.h:416
T rightEnd() const
Returns the right (excluding) pixel position of this bounding box.
Definition: PixelBoundingBox.h:437
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
void setPosition(const T &x, const T &y)
Sets the two coordinate values of this object.
Definition: PixelPosition.h:482
This class is the base class for all initializers that are provided for a single frame only.
Definition: Initializer1.h:29
This class implements an initializer that uses appearance constraints for the mapping and further res...
Definition: InitializerAppearanceMappingAreaConstrainedI1.h:46
InitializerAppearanceMappingAreaConstrainedI1(LayerI1 &layer, RandomGenerator &randomGenerator, const Frame &filter)
Creates a new initializer object.
Definition: InitializerAppearanceMappingAreaConstrainedI1.h:81
void initializeSubsetChannels(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const
This function is the specialization of the default initializeSubset() function.
Definition: InitializerAppearanceMappingAreaConstrainedI1.h:126
void initializeSubset(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const override
Initializes a subset of the entire mapping area.
Definition: InitializerAppearanceMappingAreaConstrainedI1.h:94
This class implements the abstract base class for all appearance initializers.
Definition: InitializerAppearanceMapping.h:28
This class implements a base class for all initializers basing on area constraints.
Definition: InitializerAreaConstrained.h:30
This class implements the base class for all synthesis initializers.
Definition: Initializer.h:34
This class implements the base class for all initializer objects that are applied for mappings with i...
Definition: InitializerI.h:30
This class is the base class for all initializers that mainly initialize the synthesis mapping by a h...
Definition: InitializerRandomized.h:30
This class is the base class for all initializer objects that can separate the initialization process...
Definition: InitializerSubset.h:29
This class implements a single layer for pixel synthesis within one frame and pixel accuracy.
Definition: LayerI1.h:41
This class implements a mapping with integer accuracy.
Definition: MappingI.h:30
const PixelPosition * row(const unsigned int y) const
Returns the pointer to a mapping row.
Definition: MappingI.h:243
This class implements Ocean's image class.
Definition: Frame.h:1760
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:4026
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:4136
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4416
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:4010
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition: Frame.h:30
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3111
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition: Frame.h:3151
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition: Frame.h:3121
@ 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:3116
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition: Frame.h:3131
bool isFrameTypeCompatible(const FrameType &frameType, const bool allowDifferentPixelOrigins) const
Returns whether this frame type is compatible with a given frame type.
Definition: Frame.h:3171
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.
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15