Page 225 - The Definitive Guide to Building Java Robots
P. 225
Preston_5564C06.fm Page 206 Friday, September 23, 2005 5:13 AM
206 CHAPTER 6 ■ VISION
You might be wondering how I came up with these numbers. Well, at first I experimented
until I got a match. Then I wrote a program to help create the ColorGram from a cropped image.
To get the three images for the three cans, I used an image editor and cropped just the
target image. Then I wrote a program that would optimize the cropped image until it gave me
the desired color ratio most prominent in the sample image.
Code Objective
The objective here is to create a ColorGram calibration program.
Code Discussion
In this class, I have 11 fields: currentImage, which is the current image loaded from the file-
name passed to the constructor; ImagePanel, to display and repaint the image as it changes;
maxCount, which will be used to count pixels in a particular color range; the array meanValues
and redAvg, greenAvg, and blueAvg to hold the averages of the primary colors and order them
from most color to least color; a threshold value to determine what percentage of the image it
should be optimized to; and finally, bestColorGram, which is the optimized, processed ColorGram
and ImageProcessor used to perform the ColorRatio and ColorRatioCount on the sampled images.
I overloaded the constructor to take an optional Boolean value. This tells the class whether
or not to show the GUI component. The constructor with no parameter defaults to true. Then
it sends the filename and the toShow parameter to init().
During init(), the class gets the file as it did in ImageViewer, but I also process the image
getting the top-bottom 150 greyscale colors from the image. This removes the background of
the object I’m looking for without any modification to the image via the image editor. Next,
I get the mean values of the remaining colors. After that, I construct the image panel with the
image dimensions. Then I set the other frame properties and add an Exit Listener before I show it.
The next method called is optimize(). This looks at the colors and sorts them. If any are
equal, then I increment the values of the second color by one so I can create an order for the
colors: RED, GREEN, and BLUE.
Next, I take my primary color and move the minimum value up until I still have 95 percent
of the colors I want. Then I move down from the maximum until I have 95 percent of that
image; this should be 90 percent of the original.
Finally, I move the ratios from the second and third colors down to 50 percent of the pixels.
I don’t want that many of these colors, so the percentage is lower.
The methods optmizeMin(), optmizeMax(), and optmizeRatio() call doProcessing() with a
ColorGram as modified by their descriptors.
The doProcessing() method calls colorRatioCount(), shown after Example 6-23, where the
total colors in the ColorGram are counted and returned as an int. The first reading will always
be the highest, so this is set as the maxCount. Then during each successive call, the threshold
is measured as a percentage of the maxCount, and the total colors are compared. If the number
is greater than the percentage, I save the ColorGram as my bestColorGram. This is where I used
the clone() method because I keep sending in a new cg (ColorGram), and if I would have set it
to the instance created in the optimize methods, it would change as well.
In main(), I feed a sample image of the Coke can, and then the program creates the ColorGram.
See Figure 6-20.
97022d2480fe4a63cfdfa123a6e70098