Beatmup
Beatmup::NNets::ImageSampler Class Reference

Image preprocessing operation. More...

#include <image_sampler.h>

Inheritance diagram for Beatmup::NNets::ImageSampler:
Beatmup::NNets::AbstractOperation

Public Member Functions

 ImageSampler (const std::string &name, const IntPoint &size, bool centerCrop=true, bool linearInterp=true)
 Creates an instance of image preprocessing operation. More...
 
void setCenterCrop (bool enable)
 Enables / disables center crop. More...
 
bool getCenterCrop () const
 
void setLinearInterpolation (bool enable)
 Enables / disables linear interpolation. More...
 
bool getLinearInterpolation () const
 
void setRotation (int quarterTurns)
 Specifies a rotation to apply to the input image. More...
 
int getRotation () const
 Returns rotation applied to the input image. More...
 
int getInputCount () const
 Returns number of operation inputs. More...
 
int getOutputCount () const
 Returns number of operation outputs. More...
 
bool acceptsTextureInput (int index=0) const
 Returns true if the operation can take a GL::TextureHandler at a specific input. More...
 
bool acceptsTextureOutput (int index=0) const
 Returns true if the operation can take a GL::TextureHandler at a specific output. More...
 
Size getOutputSize (int outputIndex=0) const
 Returns full size of a specific operation output. More...
 
void getOutput (GL::TextureHandler *&texture, int index=0)
 Returns a GL::TextureHandler bound to a specific operation output. More...
 
void setInput (GL::TextureHandler &texture, int inputIndex=0)
 
void setOutput (GL::TextureHandler &texture, int outputIndex=0)
 
std::map< std::string, std::string > serialize () const
 Returns a serialized representation of th operation;. More...
 
void disconnect ()
 Assigns empty inputs and outputs. More...
 
unsigned long countTexelFetches () const
 Counts (approximate) number of texels fetches. More...
 
- Public Member Functions inherited from Beatmup::NNets::AbstractOperation
virtual ~AbstractOperation ()
 
virtual bool usesGpu () const
 Returns true if the operation is run on GPU. More...
 
virtual bool acceptsStorageInput (int index=0) const
 Returns true if the operation can take a Storage::View at a specific input. More...
 
virtual bool acceptsVectorInput (int index=0) const
 Returns true if the operation can take a GL::Vector at a specific input. More...
 
virtual bool acceptsStorageOutput (int index=0) const
 Returns true if the operation can take a Storage::View at a specific output. More...
 
virtual bool acceptsVectorOutput (int index=0) const
 Returns true if the operation can take a GL::Vector at a specific output. More...
 
virtual Storage::View getOutput (int index=0)
 Returns a storage view bound to a specific operation output. More...
 
virtual void getOutput (GL::Vector *&vector, int index=0)
 Returns a GL::Vector bound to a specific operation output. More...
 
virtual void setInput (Storage::View &&storage, int index=0)
 
virtual void setOutput (Storage::View &&storage, int index=0)
 
virtual void setInput (GL::Vector &vector, int index=0)
 
virtual void setOutput (GL::Vector &vector, int index=0)
 
virtual unsigned long countMultiplyAdds () const
 Counts (approximate) number of multiply-adds used by this operation. More...
 
std::string getName () const
 

Static Public Member Functions

static bool initDeserializer ()
 Sets up deserialization of the operation. More...
 

Private Member Functions

void prepare (GraphicPipeline &gpu, ChunkCollection &data, GL::ProgramBank &bank)
 Compiles GLSL shaders. More...
 
void execute (TaskThread &thread, GraphicPipeline &gpu)
 Executes the operation. More...
 
int getInputPadding (int index=0) const
 Retrieves minimum required size of zero padding for a given input. More...
 
void getSampledChannels (int index, int &min, int &max) const
 Retrieves range of input features channels sampled at the same time for a specific input. More...
 

Private Attributes

const IntPoint size
 
GL::TextureHandlerinput
 
GL::TextureHandleroutput
 
GL::RenderingProgramprogram
 
bool linearInterpolation
 if true, the input image is linearly interpolated when possible More...
 
bool centerCrop
 if true, a center crop is performed to sample the output image from the input; otherwise the input is stretched to match the output shape More...
 
int rotation
 clockwise rotation to apply to the input image; 1 unit = 90 degrees More...
 

Additional Inherited Members

