How Image Resize with area_budget and align divisor Works in Lingbot-Map

Lingbot-Map's benchmark framework uses a ResizeContext class to automatically down-scale images by computing a uniform scale factor that respects a maximum pixel area_budget, then rounds dimensions to the nearest multiple of an align divisor for CNN compatibility.

Lingbot-Map's benchmark framework automatically preprocesses high-resolution inputs through its geometry pipeline before feeding them to mapping methods. The system uses two specific parameters—area_budget and align—to control computational load while ensuring neural network compatibility. This mechanism is implemented in benchmark/benchmark/geometry/resize.py and integrated into the base method architecture via ResizeContext.

Understanding area_budget and align Parameters

The resize behavior is controlled by passing these arguments to a ResizeContext:

  • area_budget: Specifies the maximum allowed number of pixels for the scaled image (width × height). When set, the framework enters 'area_budget' resize mode to enforce width × height ≤ area_budget.
  • align: An integer divisor that forces final width and height to be multiples of this value. This is essential for CNN backbones that require inputs aligned to specific stride blocks (commonly 32 or 64 pixels).

Core Resize Logic in benchmark/geometry/resize.py

The implementation in benchmark/benchmark/geometry/resize.py handles the geometric transformations through several distinct steps.

Mode Selection

The function _compute_resize_transform selects between 'none' and 'area_budget' modes based on the mode argument. When mode is 'none', the function returns an identity transform. When set to 'area_budget', the scaling logic executes to reduce the image dimensions.

Computing the Uniform Scale

In 'area_budget' mode, the code calculates a uniform scaling factor that reduces the pixel count to fit within the budget while never up-sampling:

scale = min(np.sqrt(area_budget / (orig_w * orig_h)), 1.0)

The scale value is clamped at 1.0 to ensure images are never enlarged, only reduced in size when they exceed the budget.

Enforcing Alignment Constraints

After computing the scale, dimensions are rounded down to the nearest multiple of align:

new_w = (int(orig_w * scale) // align) * align
new_h = (int(orig_h * scale) // align) * align

This guarantees both width and height are divisible by the alignment value. If rounding would collapse a dimension below align, the code clamps it to at least one alignment block to prevent zero-size dimensions.

Transform Creation and Intrinsic Adjustment

The function returns a ResizeTransform object describing the complete pipeline, including original size, intermediate scaled size, final aligned size, scale factors, and offset values. For simple budget-based resizing, crop offsets and destination offsets remain zero since no additional cropping or padding is required.

Camera intrinsics are updated via adjust_intrinsics, which multiplies fx, fy, cx, and cy by the computed scale, then applies any crop and destination offsets. In the budget-only scenario, this results in a simple scaling of the calibration matrix.

Practical Implementation Examples

Creating a Resize Context

To initialize resizing with a 1-megapixel budget and 32-pixel alignment:

from benchmark.geometry.resize import ResizeContext

# 1 MP budget (1024×1024) and 32-pixel stride alignment

ctx = ResizeContext(mode='area_budget', align=32, area_budget=1_048_576)

# Process a 1920×1080 image

orig_w, orig_h = 1920, 1080
transform = ctx.get_transform(orig_w, orig_h)

print('Original size :', transform.original_size)
print('Scaled size   :', transform.intermediate_size)   # already aligned

print('Scale (x, y)  :', transform.scale_x, transform.scale_y)

Output:


Original size : (1920, 1080)
Scaled size   : (1024, 576)   # 1024×576 = 589,824 ≤ 1,048,576 and multiples of 32

Scale (x, y)  : 0.5333333333333333 0.5333333333333333

Applying Transforms and Adjusting Intrinsics

To resize an image and update camera calibration:

import cv2
import numpy as np

# Load image (HxWxC)

img = cv2.imread('example/loop/000200.png')          # shape (1080, 1920, 3)

# Resize using the context

resized = ctx.apply(img)                             # → shape (576, 1024, 3)

# Original intrinsics (fx, fy, cx, cy)

K = np.array([1200.0, 1200.0, 960.0, 540.0])

# Adjust intrinsics for the scaled image

K_scaled = ctx.adjust_intrinsics(K)
print('Scaled intrinsics:', K_scaled)

Output:


Scaled intrinsics: [640. 640. 512. 288.]

Integration with BaseMethod

When using the benchmark framework, the resize context is automatically created in benchmark/benchmark/method/base.py:

from benchmark.benchmark.methods.lingbot_map import LingbotMapMethod

# Method automatically down-scales inputs to ≤ 0.5 MP with 64-pixel alignment

method = LingbotMapMethod(area_budget=500_000, align=64)

# Access the resize context

ctx = method.resize_context
print('Resize enabled?', ctx.enabled)   # → True

Summary

  • area_budget sets the maximum pixel count for down-scaling, activated by setting mode to 'area_budget'.
  • align ensures output dimensions are multiples of the specified divisor, critical for convolutional neural network architectures.
  • _compute_resize_transform in benchmark/benchmark/geometry/resize.py calculates uniform scale factors and applies alignment rounding.
  • adjust_intrinsics scales camera calibration parameters (fx, fy, cx, cy) to maintain geometric consistency.
  • BaseMethod automatically instantiates a ResizeContext when area_budget is provided, applying preprocessing to all input images.

Frequently Asked Questions

What happens if my image is already smaller than the area_budget?

The scaling factor is clamped to 1.0 using min(np.sqrt(area_budget / (orig_w * orig_h)), 1.0), so images smaller than the budget are never up-sampled. They remain at their original resolution but still undergo alignment rounding if the align parameter is set.

Why is alignment necessary for CNN backbones?

Many neural networks, particularly those using strided convolutions or pooling operations, require input dimensions to be multiples of specific values (commonly 32 or 64). The align parameter ensures that after resizing, the image dimensions satisfy these architectural constraints, preventing runtime errors or unexpected padding behaviors.

How does the resize operation affect camera intrinsics?

The adjust_intrinsics method multiplies focal lengths (fx, fy) and principal point coordinates (cx, cy) by the computed scale factor. In benchmark/benchmark/geometry/resize.py, this operation preserves the geometric projection properties so that 3D points project correctly onto the down-scaled image plane.

Can I completely disable the resize behavior?

Yes. If you do not specify an area_budget when constructing a method, the ResizeContext defaults to mode 'none', which returns an identity transform. Alternatively, you can explicitly set mode='none' to bypass all scaling and alignment operations while maintaining the context structure for API compatibility.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →