Robot vision
Activity 1: horizontal line
Write a function that will make your robot take a picture and display it with a horizontal line drawn across it at a height of your choice. This should be very similar to the drawVerticalRedLine function described below.
Activity: Color follower
Write a program that will turn your robot towards objects of a particular color. If someone is wearing a bright colored shirt, for example, make your robot turn towards it. Another good option is to make your robot turn towards other robots by looking for blue objects.
The last section of this tutorial will be most helpful.
In order to complete this activities, you will need all or part of the following information. Read carefully!
Basic Components of an Image
You can think of an image or a picture as a rectangular object which has a specific size determined by its width and its height. Each picture is composed of tiny components called pixels. You can calculate the number of pixels in an image by using the following formula:
number of pixels in an image = width of image * height of image
Each pixel has a red, green and blue component (an RGB value). Each of these colors has a value that ranges from 0 to 255. For instance, a completely red pixel would be represented as (255,0,0), or full red, and zero green and zero blue components. Similarly, a green pixel would be represented as (0,255,0) and a blue pixel would be represented as (0,0,255). Other colors are made by mixing various values of red, green, and blue. For example, white is made by combining all of the colors (255,255,255), and black is made by an absence of any color (0,0,0). If you combine green and blue with no red (0,255,255) you would get a teal color, while a combination of red and green with no blue (255,255,0) would produce yellow. Also, each pixel has a specific (x,y) location in an image.
Taking Pictures
Recall that pictures are taken in the following way:
>>> pic = takePicture() >>> show(pic)
You can determine the size of the image by using the getWidth() and getHeight() functions.
Try the following:
picWidth = getWidth(pic) picHeight = getHeight(pic) print "The Picture is", picWidth , "pixels wide and", picHeight, "pixels high."
Drawing a Line
NOTE: If you would like to use a copy of the apple picture rather than using your own picture in the examples below, replace:
takePicture()
with:
makePicture("http://wiki.roboteducation.org/wiki/images/2/2b/Apple.jpg")
If you want to change a lot of pixels all at once, you can use a loop. For example, the following loop will change all pixels that have an X value of 10 and a Y value anywhere between 0 and 100 (but not including 100) to be red:
for yValue in range(0,100): aPixel = getPixel(newPic, 10, yValue) setRed(aPixel,255) setGreen(aPixel,0) setBlue(aPixel,0) show(newPic)
The result is a vertical red line (at X position 10). Note that this piece of code will only work correctly for pictures that are exactly 100 pixels high (because you loop from zero to 100). But you can generalize this code to work on pictures of any size by replacing the 100 with a function call that tells us the actual height of the picture as follows:
for yValue in range(0, getHeight(newPic) ): aPixel = getPixel(newPic, 10, yValue) setRed(aPixel,255) setGreen(aPixel,0) setBlue(aPixel,0)
Drawing a line could be a useful function to use later, so you should prepare to re-use the code above by putting it into a function. But since you don’t know the exact X position that the user will want to draw their line, you should make that into a parameter that the user can specify. Also, since you don’t know the name of the variable that will hold the picture, that should also be a parameter:
def drawVerticalRedLine( picture, xPos ):
for yPos in range(0, getHeight(picture) ):
aPixel = getPixel( picture, xPos, yPos)
setRed(aPixel,255)
setGreen(aPixel,0)
setBlue(aPixel,0)
Now you have a function that will draw a vertical red line on a picture of any height. Note that your function does NOT show the image, so a user would have to call our function, and then call the show() function to display the line on screen:
pic = takePicture() show(pic) wait(1) drawVerticalRedLine(pic, 25) show(pic)
Because the above code does not change the green or blue values of the pixels, the picture is still recognizable, but all pixels have a reddish tint.