- Protected Member Functions inherited from Beatmup::NNets::AbstractOperation
 AbstractOperation (const std::string &name)
 
virtual void execute (TaskThread &thread)
 Executes the operation within a specific CPU thread. More...
 

Detailed Description

Image preprocessing operation.

Samples an image of a fixed size from an arbitrary size texture. Has three key missions. If enabled, performs a center crop keeping the output aspect ratio (otherwise the input is stretched to fit the output). If enabled, uses linear interpolation when possible to reduce aliasing (otherwise nearest neighbor sampling is used). Brings support of OES textures. This allows for example to read data directly from camera in Android.

Definition at line 32 of file image_sampler.h.

Constructor & Destructor Documentation

◆ ImageSampler()

ImageSampler::ImageSampler ( const std::string &  name,
const IntPoint size,
bool  centerCrop = true,
bool  linearInterp = true 
)

Creates an instance of image preprocessing operation.

Parameters
[in]nameLayer name
[in]sizeOutput image size in pixels
[in]centerCropIf true, the center crop is enabled
[in]linearInterpIf true, the linear interpolation is enabled

Definition at line 28 of file image_sampler.cpp.

33  :
35  size(size),
36  input(nullptr), output(nullptr), program(nullptr),
38 {}
AbstractOperation(const AbstractOperation &)=delete
disabling copying constructor
bool linearInterpolation
if true, the input image is linearly interpolated when possible
Definition: image_sampler.h:37
GL::TextureHandler * output
Definition: image_sampler.h:35
bool centerCrop
if true, a center crop is performed to sample the output image from the input; otherwise the input is...
Definition: image_sampler.h:38
GL::TextureHandler * input
Definition: image_sampler.h:35
GL::RenderingProgram * program
Definition: image_sampler.h:36
int rotation
clockwise rotation to apply to the input image; 1 unit = 90 degrees
Definition: image_sampler.h:41

Member Function Documentation

◆ prepare()

void ImageSampler::prepare ( GraphicPipeline gpu,
ChunkCollection data,
GL::ProgramBank bank 
)
privatevirtual

Compiles GLSL shaders.

Parameters
[in,out]gpuA graphic pipeline instance
[in,out]dataChunkfile containing operation data (e.g. weights and biases)
[in,out]bankA program bank with existing GLSL programs to be reused when possible. If a new program is built, it is added to the bank.

Implements Beatmup::NNets::AbstractOperation.

Definition at line 113 of file image_sampler.cpp.

