This project is a C++ image processing application that supports two modes of memory management:
- Conventional mode using
new/delete - Buddy System for custom memory allocation
- Load an image from the command line (JPG, PNG, BMP, etc.)
- Store the image as a 3D matrix:
pixels[height][width][channels] - Display basic image info (dimensions, color channels)
- Allow the user to enter the rotation angle.
- Implement a rotation algorithm using bilinear interpolation to preserve image quality.
- The rotation must be performed on the center of the image.
- If the rotated image generates empty spaces, they should be filled by a constant value (e.g., black or white).
- Allow the user to enter the scaling factor (greater or less than 1.0).
- Use bilinear interpolation to resize the image.
- Maintain image aspect ratio during scaling.
- Display information about the new image size after the operation.
- Implemented a simplified Buddy Allocator for memory allocation
- Toggle between Buddy System and new/delete with a command-line flag
- Compare performance and allocation behavior
- Print
offsetswhen Buddy System is used (for debugging)
- Measure processing time for rotation and scaling operations using
std::chrono. - Measure memory consumption using
mallinfo()orgetrusage()to determine the size of reserved memory. - Display on screen a direct comparison between performance and memory consumption in the two allocation modes.
The program must present a clear output with the following data:
- Original and final dimensions of the image.
- Rotation angle applied.
- Processing time in milliseconds.
- Memory consumption in both modes (Buddy System and conventional).
- Performance difference between both modes.
The image scaling function uses bilinear interpolation to maintain image quality during resizing. Here's how it works:
For a scaling factor
For each pixel in the new image at position
The bilinear interpolation uses four neighboring pixels to compute the new pixel value:
Where:
-
$P_{00}, P_{10}, P_{01}, P_{11}$ are the four neighboring pixels -
$dx, dy$ are the fractional parts of the original coordinates
-
Memory Allocation:
- Creates a new 3D matrix for the scaled image
- Supports both Buddy System and conventional memory allocation
- Properly handles memory cleanup
-
Interpolation Process:
- Maps each new pixel to its position in the original image
- Calculates weights for the four neighboring pixels
- Applies interpolation to each color channel independently
-
Edge Handling:
- Uses
std::minto prevent accessing pixels outside image boundaries - Maintains color accuracy at image edges
- Uses
For a scaling factor of 2.0:
Original Image (4x4) Scaled Image (8x8)
+--------+ +----------------+
| P00 | | P00' P01' |
| P10 | → | P10' P11' |
+--------+ +----------------+
Where each new pixel (P') is calculated using the bilinear interpolation formula.
The system includes comprehensive performance monitoring for both memory allocation modes:
-
Processing Time:
- Measured using
std::chrono::high_resolution_clock - Reported in milliseconds
- Includes both computation and memory allocation time
- Measured using
-
Memory Usage:
- Measured using
mallinfo2()for conventional allocation - Tracks memory allocation and deallocation
- Reported in kilobytes
- Measured using
-
CPU Usage:
- User time: CPU time spent in user code
- System time: CPU time spent in system calls
- Measured using
getrusage() - Reported in milliseconds
[INFO] Escalado de imagen (factor 2.0):
Tiempo de procesamiento: 150 ms
Memoria utilizada: 2048 KB
CPU User: 145 ms
CPU System: 5 ms
Nuevas dimensiones: 800x600
The system allows direct comparison between Buddy System and conventional allocation:
-
Memory Allocation:
- Buddy System: More efficient for large allocations
- Conventional: Better for small, frequent allocations
-
Processing Time:
- Buddy System: Faster for large images due to optimized allocation
- Conventional: More predictable performance across different image sizes
-
CPU Usage:
- Buddy System: Lower system time due to custom allocation
- Conventional: Higher system time due to OS memory management
To improve performance, particularly for computationally intensive tasks like image scaling, the project utilizes OpenMP for parallel processing.
- Targeted Parallelization: The primary loop within the
escalarImagenfunction (responsible for bilinear interpolation) is parallelized using the#pragma omp parallel fordirective. - Mechanism: This directive instructs the compiler to distribute the iterations of the outer loop (iterating over image rows) across multiple available processor cores. Each thread processes a subset of the rows independently.
- Benefit: This significantly reduces the execution time for scaling large images by leveraging multi-core CPU architectures. The speedup is most noticeable on systems with multiple cores.
A simple benchmark scaling the test/testImg/test.png image (540x540) by a factor of 2.0 using conventional memory allocation (-no-buddy) shows the following processing times for the scaling operation itself:
- Multi-threaded (Default OpenMP): ~69 ms
- Single-threaded (
OMP_NUM_THREADS=1): ~84 ms
Note: Actual times may vary based on the system's CPU and current load.
image-processing-system/
│
├── include/ # Header files
│ ├── imagen.h # Image processing class definition
│ └── buddy_allocator.h # Memory allocator implementation
│
├── src/ # Source files
│ ├── main.cpp
│ ├── imagen.cpp
│ ├── buddy_allocator.cpp
│ └── stb_wrapper.cpp
│
├── test/ # Test images
│ └── testImg/
│ ├── image.png
│ ├── image2.png
│ ├── test.png
│ └── test2.jpg
│
├── build/ # Compiled executable
│
├── output/ # Processed images output
│ └── *.png # Generated output images
│
└── Makefile
make all # Build the project and create necessary directories
make clean # Clean all built files and outputs# Scale image to double size
make escalar_2x
# Scale image to half size
make escalar_mitad
# Rotate image by 45 degrees
make rotar
# Run all example operations
make test_all# Custom scaling (e.g., scale by 1.5)
make run ARGS="input.jpg output/result.png escalar 1.5 -buddy"
# Custom rotation (e.g., rotate by 30 degrees)
make run ARGS="input.jpg output/result.png rotar 30 -buddy"./build/image-processing-system <input_image> <output_image> <operation> [parameters] <memory_mode>
# Operations:
- escalar <factor> # Scale image by factor
- rotar <angle> # Rotate image by angle in degrees
# Memory Modes:
- -buddy # Use Buddy System allocator (will also simulate and compare with conventional)
- -no-buddy # Use conventional allocation only- All processed images are saved in the
output/directory - The program displays:
- Image dimensions and channels
- Operation parameters (scale factor or rotation angle)
- Processing time comparison between memory allocation methods
- Output file location
-
Scale Image:
make escalar_2x # Output: output/salida_2x.png -
Rotate Image:
make rotar # Output: output/salida_rotada.png -
Compare Memory Systems:
make run ARGS="test/testImg/test.png output/comparison.png escalar 1.5 -buddy" # This will process the image with both Buddy System and conventional allocation # and display a performance comparison