Robot Vision
Operating on a single pixel in an image
Myro has a set of functions that allow you to get the individual red, green, and blue values from a pixel, as well as set the values to any number you want. But before you get or set the value of a pixel, you need to select a specific pixel to change.
The getPixel command returns the pixel at the specified x and y locations in the picture. setColor sets the given pixel’s color to any specified color. You can create a new color by specifying its RGB values in the command:
myRed = makeColor(255, 0, 0)
The following example picks the pixel at X location 10 and Y location 5 using the getPixel() function then sets its red value to full on (255) with the setRed() function.
onePixel = getPixel(newPic,10,5) print getRed(onePixel) #initial red value setRed(onePixel,255) print getRed(onePixel) #new red value show(newPic)
Operating on all pixels in an image
The getPixel() function returns a pixel at a specific location in the picture. However, sometimes you want to do something to all pixels in the picture. In such cases you can use the getPixels() method which returns a a list of all the pixels. You can use the getPixels() method in a for loop to perform an operation on all pixels in the image. For example, you can turn the red color of all pixels all the way on with the following code:
myPic = takePicture() show(myPic) for eachPixel in getPixels(myPic): setRed(eachPixel,255) show(myPic)
This should give your image a red tint.
Locate Bright Areas in an image
By making a decision about each pixel in an image, you can locate specific areas in an image. For example, by looking for pixels that have a large value, you can locate bright areas in the image. You can even modify the image to outline bright areas. For example:
myPicture = takePicture()
show(myPicture)
for pixel in getPixels(myPicture):
redValue = getRed(pixel)
greenValue = getGreen(pixel)
blueValue = getBlue(pixel)
averageValue = ( redValue + greenValue + blueValue) / 3.0
if averageValue > 175 :
#Turn the pixel white
setRed(pixel,255)
setGreen(pixel,255)
setBlue(pixel,255)
else:
#Otherwise, turn it black.
setRed(pixel,0)
setGreen(pixel,0)
setBlue(pixel,0)
show(myPicture)
Locate Red Areas in an image
By changing the conditional test, you can instead look for areas that have a large amount of the color red. Red areas are characterized by having large red values, but smaller blue and green values.
myPicture = takePicture()
show(myPicture)
for pixel in getPixels(myPicture):
redValue = getRed(pixel)
greenValue = getGreen(pixel)
blueValue = getBlue(pixel)
if redValue > 175 and greenValue < 175 and blueValue < 175 :
#Turn the pixel white
setRed(pixel,255)
setGreen(pixel,255)
setBlue(pixel,255)
else:
#Otherwise, turn it black.
setRed(pixel,0)
setGreen(pixel,0)
setBlue(pixel,0)
show(myPicture)
Pixels with red values larger than 175 highlighted in white.
Pixels with green values lower than 175 highlighted in white.
Pixels that have both red values larger than 175 and green and blue values lower than 175 highlighted in white.
Represent Red Areas in an image as White Areas
You can then define a function to find red pixels and return a black and white picture with white pixels representing “red” areas.
def findRedAreas(picture):
for pixel in getPixels(picture):
redValue = getRed(pixel)
greenValue = getGreen(pixel)
blueValue = getBlue(pixel)
if redValue > 175 and greenValue < 175 and blueValue < 175 :
#Turn the pixel white
setRed(pixel,255)
setGreen(pixel,255)
setBlue(pixel,255)
else:
#Otherwise, turn it black.
setRed(pixel,0)
setGreen(pixel,0)
setBlue(pixel,0)
return picture
The result of testing for “red areas” is an image where most of the apple has been detected, but a lot of other pixels scattered around the image are also somewhat “reddish”. If you want the robot to turn towards the direction with the most red pixels, you need to calculate the average X (horizontal) location of the pixels that have been marked (by turning them white).
Drawing a Line in the Red Area
If you examine every pixel in the image, and average the X coordinates of all the “detected” (or white) pixels, you can determine the middle of the red areas. To do this, you use two loops (one for the Y positions, and one for the X positions) to look at every pixel, and add up the X positions of all pixels that are turned “on” (or white). Because a white pixel has values of (255,255,255) and an “off” or black pixel has values of (0,0,0) you can take a shortcut and only test the value of one of the three colors.
def AverageXofWhitePixels(picture):
sumX = 0.0 # Use floating point values
counter = 0.0 # Use floating point values
for xPos in range(0, getWidth(picture) ):
for yPos in range(0, getHeight(picture) ):
pixel = getPixel(picture,xPos,yPos)
value = getGreen(pixel)
if value > 0 :
sumX = sumX + xPos
counter = counter + 1
averageX = sumX / counter
return int(averageX) #Return an Integer
Now, you can use the functions you have defined so far to locate the average X location of red pixels, and draw a line at that position:
myPicture = takePicture() picture = copyPicture(myPicture) picture = findRedAreas(picture) XposAvg = AverageXofWhitePixels(picture) drawVerticalRedLine(myPicture,XposAvg) show(myPicture)
Because of all the other “red” pixels detected that were not on the apple, the red line is not exactly centered on the apple, but it is close enough that you could use the value in the XposAvg variable to figure out which way to turn the robot to face the apple.







