I implemented the energy function by looking at each pixel coordinate in R, G, and B channels. I took the difference between the pixel to the left and the pixel to the right and squared the difference. I also took the difference between the pixel above and the pixel below and squared this difference. Then I added the the energy calculations for the R, G, and B channels together to find the total energy of the pixel coordinate.
Finding the seams is a dynamic programming problem. Our base case is the bottom row of our energy matrix. We iteratively move up the rows and for each coordinate, find the minimum cumulative energy from the 3 adjacent coordinates below. After finding a cumulative energy matrix, we start from the top row and find the coordinates with the minimum cumulative energy and store the x-value. Then we move down a row and check which of the 3 adjacent coordinates have the next minimum cumulative energy and store that x-value. The resulting list of x values is the seam with the lowest energy. We can then remove the x value from each row, resulting in the seam being removed.
The current implementation of this function finds a vertical seam. In order to find a horizontal seam but not do excess work, we can rotate and image and find vertical seams on the rotated image. After reducing the image size to our goal, we can rotate the image back to its original orientation
The results of seam carving are shown below. Images were reduced by 25% and 50% either horizontally or vertically. All images are my own.
There were two failure cases in the above examples. In the failure cases, too many seams were removed. In both of my cases, the subject was a person. By removing too many seams, the proportions of faces and body parts becomes distorted.