SeamCraft is an interactive desktop application for visualizing content-aware image resizing using Seam Carving and Dijkstra's Shortest Path Algorithm.
The project is currently at Milestone 6, supporting dynamic vertical seam removal with real-time visualization.
| Original Image | Energy Map (Sobel Gradients) | Lowest-Energy Seam |
|---|---|---|
![]() |
![]() |
![]() |
- Interactive SFML desktop application
- Fixed 1200×800 rendering window
- 60 FPS update loop
- Clean window event handling
- Modular application architecture
- Loads a default sample image at startup
- Open images from disk (
O) - Supports PNG, JPG and JPEG
- Reset image to original (
R) - Automatically scales large images while preserving aspect ratio
- Displays images centered inside the window
- Stores both original and working copies of the image
- Displays application status in the window title
- Computes Sobel energy maps after every image update
- Visualizes energy maps in grayscale (
E) - Constructs a pixel graph for seam computation
- Computes minimum-energy vertical seams using Dijkstra's Algorithm
- Automatic seam validation
- Debug statistics printed to the console
- Converts graph nodes back into image coordinates
- Renders the seam as a red overlay (
S) - Removes one seam (
C) - Automatically rebuilds the energy map and graph after every removal
- Saves the current carved image to disk with the
Pkey - Continuous seam carving (
Space)
- Animated seam removal
- Horizontal seam carving
- Image enlargement
- Additional visualization modes
| Component | Technology |
|---|---|
| Language | C++17 |
| Graphics | SFML 3.0.2 |
| Compiler | GCC 16.1.0 |
| Toolchain | MSYS2 UCRT64 |
| IDE | VS Code |
| Platform | Windows 11 |
| File Dialog | tinyfiledialogs |
- Windows 11
- MSYS2 UCRT64
- GCC 16.1.0
- SFML 3.0.2
- VS Code
- Git
Install the required packages from the MSYS2 UCRT64 terminal:
pacman -S --needed \
mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-gdb \
mingw-w64-ucrt-x86_64-sfmlMilestone 6 — Dynamic Vertical Seam Removal
Seam carving requires an energy map that measures the visual importance of every pixel.
SeamCraft computes energy using the Sobel Operator.
For each pixel:
- Convert neighboring pixels to grayscale
Gray = 0.299R + 0.587G + 0.114B
-
Compute horizontal gradient (Gx)
-
Compute vertical gradient (Gy)
-
Compute final energy
Energy = √(Gx² + Gy²)
Border pixels use replicated-border handling, ensuring every pixel has valid neighbors.
The floating-point energy values are normalized into grayscale.
Normalization:
- Find minimum energy
- Find maximum energy
- Scale values into 0–255
Result:
- Black → Low energy
- Gray → Medium energy
- White → High energy
If all pixels have identical energy, the image is rendered completely black.
Every image pixel becomes one graph node.
Each node stores:
- Node ID
- X coordinate
- Y coordinate
- Energy value
Node IDs are deterministic:
nodeId = y × imageWidth + x
Each node connects only to the next row:
- Down-left
- Down
- Down-right
Bottom-row pixels have no outgoing edges.
Each edge weight equals the energy of the destination pixel.
The minimum-energy seam is computed using Dijkstra's Shortest Path Algorithm.
Algorithm overview:
- Every top-row pixel enters the priority queue.
- Nodes are expanded in increasing total energy.
- Edge relaxations update shortest paths.
- Lowest-cost bottom-row node is selected.
- The seam is reconstructed using predecessor links.
Returned seam:
std::vector<unsigned int>Automatic validation verifies:
- Seam length equals image height
- Starts on the first row
- Ends on the last row
- Adjacent seam pixels differ by at most one column
The seam is rendered as a transparent overlay.
Pipeline:
- Convert node IDs back into pixel coordinates
- Create transparent overlay
- Color seam pixels bright red
- Draw using the same scaling transform as the original image
The original image remains unchanged.
The seam remover creates a new image one pixel narrower.
For every row:
- Copy pixels before the seam
- Skip seam pixel
- Shift remaining pixels left
After carving:
- Energy map is rebuilt
- Graph is rebuilt
- Shortest seam is recomputed
- Overlay is updated automatically
| Key | Action |
|---|---|
| O | Open image |
| R | Reset image |
| E | Toggle energy map |
| S | Toggle seam overlay |
| C | Remove one seam |
| P | Save the current carved image |
| Space | Toggle continuous seam carving |
- PNG
- JPG
- JPEG
SeamCraft/
│
├── assets/
│ ├── icons/
│ └── images/
│
├── docs/
│
├── include/
│ ├── Application.hpp
│ ├── DijkstraSolver.hpp
│ ├── EnergyCalculator.hpp
│ ├── EnergyRenderer.hpp
│ ├── ImageManager.hpp
│ ├── PixelGraph.hpp
│ ├── SeamRenderer.hpp
│ ├── SeamRemover.hpp
│ └── Window.hpp
│
├── src/
│ ├── Application.cpp
│ ├── DijkstraSolver.cpp
│ ├── EnergyCalculator.cpp
│ ├── EnergyRenderer.cpp
│ ├── ImageManager.cpp
│ ├── PixelGraph.cpp
│ ├── SeamRenderer.cpp
│ ├── SeamRemover.cpp
│ ├── Window.cpp
│ └── main.cpp
│
├── third_party/
│ └── tinyfiledialogs/
│
├── BUILD.md
├── CONTRIBUTING.md
├── LICENSE
├── PROJECT_PLAN.md
└── README.md
From the project root:
mkdir -p build
gcc -std=c99 -g \
-c third_party/tinyfiledialogs/tinyfiledialogs.c \
-o build/tinyfiledialogs.o
g++ -std=c++17 -Wall -Wextra -pedantic -g \
src/main.cpp \
src/Application.cpp \
src/DijkstraSolver.cpp \
src/Window.cpp \
src/ImageManager.cpp \
src/EnergyCalculator.cpp \
src/EnergyRenderer.cpp \
src/PixelGraph.cpp \
src/SeamRenderer.cpp \
src/SeamRemover.cpp \
build/tinyfiledialogs.o \
-Iinclude \
-Ithird_party/tinyfiledialogs \
-lsfml-graphics \
-lsfml-window \
-lsfml-system \
-lcomdlg32 \
-lole32 \
-o build/SeamCraft.exeOr simply:
- Ctrl + Shift + B → Build
- F5 → Debug
See BUILD.md for the complete setup instructions.
This project is licensed under the MIT License.
Ojas Sugur
Built as part of a deep dive into graph algorithms, image processing, and content-aware image resizing using modern C++.



