## Jupyter at Bryn Mawr College

Public notebooks: /services/public/dblank / CS110 Intro to Computing / 2015-Fall / Lectures

# 1. Photoshop-like Functions¶

## 1.1 Green screen Effects - Chroma Key Compositing¶

### Displaying an Image¶

This example introduces 6 new things related to images:

• Processing Javascript Directives: / @pjs preload=...; /
• PImage img;
• img.resize(WIDTH, HEIGHT);
• img.width, img.height
• image(img, X, Y);

In [1]:
%download http://blog.unem.de/wp-content/uploads/2012/05/11-Greenscreen-Clarissa-Knorr.jpg -f greenscreen1.jpg

Downloaded 'greenscreen1.jpg'.


Next, we display it:

In [35]:
/* @pjs preload="greenscreen1.jpg"; */

PImage img;

void setup() {
// println("" + img.width + " x " + img.height)
// 1920 x 1080
// Resize to a more reasonable size:
img.resize(int(img.width/10.0), int(img.height/10.0));
// Make sketch size match:
size(img.width, img.height);
}

void draw() {
image(img, 0, 0);
noLoop();
}

Sketch #19:

### Accessing each Pixel in a PImage¶

We can get each pixel/color in an image by using these:

• color c = img.pixels[x + y * img.width];
• red(c), green(c), blue(c)
In [36]:
/* @pjs preload="greenscreen1.jpg"; */

PImage img;

void setup() {
// println("" + img.width + " x " + img.height)
// 1920 x 1080
// Resize to a more reasonable size:
img.resize(int(img.width/10.0), int(img.height/10.0));
// Make sketch size match:
size(img.width, img.height);
// Add this to get pixel information into array:
}

void draw() {
image(img, 0, 0);
noLoop();
}

void mousePressed() {
// Make sure the index into pixels is an int:
color pixel = img.pixels[int(mouseX + mouseY * img.width)];
// See what color it is:
println("Color: " + red(pixel) + ", " + green(pixel) + ", " + blue(pixel));
}

Sketch #20:

### Composite Images¶

In addition, we can also change pixels in an image by:

• img.pixel[x + y * width] = new_color;
• img.updatePixels();
In [7]:
%download http://images.tenplay.com.au/~/media/News/National%20News/National%20News%20do%20not%20delete/News_National_showheader_480x210.jpg -f background1.jpg

Downloaded 'background1.jpg'.

In [37]:
/* @pjs preload="greenscreen1.jpg,background1.jpg"; */

PImage img;
PImage background;
PImage composite;

void setup() {
img.resize(int(img.width/10.0), int(img.height/10.0));
size(img.width, img.height);
// get background:
background.resize(img.width, img.height);
// Now we image processing:
composite = new PImage(img.width, img.height);
for (int i = 0; i < composite.width; i++) {
for (int j = 0; j < composite.height; j++) {
// if pixel is green, get it from background
// else get it from foreground
if (i > composite.width/2) {
composite.pixels[int(i + j * composite.width)] =
img.pixels[int(i + j * img.width)];
} else {
composite.pixels[int(i + j * composite.width)] =
background.pixels[int(i + j * img.width)];
}
}
}
composite.updatePixels();
}

void mousePressed() {
color pixel = composite.pixels[int(mouseX + mouseY * img.width)];
println("Color: " +
red(pixel) + ", " +
green(pixel) + ", " +
blue(pixel));
}

void draw() {
image(composite, 0, 0);
noLoop();
}

Sketch #21:

### Composite each pixel based on color¶

In [38]:
/* @pjs preload="greenscreen1.jpg,background1.jpg"; */

PImage img;
PImage background;
PImage composite;

void setup() {
img.resize(int(img.width/10.0), int(img.height/10.0));
size(img.width, img.height);
// get background:
background.resize(img.width, img.height);
// Now we image processing:
composite = new PImage(img.width, img.height);
for (int i = 0; i < composite.width; i++) {
for (int j = 0; j < composite.height; j++) {
color pixel = img.pixels[int(i + j * img.width)];
float r = red(pixel);
float g = green(pixel);
float b = blue(pixel);
// if pixel is green, get it from background
if (r < 55 &&
g < 170 && g > 145 &&
b > 50 && b < 80) {
composite.pixels[int(i + j * composite.width)] = background.pixels[int(i + j * img.width)];
} else {
// else get it from foreground
composite.pixels[int(i + j * composite.width)] = pixel;
}
}
}
composite.updatePixels();
}

void mousePressed() {
color pixel = img.pixels[int(mouseX + mouseY * img.width)];
println("Color: " + red(pixel) + ", " + green(pixel) + ", " + blue(pixel));
}

