floodFillToRect function
Performs a flood fill algorithm and directly calculates the bounding rectangle without storing all individual points.
Parameters:
binaryPixels: A Matrix representing the binary image.
visited: A Matrix to keep track of visited pixels.
startX: The starting X coordinate for the flood fill.
startY: The starting Y coordinate for the flood fill.
Returns: An IntRect representing the bounding rectangle of the connected region.
Implementation
IntRect floodFillToRect(
final Artifact binaryPixels,
final Artifact visited,
final int startX,
final int startY,
) {
final int width = binaryPixels.cols;
final int height = binaryPixels.rows;
// Initialize bounds to starting point
int minX = startX;
int minY = startY;
int maxX = startX;
int maxY = startY;
// Early bounds check
if (startX >= 0 && startX < width && startY >= 0 && startY < height) {
// Early check for valid starting pixel
if (binaryPixels.cellGet(startX, startY)) {
// Direct access to the underlying arrays
final Uint8List pixelData = binaryPixels.matrix;
final Uint8List visitedData = visited.matrix;
final Queue<int> queue = Queue<int>();
// Calculate initial index
final int startIndex = startY * width + startX;
// Mark start point as visited and add to queue
visitedData[startIndex] = 1;
queue.add(startIndex);
// Direction offsets for adjacent pixels
const List<int> rowOffsets = [0, 0, -1, 1]; // Row adjustments
const List<int> colOffsets = [-1, 1, 0, 0]; // Column adjustments
while (queue.isNotEmpty) {
final int currentIndex = queue.removeFirst();
final int x = currentIndex % width;
final int y = currentIndex ~/ width;
// Update bounds
minX = min(minX, x);
minY = min(minY, y);
maxX = max(maxX, x);
maxY = max(maxY, y);
// Check all four directions
for (int i = 0; i < 4; i++) {
final int nx = x + colOffsets[i];
final int ny = y + rowOffsets[i];
// Skip out-of-bounds
if (nx < 0 || nx >= width || ny < 0 || ny >= height) {
continue;
}
final int neighborIndex = ny * width + nx;
// Check if neighbor is valid and not visited
if (pixelData[neighborIndex] == 1 &&
visitedData[neighborIndex] == 0) {
visitedData[neighborIndex] = 1;
queue.add(neighborIndex);
}
}
}
}
}
// Calculate width and height
final int regionWidth = maxX - minX + 1;
final int regionHeight = maxY - minY + 1;
return IntRect.fromLTWH(minX, minY, regionWidth, regionHeight);
}