Seam-carving is a content-aware image resizing technique where the image is reduced in size by one pixel of height (or width) at a time. A vertical seam in an image is a path of pixels connected from the top to the bottom with one pixel in each row; a horizontal seam is a path of pixels connected from the left to the right with one pixel in each column. Below left is the original 505-by-287 pixel image; below right is the result after removing 150 vertical seams, resulting in a 30% narrower image. Unlike standard content-agnostic resizing techniques (such as cropping and scaling), seam carving preserves the most interest features (aspect ratio, set of objects present, etc.) of the image.
The underlying algorithm is simple and elegant, but the technique was not discovered until 2007 by Shai Avidan and Ariel Shamir. Now, it is a core feature in Adobe Photoshop (thanks to a Princeton graduate student) and other computer graphics applications.
Before continuing, please watch the above video.
In this assignment, you will create a data type that resizes a W-by-H image using the seam-carving technique. Finding and removing a seam involves three parts and a tiny bit of notation:
Finding a horizontal seam is analogous.
The SeamCarver API. Your task is to implement the following mutable data type:
public class SeamCarver {
public SeamCarver(Image picture) // create a seam carver object based on
// the given picture
public Image picture() // current picture
public int width() // width of current picture
public int height() // height of current picture
public double energy(int x, int y) // energy of pixel at column x and row y
public int[] findHorizontalSeam() // sequence of indices for horizontal
// seam
public int[] findVerticalSeam() // sequence of indices for vertical seam
public void removeHorizontalSeam(int[] seam) // remove horizontal seam from current
// picture
public void removeVerticalSeam(int[] seam) // remove vertical seam from current
// picture
}
yielding Δx2(1, 2) = 22 + 2042 = 41620;
and pixels (1, 1) and (1, 3) for the y-gradient
yielding Δy2(1, 2) = 1022 = 10404.
Thus, the energy of pixel (1, 2) is 41620 + 10404 = 52024. Similarly, the energy of pixel (1, 1) is 2042 + 1032 = 52225.
yielding Δx2(1, 0) = 2042 = 41616;
and pixels (1, 3) and (1, 1) for the y-gradient
yielding Δy2(1, 2) = 1022 = 10404.
Thus, the energy of pixel (1, 2) is 41616 + 10404 = 52020.
Finding a vertical seam. The findVerticalSeam() method returns an array of length H such that entry i is the column number of the pixel to be removed from row i of the image. For example, consider the 6-by-5 image below (supplied as 6x5.png).
The corresponding pixel energies are shown below, with a minimum energy vertical seam highlighted in pink. In this case, the method findVerticalSeam() returns the array { 3, 4, 3, 2, 2 }.
Analysis of running time. Estimate empirically the running times (in seconds) to remove one row and one column from a W-by-H image as a function of W, and H. Use tilde notation to simplify your answer. Answer the relevant questions in the readme.txt file.
Extra credit.
Submission. Submit SeamCarver.java, and any other files needed by your program (excluding those in stdlib.jar and algs4.jar).
Java files can be found here.
The ImageUtils.java file contains methods that will take an java.awt.Image file (a BufferedImage is suggested)
The methods are documented below: