Beatmup
Beatmup::FloodFill Class Reference

Flood fill algorithm implementation. More...

#include <flood_fill.h>

Inheritance diagram for Beatmup::FloodFill:
Beatmup::AbstractTask Beatmup::BitmapContentLock Beatmup::Object

Public Types

enum  BorderMorphology { NONE = 0 , DILATE , ERODE }
 Morphological postprocessing operation applied to discovered connected components. More...
 
- Public Types inherited from Beatmup::AbstractTask
enum class  TaskDeviceRequirement { CPU_ONLY , GPU_OR_CPU , GPU_ONLY }
 Specifies which device (CPU and/or GPU) is used to run the task. More...
 

Public Member Functions

 FloodFill ()
 
 ~FloodFill ()
 
const AbstractBitmapgetInput () const
 Returns input bitmap (null if not set yet) More...
 
const AbstractBitmapgetOutput () const
 Returns output bitmap (null if not set yet) More...
 
IntRectangle getBounds () const
 Returns bounding box of the computed mask. More...
 
int getContourCount () const
 Returns number of detected contours. More...
 
const IntegerContour2DgetContour (int contourIndex) const
 Returns a contour by index if computeContours was true, throws an exception otherwise. More...
 
void setInput (AbstractBitmap *)
 Sets the input bitmap. More...
 
void setOutput (AbstractBitmap *)
 Specifies the bitmap to put the resulting mask to. More...
 
void setMaskPos (const IntPoint &)
 Specifies left-top corner position of the mask to compute inside the input bitmap. More...
 
void setSeeds (const IntPoint seeds[], int seedCount)
 Specifies a set of seeds (starting points) More...
 
void setSeeds (const int seedsXY[], int seedCount)
 
void setTolerance (float)
 Sets the intensity tolerance threshold used to decide on similarity of neighboring pixels. More...
 
float getTolerance () const
 Returns yjr intensity tolerance threshold. More...
 
void setBorderPostprocessing (BorderMorphology operation, float holdRadius, float releaseRadius)
 Specifies a morphological operation to apply to the mask border. More...
 
void setComputeContours (bool)
 Enables or disables contours computation. More...
 
ThreadIndex getMaxThreads () const
 Gives the upper limint on the number of threads the task may be performed by. More...
 
virtual bool process (TaskThread &thread) final
 Executes the task on CPU within a given thread. More...
 
virtual void beforeProcessing (ThreadIndex threadCount, ProcessingTarget target, GraphicPipeline *gpu) final
 Instruction called before the task is executed. More...
 
virtual void afterProcessing (ThreadIndex threadCount, GraphicPipeline *gpu, bool aborted) final
 Instruction called after the task is executed. More...
 
- Public Member Functions inherited from Beatmup::AbstractTask
virtual bool processOnGPU (GraphicPipeline &gpu, TaskThread &thread)
 Executes the task on GPU. More...
 
virtual TaskDeviceRequirement getUsedDevices () const
 Communicates devices (CPU and/or GPU) the task is run on. More...
 
- Public Member Functions inherited from Beatmup::Object
virtual ~Object ()
 

Protected Attributes

AbstractBitmapinput
 input bitmap More...
 
AbstractBitmapoutput
 resulting mask More...
 
AbstractBitmapignoredSeeds
 1-bit bitmap storing flags marking used pixels More...
 
IntPoint maskPos
 left-top corner of the mask to compute over the input bitmap More...
 
IntRectangle bounds
 mask bounds More...
 
std::mutex access
 access control assuring internal thread safety More...
 
std::vector< IntPointseeds
 set of starting points (seed points) More...
 
std::vector< IntegerContour2D * > contours
 contours to store borders for each seed More...
 
BorderMorphology borderMorphology
 border morphological postprocessing More...
 
float tolerance
 intensity tolerance value More...
 
float borderHold
 
float borderRelease
 
bool computeContours
 if true, border contours will be computed per each seed More...
 

Additional Inherited Members

- Static Public Member Functions inherited from Beatmup::AbstractTask
static ThreadIndex validThreadCount (int number)
 Valid thread count from a given integer value. More...
 
- Private Member Functions inherited from Beatmup::BitmapContentLock
 BitmapContentLock ()
 
 ~BitmapContentLock ()
 
