Skip to content

shadimo11/Image_Processing_Cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 

Repository files navigation

πŸ–ΌοΈ Image Processing in C++

A full implementation of core Digital Image Processing operations in C++, supporting grayscale conversion, image flipping, brightness & contrast adjustment, blur filtering, and 90-degree rotation β€” with no external dependencies.

Language Standard Type Format


πŸ“‹ Table of Contents


Overview

This project implements a custom image processing library in pure C++ with no external dependencies. Images are represented internally as 3D matrices ([height][width][channel]) and are read from and written to the PPM (P3) format β€” a simple, human-readable pixel format.

It is commonly used as a foundation for understanding how image operations work at the pixel level, making it ideal for educational purposes, embedded systems, or any environment where library dependencies must be minimized.


✨ Features

  • βœ… Grayscale Conversion β€” Converts RGB images using the standard luminance formula
  • βœ… Horizontal Flip β€” Mirrors the image left to right
  • βœ… Vertical Flip β€” Mirrors the image top to bottom
  • βœ… Brightness Adjustment β€” Adds a fixed offset to all pixel values with clamping
  • βœ… Contrast Adjustment β€” Scales pixel intensities around the midpoint (128)
  • βœ… Blur Filter β€” Smooths the image using a 3Γ—3 average kernel
  • βœ… 90Β° Clockwise Rotation β€” Rotates the image with swapped dimensions
  • βœ… PPM File I/O β€” Load and save images in the P3 PPM format
  • βœ… No external libraries β€” Pure C++ with STL only
  • βœ… Handles edge cases: border pixels in blur, clamping in brightness/contrast

πŸ”§ How It Works

Each image is stored as a 3D vector<vector<vector<int>>> with dimensions [height][width][channels]. Operations are applied either point-wise (per pixel) or via convolution with a fixed kernel:

Original RGB Image (4Γ—4)              3Γ—3 Average Blur Kernel
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (255,0,0)   (0,255,0)        β”‚      β”‚  1/9  1/9  1/9   β”‚
β”‚ (0,0,255)   (255,255,0)      β”‚  *   β”‚  1/9  1/9  1/9   β”‚  β†’  Blurred Image
β”‚ (255,0,255) (0,255,255)      β”‚      β”‚  1/9  1/9  1/9   β”‚
β”‚ (128,128,0) (0,0,0)          β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Grayscale conversion applies the ITU-R BT.601 luminance formula per pixel:

gray = 0.299Β·R + 0.587Β·G + 0.114Β·B

Blur averages each pixel's 3Γ—3 neighborhood. Border pixels are left unchanged since no padding is applied.

Contrast adjustment scales each pixel around the midpoint to expand or compress the intensity range:

newVal = factor Γ— (pixel βˆ’ 128) + 128   β†’   clamped to [0, 255]

πŸ— Class Overview

Image

Member / Method Type / Return Description
data[height][width][channel] vector<...> Internal 3D pixel storage
Image(int w, int h, int ch = 3) Constructor Creates a blank image of given dimensions
getWidth() / getHeight() / getChannels() int Returns image dimensions and channel count
operator()(int y, int x, int channel) int& Pixel read/write access by row, column, and channel
loadPPM(const string& filename) bool Loads a P3 PPM file from disk
savePPM(const string& filename) bool Saves the image to a P3 PPM file on disk
print() void Prints pixel data to the console (for small images)

Free Functions

Function Description
convertToGrayscale(input) Converts a 3-channel image to a single-channel grayscale
flipHorizontal(input) Mirrors the image along the vertical axis
flipVertical(input) Mirrors the image along the horizontal axis
adjustBrightness(input, value) Adds value to all pixel intensities, clamped to [0,255]
adjustContrast(input, factor) Scales intensities around midpoint 128 by factor
applyBlur(input) Applies a 3Γ—3 uniform averaging filter
rotate90(input) Rotates the image 90 degrees clockwise

πŸš€ Getting Started

Prerequisites

  • C++ compiler supporting C++11 or later (e.g. g++, MSVC, Clang)
  • No external libraries required β€” pure C++ STL only

Compilation

g++ -o image_processor main.cpp -std=c++11
./image_processor

Output Files

After running, the following PPM files will be generated in the working directory:

File Description
test_image.ppm The original 4Γ—4 test input image
gray_image.ppm Grayscale output
flipped_horizontal.ppm Horizontally flipped output
flipped_vertical.ppm Vertically flipped output
bright_image.ppm Brightness-adjusted output (+50)
contrast_image.ppm Contrast-adjusted output (Γ—1.5)
blurred_image.ppm Blurred output (3Γ—3 average)
rotated90_image.ppm 90Β° clockwise rotated output