void draw() {
image(composite, 0, 0);
}

Sketch #22:

Problem 1: fix the green screen effect above to make the background a nice, uninterrupted image without any green showing through.

Problem 2: Make your own "green screen" effect using your own pictures. Use a colored blanket, for example, as your background. Do something other than a news cast simulation. For example, put yourself in an unexpected place.

## 1.2 Obamicon¶

In [34]:
%download http://i29.photobucket.com/albums/c290/trebor007/image_3655004.jpg -f obama.jpg

Downloaded 'obama.jpg'.


Problem 3: Take the regular picture of Obama and see if you can produce one programmatically that looks like the artistic version.

Problem 4: Take a pictures of yourself, and make it look like an Obamicon-ified version.

## 1.3 Edge Detection¶

https://processing.org/examples/edgedetection.html

There are a series of image processing techniques that can be accomplished by comparing a pixel to its surrounding 8 pixels.

A sample kernel for edge detection (high-pass filter):

 -1 -1 -1 -1 +9 -1 -1 -1 -1
sum = pixel1 * k[-1][-1] +
pixel2 * k[0][-1] +
pixel3 * k[1][-1] +
pixel4 * k[-1][0] +
pixel5 * k[0][0] +
pixel6 * k[1][0] +
pixel7 * k[-1][1] +
pixel8 * k[0][1] +
pixel9 * k[1][1];
// set color at pixel5 to be sum

In [17]:
%download https://processing.org/examples/moon.jpg

Downloaded 'moon.jpg'.

In [39]:
// The next line is needed if running in JavaScript Mode with Processing.js

float[][] kernel = {{ -1, -1, -1},
{ -1,  9, -1},
{ -1, -1, -1}};

PImage img;

void setup() {
size(640, 360);
}

void draw() {
image(img, 0, 0); // Displays the image from point (0,0)
// Create an opaque image of the same size as the original
PImage edgeImg = createImage(img.width, img.height, RGB);
// Loop through every pixel in the image.
for (int y = 1; y < img.height-1; y++) { // Skip top and bottom edges
for (int x = 1; x < img.width-1; x++) { // Skip left and right edges
float sum = 0; // Kernel sum for this pixel
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
// Calculate the adjacent pixel for this kernel point
int pos = (y + ky)*img.width + (x + kx);
// Image is grayscale, red/green/blue are identical
float val = red(img.pixels[pos]);
// Multiply adjacent pixels based on the kernel values
sum += kernel[ky+1][kx+1] * val;
}
}
// For this pixel in the new image, set the gray value
// based on the sum from the kernel
edgeImg.pixels[int(y * img.width + x)] = color(sum, sum, sum);
}
}
// State that there are changes to edgeImg.pixels[]
edgeImg.updatePixels();
image(edgeImg, width/2, 0); // Draw the new image
noLoop();
}

Sketch #23:

Problem 5: Try edge detection on one of your own images, but with a purpose. What is the use of edge detection?

## 1.4 Blurring¶

https://processing.org/examples/blur.html

A sample kernel for blurring (low-pass filter):

 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9
In [40]:
// The next line is needed if running in JavaScript Mode with Processing.js

float v = 1.0 / 9.0;
float[][] kernel = {{ v, v, v },
{ v, v, v },
{ v, v, v }};

PImage img;

void setup() {
size(640, 360);
}

void draw() {
image(img, 0, 0); // Displays the image from point (0,0)

// Create an opaque image of the same size as the original
PImage edgeImg = createImage(img.width, img.height, RGB);

// Loop through every pixel in the image
for (int y = 1; y < img.height-1; y++) {   // Skip top and bottom edges
for (int x = 1; x < img.width-1; x++) {  // Skip left and right edges
float sum = 0; // Kernel sum for this pixel
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
// Calculate the adjacent pixel for this kernel point
int pos = (y + ky)*img.width + (x + kx);
// Image is grayscale, red/green/blue are identical
float val = red(img.pixels[pos]);
// Multiply adjacent pixels based on the kernel values
sum += kernel[ky+1][kx+1] * val;
}
}
// For this pixel in the new image, set the gray value
// based on the sum from the kernel
edgeImg.pixels[int(y * img.width + x)] = color(sum);
}
}
// State that there are changes to edgeImg.pixels[]
edgeImg.updatePixels();

image(edgeImg, width/2, 0); // Draw the new image
noLoop();
}

Sketch #24:

Problem 6: Perform blurring on one of your own images. Why might this be useful?

Bonus: combine two of the photoshop-like effects in a single image.

In [49]:
/* @pjs preload="pinkscreen.png"; */

PImage img;
PImage composite;
PImage moon;

void setup() {