CS 305J Assignment 10, Color Histograms, two dimensional arrays and objects

Programming Assignment 10 This is a pair assignment. You may work with one other person (You make work with one other person on this assignment using the pair programming technique.. You may work with anyone in the class. They do not have to be in the same discussion section as you or the same partner as on previous assignments. One solution will be turned in for the pair. Once you start working with one partner on an assignment you may not switch partners. If you do not wish to work with a partner after starting on an assignment you must both complete it individually. The intent here is you work on the assignment together, at the same time, at the same computer. Do not simply try to work on different parts independently and then try to put it together. You may choose to work alone if you wish.)

Placed online: November 14
30 points, ~3% of total grade
Due: no later than 11 pm, Tuesday, November 25
General Assignment Requirements

Description The purposes of this assignment are:
  1. To practice working with two dimensional arrays
  2. To practice implementing only a portion of a program
  3. To learn the basics of implementing a class.

Thanks to M. Dennis Mickunas for use of his DrawingBox class.

Background:

In this assignment you will be working with images. Images in computers are handled in many different ways. We will be treating images as a 2 dimensional array of ints. A single int contains the color information for the corresponding pixel in the image. So the int at row 0, column 0 corresponds to the upper left pixel in an image.

The color scheme the program will be using is the red-green-blue or RGB color scheme. In the RGB scheme a color is specified by how much red, green, and blue light it has. A value of 0 means no light of that color, a value of 255 means maximum intensity for that color. Thus black would be 0-0-0. White would be 255-255-255. Instead of using 3 ints you will store the color data for a pixel you will be working with a single int that stores the red, green, and blue components as a single number. You will be converting from a  single int with all the information for the amount of red, green, and blue light packed into that single int to a Color object. There are methods in the ColorHistogram class to assist with this. ColorHistogram is a class you will complete parts of on the assignment.

A color histogram is a representation of a picture created by counting the number of pixels with various intensities in an image. Instead of counting the number of each intensity (which would be 256) the intensities are grouped together in bins. So for example if the bin size is 10 there will be 26 bins (256 / 10 = 25 + 1 partial bin for a total of 26 bins.) Each color component (red, green, and blue) would have 26 bins if the bin size were 10. With a bin size of 10, pixels with red intensities of 0 to 9 would be counted in red bin 0, red intensities of 10 to 19 would counted in red bin 1, red intensities of intensities of 20 to 29 would be counted in red bin 2 and so forth. (For the assignment the bin size has been set to 5 via a constant.)

Here is an example of what a color histogram can look like (The bins sizes look very small in this example):

The 2d array representing an image is scanned and for each element in the 2d array (which represents a single pixel) the red, green, and blue intensity are determined and the proper bin is incremented. After counting up all the pixels the bins are normalized to the percentage of pixels in that bin. So every bin will contain a number between 0 and 100. In this assignment you will use a 2d array of doubles to represent the bins and thus the histogram. The 2d array of doubles only has 3 rows for red, green, and blue. the number of columns equals the number of bins.

Color histograms are useful because that can be used to compare pictures of different sizes and resolution. One technique to measure how close two images are is to compare their color histograms. How well the images match can be expressed as a match score. The match score is determined by looking at each bin for each color of the two histograms and adding the minimum of the two. (This technique only works if the bin sizes an thus the number of bins are the same.)

How to Approach the Assignment:

