Basic implementation of content-aware image resizing. Still in progress! This is mostly for fun, as Photoshop has an implementation of this called Content Aware Scaling.
Original paper by Shai Avidan and Ariel Shamir.
- Numpy and Pillow (the active fork of PIL). At the moment Pillow is just used for file i/o as all of the actual image manipulation is in numpy, but might use it later for other stuff.
- tqdm for progress bar
- numba is used to speed up the part of the algorithm that uses dynamic programming and thus can't be optimized easily in pure numpy. On a Macbook Pro running OS X Sierra, this cuts the time to crop 100 pixels off
imgs/castle_small.jpgfrom ~60s to ~6s. If you are having a hard time getting numba to install properly on your machine, you can simply comment out the
import numbaand the
@numba.jit()decorator above the
cumulative energyfunction and it should all still run, just a lot slower.
I strongly recommend using
conda to set this up, because otherwise it can potentially be a huge pain to install numba. Otherwise you should probably at least use a virtualenv because a lot of the numpy stack / image processing stack tends to be finicky about dependencies.
Travis builds on Python 2.7, 3.5, and 3.6 (Linux) and it also works (manually installed via conda) on OS X Sierra.
Install Anaconda and then run
conda create env -f environment.yaml, then enter the environment with
source activate seamcarver. Exit the environment with
pip install -r requirements.txt should work locally (assuming you've installed pip), in a virtualenv, or even inside conda.
One positional arg: filename of image to crop
-a --axis What axis to shrink the image on (x or y) -p --pixels How many pixels to crop off the image
-o --output What to name the cropped image. -i --interval Save every i intermediate image. -b --border Whether or not to pad the cropped images to the size of the original. -s --show_seam Whether or not to draw the seam on the image before saving it.
Example: Crop 100 pixels off the height of
imgs/castle_small.jpg and save every 10th iteration, with padding would be
python seam_carver.py imgs/castle_small.jpg -p 100 -a y -b True -i 10
Steps for reizing an image a single direction. The other direction can be done by rotating the image and shoving it through the exact same steps.
- Read in an image
- Calculate the energy function for the whole image
- Calculate the energy of a single pixel, given the values of its neighboring pixels
- Calculate cumulative energy map and seam paths for image
- Find the seam of lowest energy
- Remove seam of lowest energy
- Repeat 2 through 6 until image is as small as specified
- Save resized image.
- Uses the notation where img[x][y] means img[row][col], which is consistent with numpy arrays, but which is supposedly the opposite of the convention in image processing.
- Currently only uses dual energy gradient energy function. As you can see in the vertical resizing example, it slowly decapitates the human figure and ends up scoring the grass as important (probably) due to the many small changes in color across the grass. Different energy functions work well with different types of images, for example, using a forward-energy algorithm would be better at preserving edges.
- Options to rescale by ratio. Instead of putting in the exact number of pixels, can rescale image to 5:3, 3:6, etc ratio.