Transcript Slide 1

CS 101:
Introduction to
Computing
More referencing pixels directly by
index number: Red eye and
mirroring
Developed by Mark Guzdial, Georgia Institute of Technology, 2003–2004; modified by
Robert H. Sloan, University of Illinois at Chicago, 2005, for educational use.
Removing “Red Eye”




When the flash of the camera
catches the eye just right
(especially with light colored
eyes), we get bounce back
from the back of the retina.
This results in “red eye”
We can replace the “red” with
a color of our choosing.
First, we figure out where the
eyes are (x,y) using
MediaTools
Removing Red Eye
def removeRedEye(pic,startX,startY,endX,endY,replacementcolor):
red = makeColor(255,0,0)
for x in range(startX,endX):
Why use a
for y in range(startY,endY):
range? Because
currentPixel = getPixel(pic,x,y)
we don’t want to
if (distance(red,getColor(currentPixel)) < 165):
replace her red
setColor(currentPixel,replacementcolor)
dress!
What we’re doing here:
• Within the rectangle of pixels (startX,startY)
to (endX, endY)
• Find pixels close to red, then replace them
with a new color
“Fixing” it: Changing red to black
removeRedEye(jenny, 109,
91, 202, 107,
makeColor(0,0,0))
 Jenny’s eyes are actually not
black—could fix that
 Eye are also not mono-color

A better function would
handle gradations of red
and replace with
gradations of the right eye
color
If you know where the pixels are:
Mirroring



Imagine a mirror horizontally across the picture,
or vertically
What would we see?
How do generate that digitally?

We simply copy the colors of pixels from one place
to another
Mirroring a picture


Slicing a picture down the middle and sticking a mirror on the slice
Do it by using a loop to measure a difference


The index variable is actually measuring distance from the
mirrorpoint
Then reference to either side of the mirror point using the difference
Program for mirroring
converts a real number to an
integer. e.g. if width=5, then
5/2 = 2.5 and int(5/2) = 2
def mirrorVertical(source):
mirrorpoint = int(getWidth(source)/2)
for y in range(1,getHeight(source)):
for xOffset in range(1,mirrorpoint):
pright = getPixel(source, xOffset+mirrorpoint,y)
pleft = getPixel(source, mirrorpoint-xOffset,y)
c = getColor(pleft)
setColor(pright,c)
How does that work?



Compute the half-way horizontal
index
The y value travels the height of
the picture
The xOffset value is an offset
It’s not actually an index
 It’s the amount to add or
subtract


We copy the color at
mirrorpoint-offset to
mirrorpoint+offset
def mirrorVertical(source):
mirrorpoint = int(getWidth(source)/2)
for y in range(1,getHeight(source)):
for xOffset in range(1,mirrorpoint):
pright = getPixel(source, xOffset+mirrorpoint,y)
pleft = getPixel(source, mirrorpoint-xOffset,y)
c = getColor(pleft)
setColor(pright,c)
Can we do it with a horizontal
mirror?
def mirrorHorizontal(source):
mirrorpoint = int(getHeight(source)/2)
for yOffset in range(1,mirrorpoint):
for x in range(1,getWidth(source)):
pbottom = getPixel(source,x,yOffset+mirrorpoint)
ptop = getPixel(source,x,mirrorpoint-yOffset)
setColor(pbottom,getColor(ptop))
Of course!
What if we wanted to copy bottom
to top?

Very simple: Swap the order of pixels in the bottom line
def mirrorHorizontal(source):
mirrorpoint = int(getHeight(source)/2)
for yOffset in range(1,mirrorpoint):
for x in range(1,getWidth(source)):
pbottom = getPixel(source,x,yOffset+mirrorpoint)
ptop = getPixel(source,x,mirrorpoint-yOffset)
setColor(ptop,getColor(pbottom))
Messing with Santa some more
Doing something useful with
mirroring


Mirroring can be used to
create interesting effects,
but it can also be used to
create realistic effects.
Consider this image that
from a trip to Athens,
Greece.

Can we “repair” the
temple by mirroring the
complete part onto the
broken part?
Figuring out where to mirror

Use MediaTools to find the mirror point and the range
that we want to copy
Writing functions for specific
files…generally


