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
   220   221   222   223   224   225   226   227   228   229   230