Walkthrough & Usage
Line-by-line code walk-through
See the source code (mergeSmallRegionsInPlace.h and mergeSmallRegionsInPlace.cpp) for the full source listing. Here we explain the important parts.
-
struct Pixel { int x,y; };— small POD for BFS queue. -
inline int idx(int x, int y, int width)— maps (x,y) to a linear index intolabels(not into pixel bytes; bytes index uses*4). This makes it simpler to index 2D data in a 1D array. -
sameColor(...)— compares 4 bytes (in RGBA form) at two pixel coordinates for exact equality.It uses exact equalityCompression or anti-aliased edges will produce many colors that are visually similar but not equal.
-
struct Region— collectssize,minX,maxX,minY,maxY, provides conveniencewidth(),height(), andisBigEnough(...). -
Flood-fill labeling loop — For every unlabeled pixel, perform a BFS:
- List
- Flowchart
- Push initial pixel
- Mark its
labels[...] = nextLabel - Add pixel to region:
r.add(x,y) - While queue non-empty
- Pop and consider 4 neighbours
- If their label is
-1andsameColor(...)holds- label them and push to queue
- If their label is
- Pop and consider 4 neighbours
- Now done with nth region:
- Add region to list of regions:
regions.push_back(r) - Increment
nextLabel
- Add region to list of regions:
-
Merge phase: iterate every pixel; if its region is too small (
isBigEnough(...) == false), check the 4 immediate neighbours; if any neighbour is in a different labelnlandregions[nl].isBigEnough(...)is true, copy the neighbour's color bytes into the small pixel and set its label tonl.noteThe merge phase uses the
labelsarray to pick neighbour region IDs and theregionsmetadata to determine which regions are "big".
Example usage
#include "mergeSmallRegionsInPlace.h"
#include <stb_image.h>
#include <stb_image_write.h>
int main() {
int w,h,comp;
unsigned char *img = stbi_load("segmented.png", &w, &h, &comp, 4);
if (!img) return 1;
// Remove tiny islands smaller than 50px and require bbox at least 3x3
mergeSmallRegionsInPlace(img, w, h, 50, 3, 3);
stbi_write_png("cleaned.png", w, h, 4, img, w*4);
stbi_image_free(img);
return 0;
}
Tweak the thresholds to match your use-case.