Ocean
InitializerCoarserMappingAdaptionSpatialCostMaskI1.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_COARSER_MAPPING_ADAPTION_SPATIAL_COST_MASK_I_1_H
9 #define META_OCEAN_CV_SYNTHESIS_INITIALIZER_COARSER_MAPPING_ADAPTION_SPATIAL_COST_MASK_I_1_H
10 
17 
18 namespace Ocean
19 {
20 
21 namespace CV
22 {
23 
24 namespace Synthesis
25 {
26 
27 /**
28  * This initializer creates an initial mapping by the adaption of an already existing mapping of a coarser synthesis layer and further creates an inpainting mask for the finer layer holding the information of initial mappings with zero spatial costs.
29  * The initializer supports mapping with integer accuracy.<br>
30  * The coarser mapping is upsampled and adjusted to the synthesis mask.
31  * @tparam tFactor The template parameter defines the dimension increase factor between the synthesis layer and the given coarser layer. A factor of 2 means that the width and height of the synthesis layer is two times larger than the width and height of the given coarser layer, must be 2
32  * @tparam tNeighborhood Defines the neighborhood size in that all mappings on the coarser layer must have zero spatial cost so that the corresponding cost mask pixel on the finer layer counts as non-mask pixel (with value 0xFF), either 1 or 9
33  * @see MappingI, LayerI1, InitializerCoarserMappingAdaptionF1, InitializerAreaConstrainedCoarserMappingAdaptionI1.
34  * @ingroup cvsynthesis
35  */
36 template <unsigned int tFactor, const unsigned int tNeighborhood>
38  virtual public InitializerI,
39  virtual public InitializerRandomized,
40  virtual public InitializerSubset,
41  virtual public Initializer1
42 {
43  public:
44 
45  /**
46  * Creates a new initializer object.
47  * @param layer The layer for that the initial mapping has to be provided
48  * @param randomGenerator Random number generator
49  * @param coarserLayer The coarser synthesis layer from that the mapping will be adapted
50  * @param costMask Resulting cost mask for the finer layer
51  */
52  inline InitializerCoarserMappingAdaptionSpatialCostMaskI1(LayerI1& layer, RandomGenerator& randomGenerator, const LayerI1& coarserLayer, Frame& costMask);
53 
54  /**
55  * Invokes the initialization process.
56  * @see Initializer::invoke().
57  */
58  bool invoke(Worker* worker = nullptr) const override;
59 
60  private:
61 
62  /**
63  * Initializes a subset of the entire mapping area.
64  * @see InitializerSubset::initializeSubset().
65  */
66  void initializeSubset(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const override;
67 
68  private:
69 
70  /// Coarser synthesis layer from that the mapping will be adapted.
72 
73  /// Resulting cost map for the finer layer.
75 
76  /// Temporal spatial cost mask for the coarser layer.
78 };
79 
80 template <unsigned int tFactor, const unsigned int tNeighborhood>
82  Initializer(layer),
83  InitializerI(layer),
84  InitializerRandomized(layer, randomGenerator),
85  InitializerSubset(layer),
86  Initializer1(layer),
87  coarserLayerI_(coarserLayer),
88  costMask_(costMask),
89  coarserCostMask_(FrameType(coarserLayer.width(), coarserLayer.height(), FrameType::FORMAT_Y8, coarserLayer.frame().pixelOrigin()))
90 {
91  static_assert(tNeighborhood == 1u || tNeighborhood == 9u, "Invalid neighborhood!");
92 }
93 
94 template <unsigned int tFactor, const unsigned int tNeighborhood>
96 {
97  static_assert(tNeighborhood == 1u || tNeighborhood == 9u, "Invalid neighborhood!");
98 
99  costMask_ = Frame(layer_.mask(), Frame::ACM_COPY_REMOVE_PADDING_LAYOUT);
100 
101  if (!CreatorInformationSpatialCostI1<4u, true>(coarserLayerI_, coarserCostMask_).invoke(worker))
102  {
103  return false;
104  }
105 
106  return InitializerSubset::invoke(worker);
107 }
108 
109 template <unsigned int tFactor, const unsigned int tNeighborhood>
110 void InitializerCoarserMappingAdaptionSpatialCostMaskI1<tFactor, tNeighborhood>::initializeSubset(const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows) const
111 {
112  static_assert(tFactor == 2u, "Invalid factor!");
113  static_assert(tNeighborhood == 1u || tNeighborhood == 9u, "Invalid neighborhood!");
114 
115  const unsigned int width = layerI_.width();
116  const unsigned int height = layerI_.height();
117 
118  const unsigned int coarserWidth = coarserLayerI_.width();
119  const unsigned int coarserHeight = coarserLayerI_.height();
120 
121  ocean_assert(width / tFactor == coarserWidth);
122  ocean_assert(height / tFactor == coarserHeight);
123 
124  MappingI& mapping = layerI_.mapping();
125  const MappingI& coarserMapping = coarserLayerI_.mapping();
126 
127  RandomGenerator randomGenerator(randomGenerator_);
128 
129  const uint8_t* const mask = layerI_.mask().template constdata<uint8_t>();
130  const uint8_t* const coarserMask = coarserLayerI_.mask().template constdata<uint8_t>();
131  uint8_t* const costMask = costMask_.data<uint8_t>();
132  const uint8_t* const coarserCostMask = coarserCostMask_.constdata<uint8_t>();
133 
134  const unsigned int maskStrideElements = layerI_.mask().strideElements();
135  const unsigned int coarserMaskStrideElements = coarserLayerI_.mask().strideElements();
136  const unsigned int costMaskStrideElements = costMask_.strideElements();
137  const unsigned int coarserCostMaskStrideElements = coarserCostMask_.strideElements();
138 
139  for (unsigned int y = firstRow; y < firstRow + numberRows; ++y)
140  {
141  const uint8_t* maskRow = mask + y * maskStrideElements;
142  PixelPosition* positionRow = mapping.row(y);
143 
144  const unsigned int yCoarser = min(y / tFactor, coarserHeight - 1u);
145 
146  const uint8_t* coarserMaskRow = coarserMask + yCoarser * coarserMaskStrideElements;
147  const PixelPosition* coarserPositionRow = coarserMapping.row(yCoarser);
148 
149  for (unsigned int x = firstColumn; x < firstColumn + numberColumns; ++x)
150  {
151  if (maskRow[x] != 0xFFu)
152  {
153  const unsigned int xCoarser = min(x / tFactor, coarserWidth - 1u);
154 
155  // if the corresponding coarser layer pixel is a mask pixel
156  if (coarserMaskRow[xCoarser] != 0xFFu)
157  {
158  const PixelPosition& coarserPosition = coarserPositionRow[xCoarser];
159  ocean_assert(coarserPosition.x() < coarserLayerI_.width());
160  ocean_assert(coarserPosition.y() < coarserLayerI_.height());
161 
162  const unsigned int candidateX = (unsigned int)(int(x) + (int(coarserPosition.x()) - int(xCoarser)) * int(tFactor));
163  const unsigned int candidateY = (unsigned int)(int(y) + (int(coarserPosition.y()) - int(yCoarser)) * int(tFactor));
164 
165  ocean_assert(candidateX < width);
166  ocean_assert(candidateY < height);
167 
168  if (mask[candidateY * maskStrideElements + candidateX] == 0xFFu)
169  {
170  positionRow[x] = CV::PixelPosition(candidateX, candidateY);
171 
172  if constexpr (tNeighborhood == 1u)
173  {
174  if (coarserCostMask[yCoarser * coarserCostMaskStrideElements + xCoarser] == 0x80u)
175  {
176  costMask[y * costMaskStrideElements + x] = 0xFFu;
177  }
178  }
179  else
180  {
181  if (xCoarser - 1u < coarserWidth - 2u && yCoarser - 1u < coarserHeight - 2u)
182  {
183  const uint8_t* const coarserCostData = coarserCostMask + (yCoarser - 1u) * coarserCostMaskStrideElements + (xCoarser - 1u);
184 
185  if (coarserCostData[0] == 0x80u && coarserCostData[1] == 0x80u && coarserCostData[2] == 0x80u
186  && coarserCostData[coarserCostMaskStrideElements + 0u] == 0x80u && coarserCostData[coarserCostMaskStrideElements + 1u] == 0x80u && coarserCostData[coarserCostMaskStrideElements + 2u] == 0x80u
187  && coarserCostData[2u * coarserCostMaskStrideElements + 0u] == 0x80u && coarserCostData[2u * coarserCostMaskStrideElements + 1u] == 0x80u && coarserCostData[2u * coarserCostMaskStrideElements + 2u] == 0x80u)
188  {
189  costMask[y * costMaskStrideElements + x] = 0xFFu;
190  }
191  }
192  else
193  {
194  bool zeroBlock = true;
195 
196  for (int xxCoarser = int(xCoarser) - 1; zeroBlock && xxCoarser <= int(xCoarser) + 1; ++xxCoarser)
197  {
198  for (int yyCoarser = int(yCoarser) - 1; zeroBlock && yyCoarser <= int(yCoarser) + 1; ++yyCoarser)
199  {
200  if ((unsigned int)(xxCoarser) < coarserWidth && (unsigned int)(yyCoarser) < coarserHeight)
201  {
202  if (coarserCostMask[(unsigned int)(yyCoarser) * coarserCostMaskStrideElements + (unsigned int)(xxCoarser)] != 0x80u)
203  {
204  zeroBlock = false;
205  }
206  }
207  }
208  }
209 
210  if (zeroBlock)
211  {
212  costMask[y * costMaskStrideElements + x] = 0xFFu;
213  }
214  }
215 
216  }
217 
218  continue;
219  }
220  }
221 
222  unsigned int candidateX, candidateY;
223  do
224  {
225  candidateX = RandomI::random(randomGenerator, width - 1u);
226  candidateY = RandomI::random(randomGenerator, height - 1u);
227  }
228  while (mask[candidateY * maskStrideElements + candidateX] != 0xFFu);
229 
230  positionRow[x] = CV::PixelPosition(candidateX, candidateY);
231  }
232  }
233  }
234 }
235 
236 }
237 
238 }
239 
240 }
241 
242 #endif // META_OCEAN_CV_SYNTHESIS_INITIALIZER_COARSER_MAPPING_ADAPTION_SPATIAL_COST_MASK_I_1_H
T y() const
Returns the vertical coordinate position of this object.
Definition: PixelPosition.h:470
T x() const
Returns the horizontal coordinate position of this object.
Definition: PixelPosition.h:458
This class implements a creator object that creates a visual representation of the spatial mapping co...
Definition: CreatorInformationSpatialCostI1.h:40
This class is the base class for all initializers that are provided for a single frame only.
Definition: Initializer1.h:29
This initializer creates an initial mapping by the adaption of an already existing mapping of a coars...
Definition: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:42
const LayerI1 & coarserLayerI_
Coarser synthesis layer from that the mapping will be adapted.
Definition: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:71
bool invoke(Worker *worker=nullptr) const override
Invokes the initialization process.
Definition: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:95
InitializerCoarserMappingAdaptionSpatialCostMaskI1(LayerI1 &layer, RandomGenerator &randomGenerator, const LayerI1 &coarserLayer, Frame &costMask)
Creates a new initializer object.
Definition: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:81
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: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:110
Frame & costMask_
Resulting cost map for the finer layer.
Definition: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:74
Frame coarserCostMask_
Temporal spatial cost mask for the coarser layer.
Definition: InitializerCoarserMappingAdaptionSpatialCostMaskI1.h:77
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
bool invoke(Worker *worker=nullptr) const override
Invokes the initialization process.
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:1792
@ ACM_COPY_REMOVE_PADDING_LAYOUT
Same as CM_COPY_REMOVE_PADDING_LAYOUT.
Definition: Frame.h:1818
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition: Frame.h:30
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.
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
PixelPositionT< unsigned int > PixelPosition
Definition of the default PixelPosition object with a data type allowing only positive coordinate val...
Definition: PixelPosition.h:27
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15