113  {
114  RuntimeError::check(input, "Input is not provided to a ImageSampler operation.");
115 
116  // delete the old program
117  if (program)
118  bank.release(gpu, program);
119 
120  // begin the shader code
122 
123  // declare the sampler
124  code.printf("uniform %s %s;", GL::FragmentShader::DIALECT_SAMPLER_DECL_TYPE, UNIFORM_INPUT);
125 
126  // add main code
127  code.printf(R"glsl(
128  void main() {
129  gl_FragColor = %s(%s, %s);
130  }
132 
133  // init program
134  bool enableExtTexExt = input->getTextureFormat() == GL::TextureHandler::TextureFormat::OES_Ext;
135  program = bank(gpu, code, enableExtTexExt);
136 }
static const char * DIALECT_SAMPLER_DECL_TYPE
glsl type name to declare a texture in Beatmup dialect
Definition: program.h:109
static const char * DIALECT_TEXTURE_SAMPLING_FUNC
glsl function name to sample a texture in Beatmup dialect
Definition: program.h:110
void release(GraphicPipeline &gpu, GL::RenderingProgram *program)
Marks a program as unused any more.
static const char * TEXTURE_COORDINATES_ID
Texture coordinates shader variable name in vertex shader.
static const char * DECLARE_TEXTURE_COORDINATES_IN_FRAG
Declaring texture coordinates in fragment shader.
virtual const TextureFormat getTextureFormat() const =0
Returns the texture format specifying how the shader must interpret the data.
static void check(const bool condition, const std::string &message)
Definition: exception.h:64
StringBuilder including a string container.
static const char * UNIFORM_INPUT

◆ execute()

void ImageSampler::execute ( TaskThread thread,
GraphicPipeline gpu 
)
privatevirtual

Executes the operation.

The operation should be prepared.

Parameters
[in,out]threadCalling CPU thread descriptor
[in,out]gpuA graphic pipeline instance

Implements Beatmup::NNets::AbstractOperation.

Definition at line 139 of file image_sampler.cpp.

139  {
140  if (!program)
141  throw NotReady(this);
142  RuntimeError::check(input, "Input is not provided to a ImageSampler operation.");
143  RuntimeError::check(output, "Output is not provided to a ImageSampler operation.");
144 
145  // enable program
146  program->enable(gpu);
147 
148  // bind output
149  gpu.bindOutput(*output);
150 
151  // bind input
153 
154  // setup texture coordinates
155  const IntPoint inputSize(input->getWidth(), input->getHeight());
156  Rectangle texCoords;
157  if (centerCrop) {
158  float hMargin = 0, vMargin = 0;
159  if (input->getWidth() * output->getHeight() > input->getHeight() * output->getWidth()) {
160  // input is cut vertically
161  hMargin = 0.5f * (input->getWidth() - (float)input->getHeight() * output->getWidth() / output->getHeight());
162  }
163  else {
164  // input is cut horizontally
165  vMargin = 0.5f * (input->getHeight() - (float)input->getWidth() * output->getHeight() / output->getWidth());
166  }
167  texCoords = gpu.getTextureCoordinates(Rectangle(hMargin, vMargin, input->getWidth() - 1 - hMargin, input->getHeight() - 1 - vMargin), inputSize, size);
168  }
169  else {
170  texCoords = gpu.getTextureCoordinates(Rectangle(0, 0, input->getWidth() - 1, input->getHeight() - 1), inputSize, size);
171  }
172 
173  // apply rotation
174  if (rotation % 4 != 0) {
175  Point topLeft(texCoords.a), topRight(texCoords.b.x, texCoords.a.y), bottomLeft(texCoords.a.x, texCoords.b.y), bottomRight(texCoords.b), tmp;
176  switch (rotation % 4) {
177  case 1:
178  tmp = bottomLeft;
179  bottomLeft = bottomRight;
180  bottomRight = topRight;
181  topRight = topLeft;
182  topLeft = tmp;
183  break;
184  case 2:
185  tmp = topLeft;
186  topLeft = bottomRight;
187  bottomRight = tmp;
188  tmp = topRight;
189  topRight = bottomLeft;
190  bottomLeft = tmp;
191  break;
192  case 3:
193  tmp = topLeft;
194  topLeft = topRight;
195  topRight = bottomRight;
196  bottomRight = bottomLeft;
197  bottomLeft = tmp;
198  break;
199  }
200  gpu.setTextureCoordinates(topLeft, topRight, bottomLeft, bottomRight);
201  }
202  else {
203  gpu.setTextureCoordinates(texCoords);
204  }
205 
206  // blend
207  program->blend();
208 }
CustomPoint< numeric > b
Definition: geometry.h:131
CustomPoint< numeric > a
Definition: geometry.h:131
void enable(const GraphicPipeline &gpu)
Definition: program.cpp:250
void blend(bool onScreen)
Definition: program.cpp:548
virtual const int getHeight() const =0
Height of the texture in pixels.
virtual const int getWidth() const =0
Width of the texture in pixels.
static Rectangle getTextureCoordinates(const Rectangle &area, const IntPoint &size, const IntPoint &sampling)
Computes floating-point texture coordinates for pixel-accurate sampling: a texture gets sampled exact...
Definition: pipeline.cpp:976
void bindOutput(AbstractBitmap &bitmap)
Binds a bitmap to the pipeline output.
Definition: pipeline.cpp:891
void setTextureCoordinates(const Rectangle &coords)
Specifies texture coordinates for the next rendering pass.
Definition: pipeline.cpp:966
void bind(GL::TextureHandler &texture, size_t texUnit, const TextureParam param)
Definition: pipeline.cpp:881
CustomRectangle< float > Rectangle
Definition: geometry.h:627
@ INTERP_LINEAR
bilinear pixel interpolation
@ INTERP_NEAREST
nearest neighbor pixel interpolation

◆ getInputPadding()

int Beatmup::NNets::ImageSampler::getInputPadding ( int  index = 0) const
inlineprivatevirtual

Retrieves minimum required size of zero padding for a given input.

Operations that sample a neighborhood of a pixel may need the input to be padded with zeros, if some of the neighboring samples fall out of the are containing data. In Beatmup the zero padding is handled by allocating a bigger input and putting zeros around the area that is actually filled with data.

Returns
number of zero columns and rows to be added to the input area.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 45 of file image_sampler.h.

45 { return 0; }

◆ getSampledChannels()

void Beatmup::NNets::ImageSampler::getSampledChannels ( int  index,
int &  min,
int &  max 
) const
inlineprivatevirtual

Retrieves range of input features channels sampled at the same time for a specific input.

The operation would typically take the entire storage and sample it at once, if needed. If the number of textures in a storage exceeds the number of texture samplers that the GPU may use simultaneously, an exception occurs. This function provides the necessary information to limit the number of textures in the storage when allocating it. When the limit is reached, multiple channels are packed into a single texture in the storage.

Parameters
[in]indexThe input index. Expected to fall in the valid range, i.e. from zero to getInputCount() - 1 inclusive.
[out]minThe minimum number of channels that can be sampled at once
[out]maxThe maximum number of channels that can be sampled at once

Implements Beatmup::NNets::AbstractOperation.

Definition at line 46 of file image_sampler.h.

46 { min = max = 0; }
CustomPoint< numeric > min(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:724
CustomPoint< numeric > max(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:728

◆ setCenterCrop()

void Beatmup::NNets::ImageSampler::setCenterCrop ( bool  enable)
inline

Enables / disables center crop.

Definition at line 66 of file image_sampler.h.

66 { this->centerCrop = enable; }

◆ getCenterCrop()

bool Beatmup::NNets::ImageSampler::getCenterCrop ( ) const
inline

Definition at line 67 of file image_sampler.h.

67 { return this->centerCrop; }

◆ setLinearInterpolation()

void Beatmup::NNets::ImageSampler::setLinearInterpolation ( bool  enable)
inline

Enables / disables linear interpolation.

Definition at line 72 of file image_sampler.h.

72 { this->linearInterpolation = enable; }

◆ getLinearInterpolation()

bool Beatmup::NNets::ImageSampler::getLinearInterpolation ( ) const
inline

Definition at line 73 of file image_sampler.h.

73 { return this->linearInterpolation; }

◆ setRotation()

void Beatmup::NNets::ImageSampler::setRotation ( int  quarterTurns)
inline

Specifies a rotation to apply to the input image.

Parameters
quarterTurnsNumber of times a clockwise rotation by 90 degree is applied to the input image.

Definition at line 79 of file image_sampler.h.

79 { this->rotation = quarterTurns; }

◆ getRotation()

int Beatmup::NNets::ImageSampler::getRotation ( ) const
inline

Returns rotation applied to the input image.

Returns
number of times a clockwise rotation by 90 degree is applied to the input image.

Definition at line 85 of file image_sampler.h.

85 { return this->rotation; }

◆ getInputCount()

int Beatmup::NNets::ImageSampler::getInputCount ( ) const
inlinevirtual

Returns number of operation inputs.

Inputs are then indexed from zero to the returned value minus one inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 87 of file image_sampler.h.

87 { return 1; }

◆ getOutputCount()

int Beatmup::NNets::ImageSampler::getOutputCount ( ) const
inlinevirtual

Returns number of operation outputs.

Outputs are then indexed from zero to the returned value minus one inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 88 of file image_sampler.h.

88 { return 1; }

◆ acceptsTextureInput()

bool Beatmup::NNets::ImageSampler::acceptsTextureInput ( int  index = 0) const
inlinevirtual

Returns true if the operation can take a GL::TextureHandler at a specific input.

Neural network operations may accept different kinds of data containers on inputs and outputs, namely Storage::View, GL::Vector and textures. This function is used to check whether a given operation accepts a texture on input.

Parameters
[in]indexThe input index. Expected to fall in the valid range, i.e. from zero to getInputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 90 of file image_sampler.h.

90 { return index == 0; }
jlong jint index

◆ acceptsTextureOutput()

bool Beatmup::NNets::ImageSampler::acceptsTextureOutput ( int  index = 0) const
inlinevirtual

Returns true if the operation can take a GL::TextureHandler at a specific output.

Neural network operations may accept different kinds of data containers on outputs and outputs, namely Storage::View, GL::Vector and textures. This function is used to check whether a given operation accepts a texture on output.

Parameters
[in]indexThe output index. Expected to fall in the valid range, i.e. from zero to getOutputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 91 of file image_sampler.h.

91 { return index == 0; }

◆ getOutputSize()

Size Beatmup::NNets::ImageSampler::getOutputSize ( int  outputIndex = 0) const
inlinevirtual

Returns full size of a specific operation output.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 93 of file image_sampler.h.

93 { return Size(size.x, size.y, 3); }

◆ getOutput()

void ImageSampler::getOutput ( GL::TextureHandler *&  vector,
int  index = 0 
)
virtual

Returns a GL::TextureHandler bound to a specific operation output.

Parameters
[out]vectorPointer to the GL::TextureHandler. If no texture is bound, becomes null.
[in]indexThe output index. Expected to fall in the valid range, i.e. from zero to getOutputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 41 of file image_sampler.cpp.

41  {
42  InvalidArgument::check(index == 0, "Invalid output index of ImageSampler operation: " + std::to_string(index));
43  texture = this->output;
44 }
static void check(const bool condition, const std::string &message)
Definition: exception.h:75
std::string to_string(Beatmup::NNets::ActivationFunction function)

◆ setInput()

void ImageSampler::setInput ( GL::TextureHandler texture,
int  inputIndex = 0 
)
virtual

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 47 of file image_sampler.cpp.

47  {
48  InvalidArgument::check(inputIndex == 0, "Invalid input index of ImageSampler operation: " + std::to_string(inputIndex));
49  this->input = &texture;
50 }

◆ setOutput()

void ImageSampler::setOutput ( GL::TextureHandler texture,
int  outputIndex = 0 
)
virtual

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 53 of file image_sampler.cpp.

53  {
54  InvalidArgument::check(outputIndex == 0, "Invalid output index of ImageSampler operation: " + std::to_string(outputIndex));
55  InvalidArgument::check(texture.getWidth() == size.x && texture.getHeight() == size.y,
56  "ImageSampler output size mismatch");
57  this->output = &texture;
58 }

◆ serialize()

std::map< std::string, std::string > ImageSampler::serialize ( ) const
virtual

Returns a serialized representation of th operation;.

Implements Beatmup::NNets::AbstractOperation.

Definition at line 90 of file image_sampler.cpp.

90  {
91  return {
92  { "_name", getName() },
93  { "_type", "image_sampler" },
94  { "output_width", std::to_string(size.x) },
95  { "output_height", std::to_string(size.y) },
96  { "linear_interp", linearInterpolation ? "true" : "false" },
97  { "center_crop", centerCrop ? "true" : "false" }
98  };
99 }
std::string getName() const
Definition: operation.h:242

◆ disconnect()

void ImageSampler::disconnect ( )
virtual

Assigns empty inputs and outputs.

Implements Beatmup::NNets::AbstractOperation.

Definition at line 102 of file image_sampler.cpp.

102  {
103  input = output = nullptr;
104 }

◆ countTexelFetches()

unsigned long ImageSampler::countTexelFetches ( ) const
virtual

Counts (approximate) number of texels fetches.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 108 of file image_sampler.cpp.

108  {
109  return size.x * size.y;
110 }

◆ initDeserializer()

static bool Beatmup::NNets::ImageSampler::initDeserializer ( )
static

Sets up deserialization of the operation.

Member Data Documentation

◆ size

const IntPoint Beatmup::NNets::ImageSampler::size
private

Definition at line 34 of file image_sampler.h.

◆ input

GL::TextureHandler* Beatmup::NNets::ImageSampler::input
private

Definition at line 35 of file image_sampler.h.

◆ output

GL::TextureHandler * Beatmup::NNets::ImageSampler::output
private

Definition at line 35 of file image_sampler.h.

◆ program

GL::RenderingProgram* Beatmup::NNets::ImageSampler::program
private

Definition at line 36 of file image_sampler.h.

◆ linearInterpolation

bool Beatmup::NNets::ImageSampler::linearInterpolation
private

if true, the input image is linearly interpolated when possible

Definition at line 37 of file image_sampler.h.

◆ centerCrop

bool Beatmup::NNets::ImageSampler::centerCrop
private

if true, a center crop is performed to sample the output image from the input; otherwise the input is stretched to match the output shape

Definition at line 38 of file image_sampler.h.

◆ rotation

int Beatmup::NNets::ImageSampler::rotation
private

clockwise rotation to apply to the input image; 1 unit = 90 degrees

Definition at line 41 of file image_sampler.h.


The documentation for this class was generated from the following files: