Section 6.6. Background Subtraction


[Page 197 (continued)]

6.6. Background Subtraction

Let's imagine that you have a picture of someone, and a picture of where they stood without them there (Figure 6.14). Could you subtract the background of the person (i.e., figure out where the colors are close), and then replace it with another another background? Say, of the moon (Figure 6.15)?

Figure 6.14. A picture of a child (Katie), and her background without her.



[Page 198]

Figure 6.15. A new background, the moon.


Program 43. Subtract the Background and Replace it with a New One
(This item is displayed on pages 198 - 199 in the print version)

/**  * Method to replace the background in the current picture  * with the background from another picture  * @param oldBackground a picture with the old background  * to replace  * @param newBackground a picture with the new background  * to use  */ public void swapBackground(Picture oldBackground,                            Picture newBackground) {   Pixel currPixel = null;   Pixel oldPixel = null;   Pixel newPixel = null;   // loop through the columns   for (int x=0; x<getWidth(); x++)   {     // loop through the rows     for (int y=0; y<getHeight(); y++)     {       // get the current pixel and old background pixel       currPixel = this.getPixel(x,y);       oldPixel = oldBackground.getPixel(x,y); 
[Page 199]
/* if the distance between the current pixel color * and the old background pixel color is less * than the 15 then swap in the new background pixel */ if (currPixel.colorDistance(oldPixel.getColor()) < 15.0) { newPixel = newBackground.getPixel(x,y); currPixel.setColor(newPixel.getColor()); } } } }


To test whether we can replace an old background with a new background, try:

> String fileName = FileChooser.getMediaPath("kid-in-frame.jpg"); > Picture p = new Picture(fileName); > fileName = FileChooser.getMediaPath("bgframe.jpg"); > Picture oldBg = new Picture(fileName); > fileName = FileChooser.getMediaPath("moon-surface.jpg"); > Picture newBg = new Picture(fileName); > p.swapBackground(oldBg,newBg); > p.show();


We can, but the effect isn't as good as we would like (Figure 6.16). Our daughter's top color was too close to the color of the wall. And though the light was dim, the shadow is definitely having an effect here.

Figure 6.16. Katie on the moon.


Barb tried the same thing with a picture of two of our kids in front of a wall. Barb should have used a tripod (really critical to get the pixels to line up). The two original pictures (Figure 6.17) weren't all that comparable. The background swap (with the bridge scene) didn't change all that much! We changed the threshold value to 50, and finally got some pretty good swapping (Figure 6.18).


[Page 200]


[Page 201]
> String fileName = FileChooser.getMediaPath("twoKidsWall.jpg"); > Picture p = new Picture(fileName); > Picture oldBg = new Picture( FileChooser.getMediaPath("wall2.jpg")); > Picture newBg = new Picture( FileChooser.getMediaPath("bridge.jpg")); > p.swapBackground(oldBg,newBg); > p.show();


Figure 6.17. Two kids in front of a wall, and a picture of the wall.
(This item is displayed on page 200 in the print version)


Figure 6.18. Swapping a country bridge for the wall, using background subtraction, with a threshold of 50.
(This item is displayed on page 200 in the print version)


Making it Work Tip: Add an Input Parameter to Generalize a Method

Notice that we changed the threshold from 15.0 to 50.0 for the second test of the swapBackground(oldBG,newBG) method. A better thing to do would be to change the method to take the threshold distance as another input parameter swapBackground(oldBG,newBG,threshold). This means we won't have to keep changing the method each time we want to change the threshold, which means the method can be used in more situations.


Program 44. Better Swap Background
(This item is displayed on pages 201 - 202 in the print version)

/**  * Method to replace the background in the current picture  * with the background from another picture  * @param oldBackground a picture with the old background  * to replace  * @param newBackground a picture with the new background  * to use  * @param threshold if the distance between the current  * pixel color and the background pixel color is less  * than this amount use the new background pixel color  */ public void swapBackground(Picture oldBackground,                            Picture newBackground,                            double threshold) {   Pixel currPixel = null;   Pixel oldPixel = null;   Pixel newPixel = null;   // loop through the columns   for (int x=0; x<getWidth(); x++)   {     // loop through the rows     for (int y=0; y<getHeight(); y++)     {       // get the current pixel and old background pixel       currPixel = this.getPixel(x,y);       oldPixel = oldBackground.getPixel(x,y); 
[Page 202]
/* if the distance between the current pixel color * and the old background pixel color is less than * the threshold then swap in the new background * pixel */ if (currPixel.colorDistance(oldPixel.getColor()) < threshold) { newPixel = newBackground.getPixel(x,y); currPixel.setColor(newPixel.getColor()); } } } }


To make this work pass the threshold too when invoking swapBackground:

> Picture p = new Picture(   FileChooser.getMediaPath("twoKidsWall.jpg")); > Picture oldBg = new Picture(   FileChooser.getMediaPath("wall2.jpg")); > Picture newBg = new Picture(   FileChooser.getMediaPath("bridge.jpg")); > p.swapBackground(oldBg,newBg,50); > p.show();




Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
ISBN: N/A
EAN: N/A
Year: 2007
Pages: 191

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net