The function to mirror the temple needs to work for one
and only one file.
But we still don’t want to write out the whole path.
setMediaPath() allows us to pick a directory where our
media will be stored.
 getMediaPath(filename) will generate the entire path for
us to the filename in the media directory


THIS ONLY WORKS WHEN WE’RE ACCESSING FILES IN
THE MEDIA DIRECTORY AND WHERE WE HAVE SET THE
PATH FIRST!
Program to mirror the temple
def mirrorTemple():
source = makePicture(getMediaPath("temple.jpg"))
mirrorpoint = 277
lengthToCopy = mirrorpoint - 14
for x in range(1,lengthToCopy):
for y in range(28,98):
p = getPixel(source,mirrorpoint-x,y)
p2 = getPixel(source,mirrorpoint+x,y)
setColor(p2,getColor(p))
show(source)
return source
Did it really work?


It clearly did the
mirroring, but that doesn’t
create a 100% realistic
image.
Check out the shadows:
Which direction is the sun
coming from?
Understanding the Temple Fix



What is the very first transfer of pixels from and
to? Which (x,y) pixel from? Which (x,y) pixel
to?
What is the second set of pixels?
How many pixels get copied?
Adding print statements to see
what’s happening
def mirrorTemple():
source = makePicture(getMediaPath("temple.jpg"))
mirrorpoint = 277
lengthToCopy = mirrorpoint - 14
for x in range(1,lengthToCopy):
for y in range(28,98):
print "Copying color from",mirrorpoint-x,y
print "to",mirrorpoint+x,y
p = getPixel(source,mirrorpoint-x,y)
p2 = getPixel(source,mirrorpoint+x,y)
setColor(p2,getColor(p))
show(source)
return source
First pixels are either side of the
mirrorpoint, then moving down
>>> p2=mirrorTemple()
Copying color from 276 28
to 278 28
Copying color from 276 29
to 278 29
Copying color from 276 30
to 278 30
Counting pixels
def mirrorTemple():
source = makePicture(getMediaPath("temple.jpg"))
mirrorpoint = 277
lengthToCopy = mirrorpoint - 14
count = 0
for x in range(1,lengthToCopy):
for y in range(28,98):
p = getPixel(source,mirrorpoint-x,y)
p2 = getPixel(source,mirrorpoint+x,y)
setColor(p2,getColor(p))
count = count + 1
show(source)
print "We copied",count,"pixels"
return source
Counting pixels
>>> p2=mirrorTemple()
We copied 18340 pixels
 Where did that come from?

How many rows? Y goes from 28 to 98


How many columns? X goes from 1 to 277-14=263


= 70 rows of pixels
= 262 columns of pixels
70 * 262 = 18340
Some Utility Functions and other
random stuff about JES


If you know the name of the file, searching for it with
pickAFile() feels tedious
You can set and get a media folder (path) for
remembering a place where your media will be coming
from (or going to)
setMediaPath() lets you pick a file in your media folder
 getMediaPath(basefilename) lets you generate a
complete filename out of only the last part
 This is useful if all your images are in a single directory

Example
>>> setMediaPath()
#And then I get a file picker to make the choice with
New media folder: /Users/sloan/Mediasources/
>>> getMediaPath("tonks.jpg")
'/Users/sloan/Mediasources/tonks.jpg'
>>> tonks = makePicture("tonks.jpg")
>>> print tonks
Picture, filename /Users/sloan/Mediasources/tonks.jpg
height 296 width 224
“Driver” utility functions
def hw(picture):
for eggs in spam spam spam spam:
def driver():
file = pickAFile()
show(makePicture(file)) # Show the “before” picture
picture = makePicture(file)
hw(picture)
show(picture)
# Show the “after” picture
writePictureTo(picture, r“myFunkyPicture.jpg”)
return(picture)
Sometimes you want to break up your code into multiple
functions like this to make it easier to read and understand.
Comments – You should know what
these are by now, but if not...



Python ignores from “#” through the rest of the
line
If you start a line with “#”, the whole line is
ignored
Why do we want lines to be ignored?

To be able to leave notes to ourselves or someone
else about how the program works