Overview
The multiband blending algorithm decomposes images into multiple frequency bands using Laplacian pyramids, blends each band separately, and reconstructs the final image. This approach produces superior results compared to simple alpha blending, especially at seam boundaries.Complete Example
This example is based on thetest_multiband() function from examples/stitch.c:9.
#include "blending.h"
#include "utils.h"
void test_multiband() {
struct timespec start, end;
double duration;
Image img_buf1 = create_image("../files/apple.jpeg");
Image img_buf2 = create_image("../files/orange.jpeg");
The
create_image() function loads JPEG images and returns an Image structure containing the pixel data, width, height, and channel count. Image mask1 = create_image_mask(img_buf1.width, img_buf1.height, 0.1f, 0, 1);
Image mask2 = create_image_mask(img_buf2.width, img_buf2.height, 0.1f, 1, 0);
0.1f - Range parameter (10% of width for transition zone)mask1:0, 1creates a left-to-right gradient (dark to bright)mask2:1, 0creates a right-to-left gradient (bright to dark)
int out = (img_buf1.width * 0.1f);
int out_width = (img_buf1.width * 2) - (out * 2);
StitchRect out_size = {0, 0, out_width, img_buf1.height};
out = 10% of image width)StitchRect structure: {x, y, width, height} int num_bands = 5;
clock_gettime(CLOCK_MONOTONIC, &start);
Blender *b = create_blender(MULTIBAND, out_size, num_bands);
clock_gettime(CLOCK_MONOTONIC, &end);
duration = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
printf("Elapsed time for creating blender: %.2f seconds\n", duration);
MULTIBAND - Blender type (vs. FEATHER)out_size - Output rectangle dimensionsnum_bands - Number of frequency bands (typically 4-7 for best results) clock_gettime(CLOCK_MONOTONIC, &start);
StitchPoint pt1 = {0, 0};
feed(b, &img_buf1, &mask1, pt1);
clock_gettime(CLOCK_MONOTONIC, &end);
duration = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
printf("Elapsed time for feed 1: %.2f seconds\n", duration);
clock_gettime(CLOCK_MONOTONIC, &start);
StitchPoint pt2 = {img_buf2.width - out * 2 - 100, 0};
feed(b, &img_buf2, &mask2, pt2);
clock_gettime(CLOCK_MONOTONIC, &end);
duration = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
printf("Elapsed time for feed 2: %.2f seconds\n", duration);
pt1 places the first image at origin (0, 0)pt2 positions the second image with appropriate overlap clock_gettime(CLOCK_MONOTONIC, &start);
blend(b);
clock_gettime(CLOCK_MONOTONIC, &end);
duration = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
printf("Elapsed time for blend: %.2f seconds\n", duration);
b->result if (b->result.data != NULL) {
if (save_image(&b->result, "merge.jpg")) {
printf("Merged image saved\n");
}
}
destroy_blender(b);
destroy_image(&img_buf1);
destroy_image(&img_buf2);
destroy_image(&mask1);
destroy_image(&mask2);
}
Expected Output
When you run this example, you’ll see timing information:merge.jpg will show a seamless blend of the two input images with no visible seam at the transition zone.
Key Parameters
- num_bands: Higher values (5-7) produce smoother blends but take longer to process
- mask range: The
0.1fparameter controls the transition zone width (10% of image width) - positioning: Careful calculation of
pt2ensures proper overlap between images
Performance Considerations
- Multiband blending is more computationally intensive than feather blending
- The algorithm uses parallel processing where available
- Memory usage scales with the number of bands and image size
- Typical processing time for 1920×1080 images: 0.3-0.5 seconds on modern hardware