void readLock (GraphicPipeline *gpu, AbstractBitmap *bitmap, ProcessingTarget target)
 Locks content of a bitmap for reading using a specific processing target device. More...
 
void writeLock (GraphicPipeline *gpu, AbstractBitmap *bitmap, ProcessingTarget target)
 Locks content of a bitmap for writing using a specific processing target device. More...
 
void unlock (AbstractBitmap *bitmap)
 Drops a lock to the bitmap. More...
 
void unlockAll ()
 Unlocks all the locked bitmaps unconditionally. More...
 
template<const ProcessingTarget target>
void lock (GraphicPipeline *gpu, AbstractBitmap *input, AbstractBitmap *output)
 
void lock (GraphicPipeline *gpu, ProcessingTarget target, AbstractBitmap *input, AbstractBitmap *output)
 
template<const ProcessingTarget target>
void lock (GraphicPipeline *gpu, std::initializer_list< AbstractBitmap * > read, std::initializer_list< AbstractBitmap * > write)
 
template<typename ... Args>
void unlock (AbstractBitmap *first, Args ... others)
 

Detailed Description

Flood fill algorithm implementation.

Discovers areas of similar colors up to a tolerance threshold around given positions (seeds) in the input image. These areas are filled with white color in another image (output). If the output bitmap is a binary mask, corresponding pixels are set to 1. The rest of the output image remains unchanged. Optionally, computes contours around the discovered areas and stores the contour positions. Also optionally, applies post-processing by dilating or eroding the discovered regions in the output image.

Definition at line 36 of file flood_fill.h.

Member Enumeration Documentation

◆ BorderMorphology

Morphological postprocessing operation applied to discovered connected components.

Enumerator
NONE 

no postprocessing

DILATE 

apply a dilatation

ERODE 

apply an erosion

Definition at line 41 of file flood_fill.h.

41  {
42  NONE = 0, //!< no postprocessing
43  DILATE, //!< apply a dilatation
44  ERODE //!< apply an erosion
45  };
@ DILATE
apply a dilatation
Definition: flood_fill.h:43
@ NONE
no postprocessing
Definition: flood_fill.h:42
@ ERODE
apply an erosion
Definition: flood_fill.h:44

Constructor & Destructor Documentation

◆ FloodFill()

FloodFill::FloodFill ( )

Definition at line 28 of file flood_fill.cpp.

28  :
29  input(nullptr), output(nullptr), maskPos(0, 0), bounds(0,0,0,0), borderMorphology(NONE), tolerance(0), borderHold(0), borderRelease(0), computeContours(false)
30 {}
BorderMorphology borderMorphology
border morphological postprocessing
Definition: flood_fill.h:58
AbstractBitmap * output
resulting mask
Definition: flood_fill.h:50
IntPoint maskPos
left-top corner of the mask to compute over the input bitmap
Definition: flood_fill.h:53
float tolerance
intensity tolerance value
Definition: flood_fill.h:60
AbstractBitmap * input
input bitmap
Definition: flood_fill.h:49
IntRectangle bounds
mask bounds
Definition: flood_fill.h:54
bool computeContours
if true, border contours will be computed per each seed
Definition: flood_fill.h:64

◆ ~FloodFill()

FloodFill::~FloodFill ( )

Definition at line 33 of file flood_fill.cpp.

33  {
34  // deleting contours, if any
35  for (IntegerContour2D* contour : contours)
36  delete contour;
37  contours.clear();
38 }
std::vector< IntegerContour2D * > contours
contours to store borders for each seed
Definition: flood_fill.h:57
A sequence of integer-valued 2D points.
Definition: contours.h:33

Member Function Documentation

◆ getInput()

const AbstractBitmap* Beatmup::FloodFill::getInput ( ) const
inline

Returns input bitmap (null if not set yet)

Definition at line 73 of file flood_fill.h.

73 { return input; }

◆ getOutput()

const AbstractBitmap* Beatmup::FloodFill::getOutput ( ) const
inline

Returns output bitmap (null if not set yet)

Definition at line 78 of file flood_fill.h.

78 { return output; }

◆ getBounds()

IntRectangle Beatmup::FloodFill::getBounds ( ) const
inline