This assignment is different than past assignments in two ways. First you will not be completing the entire program from scratch. Instead you will be completing parts of the program. I provide the shell of the program and most of the methods to handle input and output as well as the methods that convert an image file to a 2D array of ints. You will have to look at the existing code in the ColorHistogram class.

  1. Download all the provided files.

  2. Start with the ColorHistogram class. In this class you have to complete the constructor and two other methods.

  3. Complete the ColorHistogram constructor. For the constructor you are passed an ImageData object. The ImageData contains a 2d array of ints that represent the pixels of an image and the name of an image. You must initialize your histogram instance variable so that it has 3 rows and each row has columns equal to the number of bins in the color histogram. In the constructor you must traverse the 2d array of ints that represent the pixels. For each int pull out its red, green, and blue components using the getRed, getGreen, and getBlue methods already present in the ColorHistogram class. Increment the appropriate bin in your 2d array of doubles.

    After looking at all the pixels normalize each bin to the percentage out of 100. These are doubles so you will have a fractional part. After normalizing the sum of the bins for each color would add up to 100. (Sum of red bins should be 100, blue bins 100, green bins 100. There could be a little round off error because we are dealing with doubles.) You should test this after completing the constructor.

  4. Complete the matchScore method in the ColorHistogram class. This method computes the match score between two ColorHistograms. One of the ColorHistograms is the calling object (this) and the other is sent as a parameter. The match score is computer by going through all bins for all colors and adding the minimum of the corresponding bin to the score. The sum of all the mins of corresponding bins is the overall match score.

  5. Complete the draw method in the ColorHistogram class. This is the hardest part of the assignment. This method is sent a DrawingBox object and a boolean. If the boolean is true display this ColorHistogram in the top half of the DrawingBox, otherwise display it in the bottom half.

    DrawingBox is a class similar to the DrawingPanel class we used earlier in the term, but it works a little differently. The methods from the DrawingBox class you need to be familiar with are

     getDrawableHeight() returns the height of the drawable area for this DrawingBox

    getDrawableWidth() returns the width of the drawable area for this DrawingBox

    setColor(Color c) changes the color this drawing box will draw with. (Such as Color.RED, Color.BLUE, Color.GREEN)

    fillRect(int x, int y, int width, int height) draws and fills in a rectangle at the given location and size using the current color.

    So for the DrawingBox class you do not obtain the graphics object and make calls on it. Instead all requests to draw or change color go through the DrawingBox itself.

    A ColorHistogram will take up half of the DrawingBox. In turn each color of the histogram takes of up 1 third of that half. (One sixth of the total height of the DrawingBox). Instead of just displaying straight percentages for each bin (which comes out looking a little flat) the bin among the three colors with the largest value should reach all the way to the top of its section. All other bins for all colors for this histogram should be scaled accordingly. Here is an example of what a histogram will look like: (In the top histogram the max value was in a red bin and all other bins in all three colors are scaled accordingly. In the bottom histogram the max value was in a blue bin and all other bins in all three colors are scaled accordingly.)

    The top histogram was the result of this image:

    The bottom histogram was the result of this image:

     

  6. Complete the findClosest method in the ImageMatcher class. ImageMatcher is the main driver class that has the main method. The findClosest method takes in an array of ColorHistogram objects and a query ColorHistogram. The method finds and returns the ColorHistogram from the array that has the best match score with the query ColorHistogram. You will make use of the matchScore method from the ColorHistogram class to do this method.

Running the Program:

When you run the main method in ImageMatcher you are asked to pick a directory. All of the jpeg files in that directory will be read in and have ColorHistograms created for them. These are stored in an array. The program will then ask for a single jpeg file and will find and display the image in the array that is closest.

When testing the program in is probably best to create a directory with just 3 or 4 jpeg files. You can use your own or ones I provided. After you get the program working try it on a larger set of files.

Turn in your completed ImageMatcher.java and ColorHistogram.java files to one persons accounts using the turnin program.

Files
File Responsibility
DrawingBox.java. A class similar to DrawingPanel. Provided by me. Do not change.
ClosableFrame.java. A class DrawingBox needs to work. Provided by me. Do not change.
ImageFetcher.java. A class to convert jpeg files to 2d ImageData objects. Provided by me. Do not change.
ImageData.java. A class that store a complete image as a 2d array of ints. You are passed an ImageData object to your ColorHistogram constructor. You will build the color histogram for the image. Provided by me. Do not change.
ColorHistogram.java. A class that represents a color histogram of an image. You will complete the constructor for this class as well as the matchScore and draw methods. Provided by you and me.
ImageMatcher.java. The main driver class.  Run this file to run the program. You must complete the findClosest in this class. Provided by you and me.
Images.zip. A zip file with a number of images. You can use these or your own or find more from the web.  When testing your program create a directory with just a few (3 - 4) images. Provided by me.
Checklist Did you remember to:
  • review the general assignment requirements?
  • work on the assignment alone or with one other person?
  • fill in the header in your file ImageMatcher.java?
  • ensure your program creates the correct output?
  • ensure you wrote the program using good programming style?
  • ensure your program does not suffer a compile error or runtime error?
  • turn in your Java source code files named ImageMatcher.java and ColorHistogram.java to the proper account in the Microlab via the turnin program before 11 pm, Tuesday, November 25?

Back to the CS 305j homepage.