Drawing and Image
Processing in Python
with Myro Graphics
Dr. Paige H. Meeker
What can Python do
without the Robots?
We can use Python to control the robots
We can also use Python to create some interesting
drawings!
http://wiki.roboteducation.org/Myro_Reference_Ma
nual
Changing Colors
Python uses the RGB
Color model. That
stands for red, green,
and blue
The range for each
color is 0-255.
Changing Colors
To create a new color value, assign an
identifier to a new color:
redColor = color_rgb(255,0,0)
There are 256 different shades for each of the
three colors. Combinations of these shades
will allow you millions of color choices.
For a list of several of the RGB colors, visit:
http://www.tayloredmktg.com/rgb/
Alternatively, you can use Google with "rgb
color codes" as a search parameter
Drawing
To draw things, we need a window. We create
it with:
myWin = GraphWin(title, width, height)
(remember, myWin is a variable name it
can be anything you want it to be.)
After creating the window, you can do several
things to it:
myWin.setBackground(color)
myWin.close()
myWin.isClosed()
myWin.getMouse()
Myro Graphics Objects
You can draw lots of things using Myro:
Point
Oval
Circle
Rectangle
Image
Text
Line
Polygon
Point(x,y)
myPoint = Point(x,y)
Actions you can use on points include:
getX()
getY()
These actions (also called methods) will
give you back the x and y locations of the
point you reference. To use any actions, you
use the identifier of the point:
myPoint.getX() #For example
Oval(point1,point2)
myOval = Oval(point1,point2)
Actions you can use on ovals include:
getCenter()
getP1()
getP2()
These actions (also called methods) will
give you back the x and y locations of the
point you reference. To use any actions, you
use the identifier of the point:
myOval.getCenter() #For example
Rectangle(point1,point2)
myRectangle = Rectangle(point1,point2)
Actions you can use on rectangles include:
getCenter()
getP1()
getP2()
These actions (also called methods) will
give you back the x and y locations of the
point you reference. To use any actions, you
use the identifier of the point:
myRectangle.getCenter() #For example
Line(point1,point2)
myLine = Line(point1,point2)
Actions you can use on lines include:
getCenter()
setArrow("first" / "last" / "both" / "none")
getP1()
getP2()
Circle(centerPoint,radius)
myCircle = Circle(centerPoint,radius)
Actions you can use on circles include:
getCenter()
getRadius()
Polygon(point1,
point2, ...)
myPoly = Polygon(p1,p2,p3,) #list of
points
Actions you can use on polygons include:
getPoints() #Returns a list of points.
Text(anchorPoint, string)
myText = Text(anchorPoint,string)
Actions you can use on text include:
setText(string)
getText()
getAnchor()
setFace(family)
setSize(point)
setStyle('normal'/'bold'/'italic')
setTextColor(color)
Image(centerPoint,
imageFileName)
#to read in a file (jpg, gif) and then
#convert it to an image:
dis = makePicture(pickAFile())
disPixmap = makePixmap(dis)
center = Point(150,150)
pic = Image(center,disPixmap)
So, to display a photo of
ANY size correctly
from myro import * #need myro for this to work!
dis = makePicture(pickAFile()) #choose any image
disPixmap = makePixmap(dis) #create a pixmap
disWidth = disPixmap.getWidth() #gets width
disHeight = disPixmap.getHeight() #gets height
center = Point(disWidth/2,disHeight/2) #need the
center point
pic = Image(center,disPixmap) #Python needs an
IMAGE, not a JPG or GIF
disWin = GraphWin("Cinderella",disWidth,disHeight)
#make a window to display it in
pic.draw(disWin) #draw it!
Actions for all Graphics
Objects
The following are actions to take on all the
Myro graphics objects except Image and
Text
setFill( color )
setOutline( color )
setWidth( pixels )
draw(aGraphWin) #Used to draw the object onto a graph
window. Once drawn, updates are automatic.
undraw() #Removes the object from a graph window.
move( dx, dy ) #Relative to current location.
clone() #Returns a reference to a clone of the object.
Cat.py
#Cat window created by Dr. Paige Meeker
#Robot Class
#September 5, 2008
#
#Collaboration Statement: I worked on this
program alone.
Cat.py
Setting up the Window
#Import the myro library
from myro import *
#Create a window
animalWindow = GraphWin("My Animal Drawing", 300, 300)
#Change the background color of the window
#For a list of several of the RGB colors, visit:
#http://www.tayloredmktg.com/rgb/#OR
#alternatively, you can use Google with "rgb color codes"
as a search parameter
lightPink = color_rgb(255,182,192)
animalWindow.setBackground(lightPink)
Cat.py
Making a face
#create the face of the cat:
centerCatFace = Point(150,150)
face = Circle(centerCatFace,50)
catColor = color_rgb(255,105,180)
face.setOutline(catColor)
face.setWidth(10)
face.draw(animalWindow)
Cat.py
Making ears
earPt1 = Point(125,110)
tip = Point(125,50)
earPt2 = Point(150,100)
tip2 = Point(175,50)
earPt3 = Point(175,110)
leftEar1 = Line(earPt1,tip)
leftEar2 = Line(tip,earPt2)
leftEar1.setWidth(10)
leftEar1.setOutline(catColor)
leftEar1.draw(animalWindow)
leftEar2.setWidth(10)
leftEar2.setOutline(catColor)
leftEar2.draw(animalWindow)
rightEar1 = Line(earPt2,tip2)
rightEar2 = Line(tip2,earPt3)
rightEar1.setWidth(10)
rightEar1.setOutline(catColor)
rightEar1.draw(animalWindow)
rightEar2.setWidth(10)
rightEar2.setOutline(catColor)
rightEar2.draw(animalWindow)
Cat.py
Making eyes
eyeColor = color_rgb(0,255,0)
eyePt1 = Point(135,135)
eyePt2 = Point(165,135)
leftEye = Circle(eyePt1,10)
leftEye.setFill(eyeColor)
leftEye.draw(animalWindow)
rightEye = Circle(eyePt2,10)
rightEye.setFill(eyeColor)
rightEye.draw(animalWindow)
Cat.py
Making the nose and
mouth
nose = Circle(centerCatFace,5)
nose.setFill(catColor)
nose.draw(animalWindow)
mouthPt = Point(150,175)
mouth = Text(mouthPt,"W")
mouth.setSize(30)
mouth.setTextColor(catColor)
mouth.draw(animalWindow)
Disney.py
To import images into your files, use the following example.
#Disney Image window created by
Dr. Paige Meeker
#Robot Class
#September 5, 2008
#
#Collaboration Statement: I
worked on this program alone.
#Import the myro library
from myro import *
#Create a window
disneyWin = GraphWin("My Disney
Images", 300, 300)
dis = makePicture(pickAFile())
#show(dis)
disPixmap = makePixmap(dis)
center = Point(150,150)
pic = Image(center,disPixmap)
pic.draw(disneyWin)
Disney.py
#Disney Image window created by
Dr. Paige Meeker
#Robot Class
#September 5, 2008
#
#Collaboration Statement: I
worked on this program alone.
#Import the myro library
from myro import *
#Create a window
disneyWin = GraphWin("My Disney
Images", 300, 300)
dis = makePicture(pickAFile())
#show(dis)
disPixmap = makePixmap(dis)
center = Point(150,150)
pic = Image(center,disPixmap)
pic.draw(disneyWin)
#Can also draw on the window
with the picture
circleTest = Circle(center,20)
ccolor = color_rgb(255,182,98)
circleTest.setFill(ccolor)
circleTest.draw(disneyWin)
Gathering User Input
To ask the user for information, use the
input command. In the parenthesis, ask a
question of the user that will give the user the
information they need to give back the proper
answer. This is usually stored in a variable
name.
<variable name> = input(<some prompt string>)
xPoint = input(Please enter the x coordinate of the point.)
yPoint = input(Please enter the y coordinate of the point.)
userPoint = Point(xPoint,yPoint)
Repetition aka Looping
Loop statements will allow repetition of
events for a fixed number of times.
for <variable> in <sequence>:
<do something>
<do something>
...
We can use loop statements for lots of things.
One example is animation!
LoopingCircles.py
#Circle window created by Dr.
Paige Meeker
#Robot Class
#September 5, 2008
#
#Collaboration Statement: I
worked on this program alone.
#create the circle to be moved:
center = Point(150,150)
myCircle = Circle(center,50)
myColor = color_rgb(75,105,180)
myCircle.setOutline(myColor)
myCircle.draw(circleWin)
#Import the myro library
from myro import *
#Create a window
circleWin = GraphWin("My Circle
Drawing", 300, 300)
for i in range(10):
myCircle.move(5,5)
wait(1) #without this, you
cant see the movement!
Repetition aka Looping
Loop statements also allow you to specify a
start point, end point, and stepping sequence
for i in range(1,10,2):
myCircle.move(-5,-5)
wait(1)
How do you think this statement will affect
our circles movement if we add it to the
code?
Repetition another way
With the for example, we specified a
number of times we wanted our actions to
repeat. We can also specify repetition as the
amount of time we want our actions to repeat.
while timeRemaining(10):
<do something>
<do something>
...
This will issue the commands for 10 seconds.
(The 10 can be any time you want.)
While
To have your while command repeat forever,
type:
while True:
<do something>
<do something>
Image Processing
and Perception
Dr. Paige H. Meeker
Whats an Image?
Images are pictures, taken by a digital camera
or created in a digital program.
These images are made up of picture
elements (aka pixels) that contain color
values.
Manipulation of these color values can make
for interesting interpretations and make
existing data easier to see
The field that studies this is called image
processing.
Whats an Image?
Color images are made up of 255 shades of
red mixed with 255 shades of green mixed
with 255 shades of blue.
It takes 3 bytes (24 bits) to hold a single
pixels color value.
Grayscale images contains the level of gray in
a pixel which can be represented in one byte
(8 bits) with a number ranging from 0 to 255.
Whats an Image?
Most digital cameras take photos of at least 6
Megapixels.
Refers to the largest size image the camera can
take
Scribbler takes photos of 0.14 megapixels
Myro supports images of type JPG and GIF
Myro Image Review
pic = takePicture() #Takes a photo with the Scribbler, stores
it in variable pic
pic = takePicture(gray) #Takes a grayscale photo with the
Scribbler
getWidth(pic) # gives the width of pic
getHeight(pic) # gives the height of pic
savePicture(pic, NewPicName.jpg) #saves a JPG
savePicture(pic, NewPicName.gif) #saves a GIF
makePicture(directory/nameOfPic.JPGor.GIF) #reads back
in a photo that has been stored
pickAFile() #opens navigational dialog box to allow user a
choice of files to load in.
show(pic) #shows the photo on the monitor
Robot Explorer
You can use the joyStick() function to guide your
robots movements while taking photos, allowing
you to remotely guide the robot. Try the following
code:
joyStick()
for i in range(25):
pic = takePicture(gray)
show(pic)
What do you expect this code to allow you to do?
Animated GIFs
In chapter 5 (Sensing the World), we made an
animated GIF the instructions are repeated here.
Looking at the last slide, can you remember how
to create one?
Animated GIFs
First, you use the robot to create a list of pictures
(through movement or rotating in place)
Use the savePicture command with the list instead
of a single photo save it to a GIF file (JPGs are
not animated)
Example:
pic1 = takePicture()
#move the robot
pic2 = takePicture()
picList = [pic1,pic2] #can have many more photos here
savePicture(picList, AnimatedGifExample.gif)
Open AnimatedGifExample.gif in any web browser to see the
movie.
Making Photos
You can create photos in fact, you have
created drawings of your own. (See chapter 8
and or previous notes on creating images.)
Lets see what else we can do we can create
our own photos by manipulating each of the
pixels within an image.
Color Values
Myro has some predefined colors:
black = makeColor( 0, 0, 0)
white = makeColor(255, 255, 255)
blue = makeColor( 0, 0, 255)
red = makeColor(255, 0, 0)
green = makeColor( 0, 255, 0)
gray = makeColor(128, 128, 128)
darkGray = makeColor( 64, 64, 64)
lightGray = makeColor(192, 192, 192)
yellow = makeColor(255, 255, 0)
pink = makeColor(255, 175, 175)
magenta = makeColor(255, 0, 255)
cyan = makeColor( 0, 255, 255)
Making Pictures
To create a picture filled with one color:
#define some size for the width and height of the image
Width = Height = 100
#fill in black with any color
newPic = makePicture(width,height,black)
show(newPic)
newPic2 = makePicture(width,height,makeColor(r,g,b))
Show(newPic2)
Picture Commands
getPixel(x,y)
Returns the pixel at location x,y
pickAColor()
Displays a color palette allowing you to chose a new color
repaint(pictureName)
Refreshes the displayed image to allow you to see any
changes that have been made
setRGB(pixel,(r,g,b))
Sets a pixel to the color specified by r,g,b (which are in
the range of 0 to 255 each)
r, g, b = getRGB(pixel)
Returns the color values for red, green, and blue in pixel
getRed(pixel), getGreen(pixel), getBlue(pixel)
Returns the red, green, or blue color values in the pixel
Image Processing
By manipulating the pixels in an image, we
can create some interesting pictures.
To make things easier, lets make them
grayscale with the gray function below:
def gray(v):
return makeColor(v,v,v) #returns an rgb gray color for v
Image Processing
A range of gray? Use the previous function
with the rule pixel at x,y colored using
grayscale x+y
def shadesOfGray():
MAX = 255
W = H = 100
myPic = makePicture(W,H)
show(myPic,"Shades of Gray")
for x in range (W):
for y in range (H):
color = gray((x+y)%(MAX+1))
setPixel(myPic, x, y, color)
show(myPic)
Image Processing
Why does this work?
Think about the values: location 0,0 will be
the value 0+0 MOD (max grayscale value) or
0 black.
How about location 100,100? (100+100 MOD
256) light gray!
What if our image was size 123x123?
123+123 MOD 256 = WHITE
Image Processing
Play with the other examples in your book
play with the values and see if you can predict
the results before you view them.
Image Processing
You dont have to start with a blank image to
create a new one.
You can use other techniques to transform
existing images in interesting ways.
Lets see how we can:
Shrink
Enlarge
Blur
Sharpen
Negative
Emboss
Image Processing Shrinking
Take an input image and shrink it by a given
factor.
Use the rule:
New pixel at x,y = old pixel at x*Factor, y*Factor
def shrink(pic):
show(pic,"Before")
x = getWidth(pic)
y = getHeight(pic)
F = int(ask("Enter shrink factor"))
newX = x/F
newY = y/F
newPic = makePicture(newX,newY)
for x in range(1,newX):
for y in range(1,newY):
setPixel(newPic, x, y, getPixel(pic, x*F,y*F))
show(newPic,"After")
return newPic
Image Processing Enlarging
Take an input image and enlarge it by a given
factor.
Use the rule:
New pixel at x,y = old pixel at x/Factor, y/Factor
def enlarge (pic):
show(pic,"Before")
x = getWidth(pic)
y = getHeight(pic)
F = int(ask("Enter enlarge factor"))
newX = x*F
newY = y*F
newPic = makePicture(newX,newY)
for x in range(1,newX):
for y in range(1,newY):
setPixel(newPic, x, y, getPixel(pic, x/F,y/F))
show(newPic,"After")
return newPic
Image Processing Blurring
You can blur an image by taking the average color
values of neighboring pixels
Using a neighborhood of 4:
def blur(pic):
show(pic,"Before")
w = getWidth(pic)
h = getHeight(pic)
newPic = makePicture(w,h)
for x in range(1,w-1):
for y in range(1,h-1):
n1 = getPixel(pic, x, y)
n2 = getPixel(pic, x-1, y)
n3 = getPixel(pic, x+1, y)
n4 = getPixel(pic, x, y-1)
n5 = getPixel(pic, x, y+1)
v = (getRed(n1)+getRed(n2)+getRed(n3)+getRed(n4)+getRed(n5))/5
setPixel(newPic, x, y, gray(v))
show(newPic,"After")
return newPic
Image Processing Blurring
You can blur an image by taking the average color
values of neighboring pixels
How would you modify the code on the previous
slide to:
Calculate a color blurring instead of a grayscale
one?
Calculate a blurring of a neighborhood of 8?
Calculate a blurring of a neighborhood of 15?
Image Processing Sharpening
You can sharpen an image by subtracting the
values instead of averaging them.
Using a neighborhood of 4:
def sharpen(pic):
show(pic,"Before")
w = getWidth(pic)
h = getHeight(pic)
newPic = makePicture(w,h)
for x in range(1,w-1):
for y in range(1,h-1):
n1 = getPixel(pic, x, y)
n2 = getPixel(pic, x-1, y)
n3 = getPixel(pic, x+1, y)
n4 = getPixel(pic, x, y-1)
n5 = getPixel(pic, x, y+1)
v = (5*getRed(n1)-(getRed(n2)+getRed(n3)+getRed(n4)+getRed(n5)))
setPixel(newPic, x, y, gray(v))
show(newPic,"After")
return newPic
Image Processing Sharpening
How would you modify the code on the previous
slide to:
Calculate a color sharpening instead of a grayscale
one?
Calculate a sharpening of a neighborhood of 8?
Calculate a sharpening of a neighborhood of 15?
Image Processing
Negative and Embossing
A negative of an image is obtained by
inverting the pixel values for a grayscale
image, this means subtracting each pixel
value from 255.
An embossed image can be created by
subtracting from the current pixels value the
value (or fraction of the value) of a pixel two
pixels away.
How do we implement these ideas?
Negative
def negative(pic):
show(pic,"Before")
W = getWidth(pic)
H = getHeight(pic)
MAX = 255
newPic = makePicture(W,H)
for x in range(W):
for y in range(H):
pixel = getPixel(pic,x,y)
v = MAX - getRed(pixel)
setPixel(newPic, x, y, gray(v))
show(newPic,"After")
return newPic
Emboss (full pixel value)
def emboss(pic):
show(pic,"Before")
W = getWidth(pic)
H = getHeight(pic)
newPic = makePicture(W,H)
for x in range(W-2):
for y in range(H-2):
pixel1 = getPixel(pic,x,y)
pixel2 = getPixel(pic,x+2,y+2)
v = getRed(pixel1) - getRed(pixel2)
setPixel(newPic, x, y, gray(v))
show(newPic,"After")
return newPic
Emboss (fraction of pixel
value)
def embossFrac(pic,fraction):
show(pic,"Before")
W = getWidth(pic)
H = getHeight(pic)
MAX = 255
newPic = makePicture(W,H)
for x in range(W-2):
for y in range(H-2):
pixel1 = getPixel(pic,x,y)
pixel2 = getPixel(pic,x+2,y+2)
v = getRed(pixel1) + (MAX/fraction - getRed(pixel2))
setPixel(newPic, x, y, gray(v))
show(newPic,"After")
return newPic
Image Understanding
We can look at a picture and
be able to answer questions
about it.
Given the image here
How many people are in the
photo?
How many are kneeling?
Could you draw a box around
each of their faces?
Now, how can you do this
computationally? So the a
computer or a robot can
Image Understanding
For our robots to perceive their environment
visually:
First we need to take a picture
Then, we ask a question about the environment
We analyze the picture and answer our
question
QUESTION: Can the robot recognize a ball?
Once recognized, can the robot follow a ball
wherever it goes?
Answering Questions
Assume we can recognize the ball. How do
we follow it?
while timeRemaining(T):
#take picture and locate ball
if <ball is to the left>
turnLeft(cruiseSpeed)
elif <ball is to the right>
turnRight(cruiseSpeed)
else:
forward(cruiseSpeed)
Answering Questions
So, how do we recognize the ball?
Start at the pixel level if we know what color
the ball is, we can look for pixels that are in that
color range.
The authors ball was pink with R=253 and G
= 66 so looking for a range within acceptable
values of these would help us find the ball!
for pixel in getPixels(p):
r, g, b = getRGB(pixel)
if r > 200 and g < 100:
setRGB(pixel, (255,255,255))
else:
setRGB(pixel, (0,0,0))
Answering Questions
So, how do we recognize the ball?
Using the code on the previous slide, we
effectively filter out the unwanted regions of
the image and can focus on the desired color.
Now, how do you turn left, right, or keep
center?
We know the image is 256 pixels wide; divide
this into 3 parts and assign left, right, and
center!
Code illustrated
while timeTemaining(T):
# take picture and locate the ball
pic = takePicture()
ballLocation = locateBall(pic)
if ballLocation <= 85:
turnLeft(cruiseSpeed)
elif ballLocation <= 170:
forward(cruiseSpeed)
else:
turnRight(cruiseSpeed)
Blobs
This kind of threshold filtering is called blob
filtering
Our robots can define blobs
First, take a picture
Then, display the picture and using your mouse,
define a rectangular region that contains the
desired blob.
Once defined, you can use the command
takePicture(blob)
Use the blob image to control the robot (this
time, resulting blob is black)
You can also use the getBlob() command:
onPixels, avgX, avgY = getBlob()
Object Recognition
Other computations on images include edge
detection and object recognition.
Can you think of features in todays digital
cameras that use object recognition?
Next Steps?
Type in these code segments and try them
out on your own images. Do you get what you
expect?