Returns bounding box of the computed mask.

Definition at line 83 of file flood_fill.h.

83 { return bounds; }

◆ getContourCount()

int Beatmup::FloodFill::getContourCount ( ) const
inline

Returns number of detected contours.

Definition at line 88 of file flood_fill.h.

88 { return contours.size(); }

◆ getContour()

const IntegerContour2D & FloodFill::getContour ( int  contourIndex) const

Returns a contour by index if computeContours was true, throws an exception otherwise.

Definition at line 173 of file flood_fill.cpp.

173  {
174  RuntimeError::check(contourIndex >= 0 && contourIndex < contours.size(),
175  "Contour index is out of range. Contours computation may have been disabled.");
176  return *contours[contourIndex];
177 }
static void check(const bool condition, const std::string &message)
Definition: exception.h:64

◆ setInput()

void FloodFill::setInput ( AbstractBitmap inputBitmap)

Sets the input bitmap.

Definition at line 41 of file flood_fill.cpp.

41  {
42  this->input = inputBitmap;
43 }

◆ setOutput()

void FloodFill::setOutput ( AbstractBitmap mask)

Specifies the bitmap to put the resulting mask to.

Definition at line 46 of file flood_fill.cpp.

46  {
47  this->output = mask;
48 }

◆ setMaskPos()

void FloodFill::setMaskPos ( const IntPoint pos)

Specifies left-top corner position of the mask to compute inside the input bitmap.

Definition at line 51 of file flood_fill.cpp.

51  {
52  this->maskPos = pos;
53 }

◆ setSeeds() [1/2]

void FloodFill::setSeeds ( const IntPoint  seeds[],
int  seedCount 
)

Specifies a set of seeds (starting points)

Definition at line 56 of file flood_fill.cpp.

56  {
57  this->seeds.clear();
58  for (int n = 0; n < seedCount; n++)
59  this->seeds.push_back(seeds[n]);
60 }
std::vector< IntPoint > seeds
set of starting points (seed points)
Definition: flood_fill.h:56
int n

◆ setSeeds() [2/2]

void FloodFill::setSeeds ( const int  seedsXY[],
int  seedCount 
)

Definition at line 63 of file flood_fill.cpp.

63  {
64  this->seeds.clear();
65  for (int n = 0; n < seedCount; n++)
66  this->seeds.push_back(IntPoint(seedsXY[2*n], seedsXY[2*n+1]));
67 }

◆ setTolerance()

void FloodFill::setTolerance ( float  tolerance)

Sets the intensity tolerance threshold used to decide on similarity of neighboring pixels.

Definition at line 161 of file flood_fill.cpp.

161  {
162  this->tolerance = tolerance;
163 }

◆ getTolerance()

float Beatmup::FloodFill::getTolerance ( ) const
inline

Returns yjr intensity tolerance threshold.

Definition at line 124 of file flood_fill.h.

124 { return tolerance; };

◆ setBorderPostprocessing()

void FloodFill::setBorderPostprocessing ( BorderMorphology  operation,
float  holdRadius,
float  releaseRadius 
)

Specifies a morphological operation to apply to the mask border.

Parameters
operationA postprocessing operation
holdRadiusErosion/dilation hold radius (output values set to 1)
releaseRadiusErosion/dilation radius of transition from 1 to 0

Definition at line 166 of file flood_fill.cpp.