πŸ’‘ Use an image viewer that supports PPM format, or convert to PNG/JPG using GIMP or ImageMagick:

convert output.ppm output.png

πŸ“– Usage Examples

// Load an image
Image input;
input.loadPPM("test_image.ppm");

// Grayscale conversion
Image gray = convertToGrayscale(input);
gray.savePPM("gray_image.ppm");

// Flip operations
Image flippedH = flipHorizontal(input);
Image flippedV = flipVertical(input);
flippedH.savePPM("flipped_horizontal.ppm");
flippedV.savePPM("flipped_vertical.ppm");

// Brightness and contrast
Image bright   = adjustBrightness(input, 50);    // +50 to all channels
Image contrast = adjustContrast(input, 1.5f);    // 1.5x contrast boost
bright.savePPM("bright_image.ppm");
contrast.savePPM("contrast_image.ppm");

// Blur and rotation
Image blur    = applyBlur(input);
Image rotated = rotate90(input);
blur.savePPM("blurred_image.ppm");
rotated.savePPM("rotated90_image.ppm");

πŸ“š API Reference

Image convertToGrayscale(const Image& input)

Converts each RGB pixel to a single intensity value using the ITU-R BT.601 luminance formula: gray = 0.299Β·R + 0.587Β·G + 0.114Β·B. Returns a new single-channel image.

Time Complexity: O(W Γ— H)

Image flipHorizontal(const Image& input)

Mirrors the image along the vertical axis by mapping each pixel at (y, x) to (y, widthβˆ’1βˆ’x).

Time Complexity: O(W Γ— H Γ— C)

Image flipVertical(const Image& input)

Mirrors the image along the horizontal axis by mapping each pixel at (y, x) to (heightβˆ’1βˆ’y, x).

Time Complexity: O(W Γ— H Γ— C)

Image adjustBrightness(const Image& input, int value)

Adds a fixed integer value (positive to brighten, negative to darken) to every channel of every pixel, then clamps results to [0, 255].

Time Complexity: O(W Γ— H Γ— C)

Image adjustContrast(const Image& input, float factor)

Scales each pixel channel around midpoint 128: newVal = factor Γ— (pixel βˆ’ 128) + 128, clamped to [0, 255]. Values above 1.0 increase contrast; values below 1.0 reduce it.

Time Complexity: O(W Γ— H Γ— C)

Image applyBlur(const Image& input)

Applies a 3Γ—3 box blur by averaging each pixel's 3Γ—3 neighborhood. Border pixels (first/last row and column) are left as 0 due to no border padding.

Time Complexity: O(W Γ— H Γ— C Γ— 9) β‰ˆ O(W Γ— H Γ— C)

Image rotate90(const Image& input)

Rotates the image 90 degrees clockwise by mapping each pixel at (y, x) to (x, heightβˆ’1βˆ’y) in a new image with swapped width and height dimensions.

Time Complexity: O(W Γ— H Γ— C)


πŸ§ͺ Test Cases

The main() function runs a full pipeline on a programmatically generated 4Γ—4 test image covering all implemented operations:

Test Description
1 Test image creation β€” 4Γ—4 pattern with 16 named colors
2 Grayscale conversion β€” single-channel luminance output
3 Horizontal flip β€” pixel position mirror validation
4 Vertical flip β€” pixel position mirror validation
5 Brightness adjustment β€” +50 with overflow clamping
6 Contrast adjustment β€” Γ—1.5 with underflow clamping
7 Blur filter β€” 3Γ—3 averaging on interior pixels
8 90Β° rotation β€” swapped dimensions and pixel remapping

⚠️ Notes

  • Only the P3 (ASCII) PPM format is supported for file I/O
  • Blur border pixels are set to 0 β€” no border padding or pixel replication is applied
  • Grayscale images are saved as 3-channel PPM by repeating the intensity across R, G, B for viewer compatibility
  • adjustContrast uses float arithmetic internally before clamping to avoid integer precision loss
  • All operations return a new image β€” the original input is never modified

πŸ‘₯ Contributors

Name GitHub
Shady Mohamed @shadimo11
Kerolos Safwat @KiroSafwat
Shahira Abdallah @Shahira-Abdallah
Mazen Elkashlan @toshiba-chef-89
Youssef Asaad @Usf132

πŸ“Œ Agile & Project Management

This project is managed using Agile methodology on Jira.

Sprints are organized around function implementation phases as defined in the SRS document, with tasks distributed across team members to minimize blocking dependencies.


πŸ“„ License

This project was developed as part of Winter SWE Training by Fuzetek.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages