1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
|
/*
* Copyright (C) 2017-2019 CS Systemes d'Information (CS SI)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbMultiImageFileWriter_h
#define otbMultiImageFileWriter_h
#include "otbImageFileWriter.h"
#include "otbImage.h"
#include "itkImageBase.h"
#include "itkProcessObject.h"
#include "itkImageIOBase.h"
#include "OTBImageIOExport.h"
#include <boost/shared_ptr.hpp>
namespace otb
{
/** \class MultiImageFileWriter
* \brief Streams a pipeline with multiple outputs.
* It writes each output to a file. Inputs
* are connected to the writer using the AddInputImage method.
* The type of streaming can be chosen. Each output may have a different size.
* When the user gives a number of lines per strip or a tile size, the value
* is interpreted on the first input to deduce the number of streams. This
* number of streams is then used to split the other inputs.
*
* \ingroup OTBImageIO
*/
class OTBImageIO_EXPORT MultiImageFileWriter : public itk::ProcessObject
{
public:
/** Standard class typedefs. */
typedef MultiImageFileWriter Self;
typedef itk::ProcessObject Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
itkNewMacro(Self);
itkTypeMacro(MultiImageFileWriter, itk::ProcessObject);
/** Public typedefs */
typedef itk::ImageBase<2> ImageBaseType;
typedef ImageBaseType::RegionType RegionType;
typedef ImageBaseType::IndexType IndexType;
typedef ImageBaseType::IndexValueType IndexValueType;
typedef ImageBaseType::SizeType SizeType;
typedef ImageBaseType::SizeValueType SizeValueType;
/** Set the streaming mode to 'stripped' and configure the number of strips
* which will be used to stream the image */
void SetNumberOfDivisionsStrippedStreaming(unsigned int nbDivisions);
/** Set the streaming mode to 'tiled' and configure the number of tiles
* which will be used to stream the image */
void SetNumberOfDivisionsTiledStreaming(unsigned int nbDivisions);
/** Set the streaming mode to 'stripped' and configure the number of strips
* which will be used to stream the image with respect to a number of line
* per strip */
void SetNumberOfLinesStrippedStreaming(unsigned int nbLinesPerStrip);
/** Set the streaming mode to 'stripped' and configure the number of MB
* available. The actual number of divisions is computed automatically
* by estimating the memory consumption of the pipeline.
* Setting the availableRAM parameter to 0 means that the available RAM
* is set from the CMake configuration option.
* The bias parameter is a multiplier applied on the estimated memory size
* of the pipeline and can be used to fine tune the potential gap between
* estimated memory and actual memory used, which can happen because of
* composite filters for example */
void SetAutomaticStrippedStreaming(unsigned int availableRAM = 0, double bias = 1.0);
/** Set the streaming mode to 'tiled' and configure the dimension of the tiles
* in pixels for each dimension (square tiles will be generated) */
void SetTileDimensionTiledStreaming(unsigned int tileDimension);
/** Set the streaming mode to 'tiled' and configure the number of MB
* available. The actual number of divisions is computed automatically
* by estimating the memory consumption of the pipeline.
* Tiles will be square.
* Setting the availableRAM parameter to 0 means that the available RAM
* is set from the CMake configuration option
* The bias parameter is a multiplier applied on the estimated memory size
* of the pipeline and can be used to fine tune the potential gap between
* estimated memory and actual memory used, which can happen because of
* composite filters for example */
void SetAutomaticTiledStreaming(unsigned int availableRAM = 0, double bias = 1.0);
/** Set the streaming mode to 'adaptative' and configure the number of MB
* available. The actual number of divisions is computed automatically
* by estimating the memory consumption of the pipeline.
* Tiles will try to match the input file tile scheme.
* Setting the availableRAM parameter to 0 means that the available RAM
* is set from the CMake configuration option */
void SetAutomaticAdaptativeStreaming(unsigned int availableRAM = 0, double bias = 1.0);
virtual void UpdateOutputData(itk::DataObject* itkNotUsed(output)) override;
/** Connect a new input to the multi-writer. Only the input pointer is
* required. If the filename list is empty,
* streaming will occur without writing. It the filename list contains more
* than one element, then the output will be divided into this number of
* granule files. The resolution factor specifies the ratio between the height of this image and the
* height of a reference image. The number of lines per strip class parameter will be modified according to this factor, so
* that images with different resolutions can be streamed together. For example, use 1.0 for a 10m pixels image, 0.5 for a 20m
* pixels image, and specify the number of lines per strip according to the 10m pixels image.
* You may specify top and bottom margins that will be removed from the input image, according to its largest possible region.
*/
template <class TImage>
void AddInputImage(const TImage* inputPtr, const std::string& fileName);
/** Add a new ImageFileWriter to the multi-writer. This is an alternative method
* when you already have an instanciated writer.
*/
template <class TWriter>
void AddInputWriter(typename TWriter::Pointer writer);
virtual void UpdateOutputInformation() override;
virtual void Update() override
{
this->UpdateOutputInformation();
this->UpdateOutputData(NULL);
}
protected:
MultiImageFileWriter();
virtual ~MultiImageFileWriter()
{
}
/** GenerateData calls the Write method for each connected input */
virtual void GenerateData(void) override;
/** GenerateInputRequestedRegion can predict approximate input regions
* based on the requested region of the fake output. Only useful for
* pipeline memory print estimation
*/
virtual void GenerateInputRequestedRegion() override;
/** Computes the number of divisions */
virtual void InitializeStreaming();
/** Goes up the pipeline starting at imagePtr, resetting all requested regions
* to a null region. This may be useful when mixing inputs of different
* resolutions. */
void ResetAllRequestedRegions(ImageBaseType* imagePtr);
/** Returns the current stream region of the given input */
virtual RegionType GetStreamRegion(int inputIndex);
void operator=(const MultiImageFileWriter&) = delete;
void ObserveSourceFilterProgress(itk::Object* object, const itk::EventObject& event)
{
if (typeid(event) != typeid(itk::ProgressEvent))
{
return;
}
itk::ProcessObject* processObject = dynamic_cast<itk::ProcessObject*>(object);
if (processObject)
{
m_DivisionProgress = processObject->GetProgress();
}
this->UpdateFilterProgress();
}
void UpdateFilterProgress()
{
this->UpdateProgress((m_DivisionProgress + m_CurrentDivision) / m_NumberOfDivisions);
}
private:
typedef otb::Image<unsigned char, 2> FakeOutputType;
typedef StreamingManager<FakeOutputType> StreamingManagerType;
/** Streaming manager used for the N inputs */
StreamingManagerType::Pointer m_StreamingManager;
// Division parameters
unsigned int m_NumberOfDivisions;
unsigned int m_CurrentDivision;
float m_DivisionProgress;
bool m_IsObserving;
unsigned long m_ObserverID;
/** \class SinkBase
* Internal base wrapper class to handle each ImageFileWriter
*
* \ingroup OTBImageIO
*/
class SinkBase
{
public:
SinkBase()
{
}
SinkBase(ImageBaseType::ConstPointer inputImage) : m_InputImage(inputImage)
{
}
virtual ~SinkBase()
{
}
virtual ImageBaseType::ConstPointer GetInput() const
{
return m_InputImage;
}
virtual ImageBaseType::Pointer GetInput()
{
return const_cast<ImageBaseType*>(m_InputImage.GetPointer());
}
virtual void WriteImageInformation() = 0;
virtual void Write(const RegionType& streamRegion) = 0;
virtual bool CanStreamWrite() const = 0;
typedef boost::shared_ptr<SinkBase> Pointer;
virtual itk::ImageRegion<2> GetRegionToWrite() const = 0;
protected:
/** The image on which streaming is performed */
ImageBaseType::ConstPointer m_InputImage;
};
/** \class Sink
* Wrapper class for each ImageFileWriter
*
* \ingroup OTBImageIO
*/
template <class TImage>
class Sink : public SinkBase
{
public:
Sink()
{
}
Sink(typename TImage::ConstPointer inputImage, const std::string& filename);
Sink(typename otb::ImageFileWriter<TImage>::Pointer writer);
virtual ~Sink()
{
}
void WriteImageInformation() override;
void Write(const RegionType& streamRegion) override;
bool CanStreamWrite() const override;
typedef boost::shared_ptr<Sink> Pointer;
/** Get the region that should be written. By default this is the largest possible region
* of the input image, but this might be overridden by the box extended filename parameter of
* the input writer */
itk::ImageRegion<2> GetRegionToWrite() const override;
private:
/** Actual writer for this image */
typename otb::ImageFileWriter<TImage>::Pointer m_Writer;
/** An ImageIO used to actually write data to a file */
otb::ImageIOBase::Pointer m_ImageIO;
};
/** The list of inputs and their associated parameters, built using AddInput */
typedef std::vector<boost::shared_ptr<SinkBase>> SinkListType;
SinkListType m_SinkList;
std::vector<RegionType> m_StreamRegionList;
};
} // end of namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbMultiImageFileWriter.hxx"
#endif
#endif // otbMultiImageFileWriter_h
|