Project 1: Image Filtering and Hybrid Images

Fig. 1. One layer of the image with extended edges, before being filtered.

The high-level steps taken for this project are listed below. They are described in greater detail in following sections.

  1. Get dimensions for image and filter.
  2. Create a new 3-dimensional image initialized with zeroes with dimensions matching the original image (with extended edges).
  3. For each color layer, pad the edges by extending the pixels to maintain color consistency (Fig. 1).
  4. Iterate through each color layer in rectangles matching the size of the filter. For each rectangle, calculate the average dot product of that rectangle and the filter.
  5. Take this calculated value and store it at the center of the rectangle in the new image (at the appropriate layer) initialized in step 2.
  6. Once finished building the new image, trim down the edges so that the dimensions are the same as the original image.


Choosing Dimensions

The amount of padding is calculated by finding the length of the filter, and dividing it by two (floored to avoid decimals). The extended dimensions of the new image are the length of the original image plus 2 * the padding (for the left and right), and the depth of the original image, also padded on each side.

%Creating a new image
padding = floor(fLen/2);
newImage = zeros([iSize(1) + 2*padding, iSize(2) + 2*padding, 3]);


Padding Image

For each layer, the left, right, top, and bottom most row/column of pixels was appended to the respective side of the image a total of "padding" times. This created an image with the edges extended so that the filtering didn't leave black edges around the exterior of the image. (Fig 1).

%Padding a color layer
for i = 1:paddingCount
        leftPadding = layer(:, 1);
        rightPadding = layer(:, end);
        layer = [ leftPadding layer rightPadding ];

        topPadding =  layer(1, :);
        bottomPadding = layer(end, :);
        layer = [ topPadding; layer; bottomPadding ];
end


Filtering Layer

As stated above, the filter is applied by finding the average dot product of each rectangle (in many cases, a square) of size filter length by filter width and the filter. This single number is placed in the center of the dimensions in the new image. The rectangle is moved left by one pixel until it reaches the end of the row, and then it is moved down by a pixel and the process is repeated until the image has been fully filtered.

% Go through each color layer
for cIndex = 1:3
    colorLayer = getColorLayer(image(:, :, cIndex), padding);

    for y = 1:iLen - fLen + + 1
        for x = 1:iWidth - fWidth + 1

            multColor = colorLayer(y:y + fLen - 1, x:x + fWidth - 1);
            avgColor = sum(multColor * filter')/fLen;
            newImage(padding + y, floor(fWidth/2) + x, cIndex) = sum(avgColor);

        end
    end
end


Discussion of Results

To build a hybrid image, the first image was filtered with a blur filter - specifically a Gaussian blur function. This function was chosen for its superior blurring as compared to the box filter blur. This result is shown in Fig. 2. The high frequency image was generated by finding the blurred version of the image, then subtracting that from the original image (Fig. 3). The two images added together form a hybrid image that appears to be Image 2 when viewed close up, and Image 1 when viewed from far away. (Fig. 4).

Fig. 2 (left): Image 1 with Gaussian filter, emphasis on low frequencies. Fig. 3 (right): Image 2 with high frequencies. Fig. 4 (below): hybrid image, as viewed at different distances.


Adjusting the cutoff frequency for the Gaussian filter did not appear to make a significant or perceivable difference, at least on the original images provided for testing. Fig. 5 shows the hybrid image with a cutoff frequency of 0.5, and Fig. 6 shows the hybrid image with a cutoff frequency of 500.

Fig. 5 (above), Fig. 6 (below)