The gradient magnitude image is calculated by running a horizontal edge gradient filter and a vertical edge gradient filter over the image and then combining the results. First, a Gaussian blur is applied across the original image to reduce gradient detection of noise in the image. Next, the horizontal and vertical gradient magnitude images are calculated by convolving a simple difference filter over the blurred image. Finally, the two gradient images are added together, normalized, and binarized to 0 or 1 based on an arbitrary threshold (I used 0.3).
By adding a Gaussian blur, the horizontal and vertical derivative filters became less affected by random noise in the image. This meant that the filtered images became much smoother. When I convolved the D_x and D_y filters with the Gaussian blur and then convolved the resulting filter with the original image I got the same result as doing all three separately.
Image straightening was implemented by convolving the image with the horizontal and vertical derivative filters and then calculating the angle of the gradient at each point. After this, the image was rotated through a -20 to +20 degree range from vertical. In each step the number of points with a gradient within 5 degrees of horizontal and vertical were calculated and the rotation with the highest number of these points was selected as the straightened image.
Image "sharpening" was implemented by taking an image, subtracting a Gaussian blur from the image, and then adding the subtraction back into the original image to highlight the high frequencies.
Hybrid images were created by taking the high frequencies of one image (obtained by subtracting the Gaussian blur of an image from the original) and combining it with the low frequencies of another image. The resulting image will look one way from close up and another way from far away based on the frequencies in the image.
Gaussian and Laplacian stack are a way of storing different amounts of Gaussian blurring or Laplacian sharpening. Each layer of the Laplacian stack contained a further subtracted Gaussian to obtain a higher and higher frequency image.
Multi-resolution blending was implemented by breaking down the two images to be blended into Laplacian stacks. The step function for each layer also had to be blended using a Gaussian blur for each subsequent layer. Once each layer had the combination of each Laplacian, they were summed back to get a blended image.