166  {
167  borderMorphology = operation;
168  borderHold = std::max(0.0f, holdRadius);
169  borderRelease = std::max(borderHold, releaseRadius);
170 }
CustomPoint< numeric > max(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:728

◆ setComputeContours()

void FloodFill::setComputeContours ( bool  compute)

Enables or disables contours computation.

Definition at line 70 of file flood_fill.cpp.

70  {
71  this->computeContours = compute;
72 }

◆ getMaxThreads()

ThreadIndex FloodFill::getMaxThreads ( ) const
virtual

Gives the upper limint on the number of threads the task may be performed by.

The actual number of threads running a specific task may be less or equal to the returned value, depending on the number of workers in ThreadPool running the task.

Reimplemented from Beatmup::AbstractTask.

Definition at line 75 of file flood_fill.cpp.

75  {
76  return validThreadCount((int)seeds.size());
77 }
static ThreadIndex validThreadCount(int number)
Valid thread count from a given integer value.
Definition: parallelism.cpp:45

◆ process()

bool FloodFill::process ( TaskThread thread)
finalvirtual

Executes the task on CPU within a given thread.

Generally called by multiple threads.

Parameters
threadassociated task execution context
Returns
true if the execution is finished correctly, false otherwise

Implements Beatmup::AbstractTask.

Definition at line 80 of file flood_fill.cpp.

80  {
81  std::vector<IntPoint> border;
82  border.reserve((output->getWidth() + output->getHeight()) * 2);
83 
84  std::vector<IntegerContour2D*> myContours;
86  bounds.a = bounds.b = seeds[thread.currentThread()];
87 
88  for (int n = thread.currentThread(); n < seeds.size(); n += thread.numThreads())
89  if (!thread.isTaskAborted()) {
90  IntPoint seed = seeds[n];
91  if (seed.x >= maskPos.x && seed.y >= maskPos.y && seed.x < maskPos.x + output->getWidth() && seed.y < maskPos.x + output->getHeight()) {
92  BitmapProcessing::pipelineWithMaskOutput<Kernels::FillRegion>(*input, *output, maskPos, seed, tolerance, border, bounds);
93  }
94  }
95 
96  // compute contours
97  if (!thread.isTaskAborted())
98  if (computeContours) {
100  IntegerContour2D::computeBoundary(myContours, *output, border, writer, 0);
101  }
102 
103  if (!thread.isTaskAborted())
104  switch (borderMorphology) {
105  case DILATE:
106  BitmapProcessing::writeToMask<Kernels::CircularDilatation>(*output, border, 255, borderHold, borderRelease);
107  bounds.grow((int) ceilf(borderHold + borderRelease));
109  break;
110  case ERODE:
111  BitmapProcessing::writeToMask<Kernels::CircularErosion>(*output, border, 255, borderHold, borderRelease);
112  bounds.grow(-(int) floorf(borderHold));
113  break;
114  default: break;
115  }
116 
117  // updating bounds and merging contours
118  {
119  std::lock_guard<std::mutex> lock(access);
120  if (bounds.a.x < this->bounds.a.x) this->bounds.a.x = bounds.a.x;
121  if (bounds.a.y < this->bounds.a.y) this->bounds.a.y = bounds.a.y;
122  if (bounds.b.x > this->bounds.b.x) this->bounds.b.x = bounds.b.x;
123  if (bounds.b.y > this->bounds.b.y) this->bounds.b.y = bounds.b.y;
124 
125  if (computeContours) {
126  contours.reserve(contours.size() + myContours.size());
127  for (auto contour : myContours)
128  contours.push_back(contour);
129  }
130  }
131 
132  return true;
133 }
const ImageResolution getSize() const
Returns the bitmap resolution within ImageResolution object.
void lock(GraphicPipeline *gpu, AbstractBitmap *input, AbstractBitmap *output)
Definition: content_lock.h:84
void limit(const CustomRectangle &frame)
Truncates a rectangle to a limiting frame.
Definition: geometry.h:221
CustomPoint< numeric > b
Definition: geometry.h:131
CustomPoint< numeric > a
Definition: geometry.h:131
void grow(numeric r)
Definition: geometry.h:287
std::mutex access
access control assuring internal thread safety
Definition: flood_fill.h:55
AbstractBitmap * ignoredSeeds
1-bit bitmap storing flags marking used pixels
Definition: flood_fill.h:51
virtual const int getHeight() const =0
Height of the texture in pixels.
virtual const int getWidth() const =0
Width of the texture in pixels.
IntRectangle closedRectangle() const
static void computeBoundary(std::vector< IntegerContour2D * > &boundary, AbstractBitmap &bitmap, std::vector< IntPoint > &border, BinaryMaskWriter &testedPixels, float level=0.5f)
Discovers an area boundary in a bitmap following a level curve, starting from a given set of points.
Definition: contours.cpp:166
A generic to write mask bitmap data lookup tables for masks values.
virtual ThreadIndex numThreads() const =0
ThreadIndex currentThread() const
Definition: parallelism.h:165
virtual bool isTaskAborted() const =0
Returns true if the task is asked to stop from outside.

◆ beforeProcessing()

void FloodFill::beforeProcessing ( ThreadIndex  threadCount,
ProcessingTarget  target,
GraphicPipeline gpu 
)
finalvirtual

Instruction called before the task is executed.

Parameters
threadCountNumber of threads used to perform the task
targetDevice used to perform the task
gpuA graphic pipeline instance; may be null.

Reimplemented from Beatmup::AbstractTask.

Definition at line 136 of file flood_fill.cpp.

136  {
137  NullTaskInput::check(input, "input bitmap");
138  NullTaskInput::check(output, "output bitmap");
139  lock<ProcessingTarget::CPU>(gpu, input, output);
140  for (IntegerContour2D* contour : contours)
141  delete contour;
142  contours.clear();
143  if (computeContours) {
146  std::memset(ignoredSeeds->getData(0, 0), 0, ignoredSeeds->getMemorySize());
147  }
148  bounds.a = bounds.b = seeds[0];
149 }
Context & getContext() const
virtual const pixbyte * getData(int x, int y) const =0
Returns a pointer to given pixel.
virtual const msize getMemorySize() const =0
Bitmap size in bytes.
void writeLock(GraphicPipeline *gpu, AbstractBitmap *bitmap, ProcessingTarget target)
Locks content of a bitmap for writing using a specific processing target device.
Bitmap whose memory is managed by the Beatmup engine.
static void check(const void *pointer, const char *which)
Definition: exception.h:115
@ BinaryMask
1 bit per pixel

◆ afterProcessing()

void FloodFill::afterProcessing ( ThreadIndex  threadCount,
GraphicPipeline gpu,
bool  aborted 
)
finalvirtual

Instruction called after the task is executed.

Parameters
threadCountNumber of threads used to perform the task
gpuGPU to be used to execute the task; may be null.
abortedtrue if the task was aborted

Reimplemented from Beatmup::AbstractTask.

Definition at line 152 of file flood_fill.cpp.

152  {
153  unlock(input, output);
154  if (computeContours) {
156  delete ignoredSeeds;
157  }
158 }
void unlock(AbstractBitmap *bitmap)
Drops a lock to the bitmap.

Member Data Documentation

◆ input

AbstractBitmap* Beatmup::FloodFill::input
protected

input bitmap

Definition at line 49 of file flood_fill.h.

◆ output

AbstractBitmap * Beatmup::FloodFill::output
protected

resulting mask

Definition at line 50 of file flood_fill.h.

◆ ignoredSeeds

AbstractBitmap * Beatmup::FloodFill::ignoredSeeds
protected

1-bit bitmap storing flags marking used pixels

Definition at line 51 of file flood_fill.h.

◆ maskPos

IntPoint Beatmup::FloodFill::maskPos
protected

left-top corner of the mask to compute over the input bitmap

Definition at line 53 of file flood_fill.h.

◆ bounds

IntRectangle Beatmup::FloodFill::bounds
protected

mask bounds

Definition at line 54 of file flood_fill.h.

◆ access

std::mutex Beatmup::FloodFill::access
protected

access control assuring internal thread safety

Definition at line 55 of file flood_fill.h.

◆ seeds

std::vector<IntPoint> Beatmup::FloodFill::seeds
protected

set of starting points (seed points)

Definition at line 56 of file flood_fill.h.

◆ contours

std::vector<IntegerContour2D*> Beatmup::FloodFill::contours
protected

contours to store borders for each seed

Definition at line 57 of file flood_fill.h.

◆ borderMorphology

BorderMorphology Beatmup::FloodFill::borderMorphology
protected

border morphological postprocessing

Definition at line 58 of file flood_fill.h.

◆ tolerance

float Beatmup::FloodFill::tolerance
protected

intensity tolerance value

Definition at line 60 of file flood_fill.h.

◆ borderHold

float Beatmup::FloodFill::borderHold
protected

Definition at line 62 of file flood_fill.h.

◆ borderRelease

float Beatmup::FloodFill::borderRelease
protected

Definition at line 63 of file flood_fill.h.

◆ computeContours

bool Beatmup::FloodFill::computeContours
protected

if true, border contours will be computed per each seed

Definition at line 64 of file flood_fill.h.


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