Assignments | Class Photo | Course Home | Documentation | Lab Hours/Tutoring | Schedule | Submit

Saint Louis University

Computer Science 180
Data Structures

Michael Goldwasser

Spring 2012

Dept. of Math & Computer Science

Programming Assignment 05
Image Compression

Due: Monday, 2 April 2012, 11:59pm

Please see the general programming webpage for details about the programming environment for this course, guidelines for programming style, and details on electronic submission of assignments.

Collaboration Policy

For this assignment, you are allowed to work with one other student if you wish (in fact, we suggest that you do so). If any student wishes to have a partner but has not been able to locate one, please let the instructor know so that we can match up partners.

Please make sure you adhere to the policies on academic integrity in this regard.


Contents:


Overview

For this assignment, we are going to use another of the programming contest problems, and a fun one, but one that will take more time (and which deserves more credit) than our typical 50-minute lab.

So this is being elevated to "Programming Assignment" status. As such, I will also grade the source code more critically than I do for the typical lab. That is, I would ideally like for you to get the program working and passing the judge's tests, but even so, the grade will include an evaluation of the clarity and organization of your source code.

I would also like to stress the standard policy on academic integrity, in that a pair of students collaborating for this assignment must not coordinate with any other students, and must not seek any solutions online.


The Contest Problem

The problem we are using comes from our midwest region in 2010. It looks like a very complex problem, but it turns out to have a rather simple and elegant solution via recursion. By the end of the 5-hour contest, 26% of the teams had successfully completed it. Of course, the other might not have recognized the recursive solution. In the rest of this section, we provide the official problem statement. But please make sure to read my own advice, which follows the official problem statement, as that gives you a roadmap for success.

Image Compression

Source code:  compress.cpp

Strategies for compressing two-dimensional images are often based on finding regions with high similarity. In this problem, we explore a particular approach based on a hierarchical decomposition of the image. For simplicity, we consider only bitmapped images such as the following:

The image is encoded as a tree, with the root representing the entire image region. If a region is monochromatic, then the node for that region is a leaf storing the color of the region. Otherwise, the region is divided into four parts about its center, and the approach is applied recursively to each quadrant. For a non-leaf node, its four children represent the four quadrants ordered as upper-right, upper-left, lower-left, lower-right respectively. As an example, here is the tree encoding of the above image.

The original image is not monochromatic, so we considered the four quadrants. The top-right quadrant is monochromatic white, so the first child of the root node is a leaf with value 0. The top-left quadrant is not monochromatic, so it is further divided into four subquadrants, each of which is trivially monochromatic. This results in the subtree with leaf values 0, 0, 1, 0. The final two quadrants are monochromatic with respective values 0 and 1.

As a larger example, here is an 8x8 image and the tree encoding of it.


Thus far we have described a lossless compression scheme, but the approach can be used for lossy compression with the following adjustment. Instead of continuing the decomposition until reaching a monochromatic region, a threshold such as 75% is used, and a leaf is created whenever a region has at least that percentage of either color. As an example, here is the encoding of the above 8x8 image if using 75% as the threshold.

Notice that 75% of the top-left quadrant of the full image is black, and therefore the second child of the root is 1, and that more than 75% of the bottom-left quadrant of the full image is white, and therefore the third child of the root is 0. However, neither white nor black reaches 75% in the top-right quadrant, so the recursive decomposition continues, but all four of those subquadrants achieve the 75% threshold and become leaves. If we were to uncompress the image based on this new lossy encoding, we get back the following result.

Your goal is to determine the image that results from this lossy compression scheme, given an original bitmap image and a specific threshold percentage.

Input: The input will consist of a series of data sets, followed by a line containing only 0. Each data set begins with a line containing values W and T, where W is the width of the bitmap and T is the threshold percentage. Images will always be square with 1 ≤ W ≤ 64 being a power of two. Threshold T will be an integer with 51 ≤ T ≤ 100. Following the specification of W and T are W additional lines, each of which is a string of width W containing only characters 0 and 1, representing a row of the image bitmap, from top to bottom.

Output: For each data set, you should print an initial line of the form "Image 1:" numbering the images starting with 1. Following that should be W lines, with each line representing a row of the resulting bitmap as a string of characters 0 and 1, from top to bottom.

Example Input: Example Output:
4 80
0000
1000
0011
0011
8 75
11111000
11110000
11000011
11000011
11000100
00000100
00010011
00010011
4 75
1101
1111
0111
0011
0
Image 1:
0000
1000
0011
0011
Image 2:
11110000
11110000
11110011
11110011
00000100
00000100
00000011
00000011
Image 3:
1111
1111
1111
1111

Advice

The first thing I wish to point out is that a solution to this problem does not require the use of any tree data structures!. Although we will soon discuss trees, and they are a valuable structure, they simply are not needed here (and time devoted to writing such a data structure would be wasted). Admittedly, the description of the problem may lead readers astray, given the many pictures of trees that are drawn along the way. But the tree can be thought of as a simple conceptual approach for describing the hierarchical (i.e., recursive) decomposition of an image.

All you need for a data structure is a simple array (or vector) of strings. Read each line as a string, and then you have a sequence of lines. That provides a great data structure, as you can use a syntax such as image[r][c] to describe the 0/1 character that is in row r, column c (zero indexed, of course). Furthermore, strings in C++ are mutable, so you are welcome to edit those characters.

The real work for transforming the image can be accomplished recursively. At face value, assuming your job is to transform the entire image. What you can do is count up the number of 0 and 1 characters that occur. If either of those totals reaches the threshold, then you turn the entire image to the dominant color. Otherwise, you simply make four recursive calls, one for each quadrant, and you are done. (I should note that as a base case, a one-by-one portion of the image will have 100% saturation of one of the two colors).

The key is to define the recursive parameterization. You should avoiding making independent copies of quadrants of an image, and instead, send the original image (by reference) throughout the recursion, but with additional parameterization that defines the scope of one recursive call to a portion of the original image. For inspiration, review the coverage of recursion from Chapter 3, and the way that it defines several recursions on a one-dimensional array by passing the entire array recursively, but with additional parameters to define the scope of a recursive computation.

Finally, make the goal of each recursion to overwrite its portion of the image with the updated values, so that by the end of the entire process, the original image will have been transformed. To do this, you should pass the image by reference (but not by const reference, since you will intend to change it).


Files to Submit


Grading Standards

The assignment is worth 10 points.


Michael Goldwasser
CSCI 180, Spring 2012
Last modified: Sunday, 01 April 2012
Assignments | Class Photo | Course Home | Documentation | Lab Hours/Tutoring | Schedule | Submit