Building on the earlier image manipulation and logic sections, here we see how to implement a movie special effect.
Bluescreen Special Effect
"Bluescreen" video special effect
Video is just a series of still images, 20-60 per second
Have some background image, e.g. leaves.jpg
Detect colored area in an image, e.g. red in stop.jpg
For colored area, substitute in pixels from background image
The stop.jpg image and the leaves.jpg image
Bluescreen Algorithm
Bluescreen algorithm
Two images: image and back
Detect, say, red pixels in image
For each red pixel:
--Consider the pixel at the same x,y in back image
--Copy over the pixel from back to image
--What defines how a pixel looks? Three numbers.
--Copy over the red, green, and blue values
Result: red areas, substitute in areas from back image
Adjacent pixels maintained
Bluescreen Example Code
Two images: image and back
if-statement / avg -- detects red as usual
Inside if:
--1. Figure out x,y of pixel
--2. Get pixel2 from back image (at x,y)
--3. Make pixel the same as pixel2
-- i.e. copy over red/green/blue values
The above bluescreen example code detects the red part of the sign, and for those pixels, copies over the pixels from the back image. The bluescreen code below has 3 key differences from the earlier examples:
back = new SimpleImage("leaves.jpg"); -- open a second image and store it in the variable "back" (thus far we've only opened one image at a time)
pixel2 = back.getPixel(x, y); -- say we are looking at pixel x,y in the main image. Get the x,y pixel from the other image and store it in the variable "pixel2". We can get the x and y of the current pixel in the loop with the functions pixel.getX() and pixel.getY().
pixel.setRed(pixel2.getRed()); -- copy the red value from pixel2 to pixel. Also do this for the other two channels. In effect, for the x,y location, this copies the pixel from back to image.
Experiments: (a) Try copying the leaves to the sky instead of to the red parts of the sign (similar to the earlier Night Mode problem). (b) Make the code a little shorter by eliminating the need for "x" and "y" variables. Put the calls to pixel.getX() and pixel.getY() right in the back.getPixel(...) call.
Abby Bluescreen
In this example we have the abby.jpg image -- make it appear that the green parts of her little chair are sprouting leaves.
Solution code:
// Here the pixel2 = ... computation is shortened to one line
image = new SimpleImage("abby.jpg");
back = new SimpleImage("leaves.jpg");
for (pixel: image) {
avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue())/3;
// your code here
if (pixel.getGreen() > avg * 1.05) {
// 1. Get pixel2 from back image at same x,y (one line)
pixel2 = back.getPixel(pixel.getX(), pixel.getY());
// 2. Copy pixel2 over to pixel
pixel.setRed(pixel2.getRed());
pixel.setGreen(pixel2.getGreen());
pixel.setBlue(pixel2.getBlue());
}
}
print(image);
Monkey Bluescreen Like The Movies
Now we'll do one like the movies -- film the movie start in front of a blue screen.
Here is our monkey movie star:
Here is our background, the famous Apollo 8 photo of the earth shown rising
above the moon horizon.
Solution code:
image = new SimpleImage("monkey.jpg");
back = new SimpleImage("moon.jpg");
for (pixel: image) {
avg = (pixel.getRed() + pixel.getGreen() + pixel.getBlue())/3;
// your code here
if (pixel.getBlue() > avg * 0.92) {
pixel2 = back.getPixel(pixel.getX(), pixel.getY());
pixel.setRed(pixel2.getRed());
pixel.setGreen(pixel2.getGreen());
pixel.setBlue(pixel2.getBlue());
}
}
print(image);
Bluescreen Summary
Real technique
1. Two images: image, back
2. Loop over image, detect color area
3. Color area: copy over x,y pixel from back to image