UserPreferences

Pyro Vision Functions for the Pioneer


Using a Pioneer with a Camera

The camera should be plugged into the Pioneer, and the green light on the front of the camera should be on. If the light isn't on, check to make sure the power switch on the back of the camera is on.

/!\ Because of the way the connection to the camera is currently implemented, if there is a bug in your program that prevents it from loading, you must exit Pyro, correct the bug, and then re-invoke Pyro. Reloading your edited Brain program will not work. Also in these cases, Pyro may not shut down cleanly leaving processes running. You can suspend these processes with Control-Z and then do a killall -9 pyro to kill these hung processes.

Pyro Vision Functions

The following functions can be used in Pyro with the Video for Linux (V4L) frame grabber on the Pioneers. They are defined in /usr/local/pyrobot/camera/v4l/init.py.

To start the V4L service:

        self.getRobot().startService("V4LCamera")
        self.camera = self.getRobot().getService("V4LCamera")
        self.camera.makeWindow()

The image that the camera captures is dumped to a shared memory buffer. This buffer can be accessed by both Pyro and C. For speed reasons, the vision processing is done in C. All the changes to the image are done by manipulating this shared memory buffer, which is then read by pyro to display the newly modified image.

The frame grabber grabs images in a different thread then what the program is running in, so it updates itself reguardless of where the program is executing. This can cause wierd things to happen. Lets say you run a color filter to keep only red items in the image, and halfway through the filter process, the framegrabber updates the image. This would cause the filtering that has just been done to be over written, and the filter will continue to filter the bottom half of the image. Therefore, you would be left with an image with the top half not filtered and the bottom half being filtered for red. To stop this, the camera has a flag called lockCamera. If this flag is set, it will stop the framegrabber from being able to update the shared memory so that all the filtering, blobbing, etc can be done on the same image. Here is an example:

        self.camera.lockCamera = 1 #lock the buffer
        self.camera.superColor("red",0)
        self.camera.maxBlob(2, 1, 255, "mass")
        self.camera.lockCamera = 0 #unlock the buffer

Once you are done manipulating the image and have the information you need, setting lockCamera to 0 will allow the framegrabber to update the images again.

Another flag that the camera has is the sleepFlag. If set, the sleepFlag will cause the program to sleep, for what sleepTime is set to, after filtering processes have been completed. This allows the effects to be seen in the video window. This is mostly for testing purposes to make sure that the filter does what you want it to do. Here is an example:

        self.camera.sleepTime=2.0  #sleep for 2 seconds after filters
        self.camera.sleepFlag = 1  #turn sleep flag on
        self.camera.lockCamera = 1 #lock the buffer
        self.camera.superColor("red",0)
        self.camera.maxBlob(2, 1, 255, "mass")
        self.camera.lockCamera = 0 #unlock the buffer

General explanation of use of channel for processing.

Talk about problems with color filtering, and vision in general.

camera.colorFilterHiLow

This function filters for color values within specified ranges. Points that have values between the low and high ranges specified for red, green and blue will be marked in the buffer as containing the color. After using this function, you would probably call maxBlob.

Parameters:

Return Values:

Example calls:

  self.camera.colorFilterHiLow(70,30,30,255,60,60)

http://www.cs.uml.edu/robots/PyroImages/foo3.gif http://www.cs.uml.edu/robots/PyroImages/foo.gif

  self.camera.colorFilterHiLow(0,30,30,255,60,60)
http://www.cs.uml.edu/robots/PyroImages/HiLowBefore0255.gif http://www.cs.uml.edu/robots/PyroImages/HiLowAfter0255.gif

camera.colorFilterOneTol

This function filters the image for a specific color with one tolerance being used for each of the RGB values.

Parameters:

Return Values:

Example calls:

  self.camera.colorFilterOneTol(215,215,70,40,2)

http://www.cs.uml.edu/robots/PyroImages/OneTolBefore70.gif http://www.cs.uml.edu/robots/PyroImages/OneTolAfter70.gif

camera.colorFilterThreeTol

This function also filters the image for a specific color, but the user has the option of setting a specific individual tolerance for R,G and B.

Parameters:

Return Values:

Example calls:

  self.camera.colorFilterThreeTol(255,255,0,30,30,200,0)

http://www.cs.uml.edu/robots/PyroImages/ThreeTolBefore200.gif http://www.cs.uml.edu/robots/PyroImages/ThreeTolAfter200.gif

camera.superColor

Lets say you wanted to filter for red. If you just look at the red component and filter and color that has a red value over 180, for instance, then any white pixel will be filtered as a red pixel, because white has a red value of 255. What super color does, is subtracts out the secondary colors from the main color. So if you want to filter on red, the green and blue values get subtracted from the red value resulting in an overall value from 0-255. Super Color is only for Red, Green and Blue (the three primary colors). The return value is between 0-255 so you have the ability to choose how red, green, or blue you want to filter for.

Parameters:

Return Values:

Example calls:

Before:

http://www.cs.uml.edu/robots/PyroImages/superRedBefore.jpg

  self.camera.superColor("red",0)

http://www.cs.uml.edu/robots/PyroImages/superRedNoLightAfter.jpg

  self.camera.superColor("red",0,1)

http://www.cs.uml.edu/robots/PyroImages/superRedLightAfter.jpg

camera.trainColor

The train color function takes a histogram of the colors in a 50x50 pixel box in the center of the image. It takes the average color of the peak and that is the color that it returns. This function is useful for determining what overall RGB value an object has. It is also good for passing into a filter function to beable to filter for the color that was just trained on.

Parameters:

Return Values:

Example call(s).

  self.camera.trainColor()
  self.camera.colorFilterOneTol(self.camera.histRed,self.camera.histGreen, self.camera.histBlue, 30)

camera.gaussianBlur

The gaussianBlur function blurs the image by changing the current pixel's values by weighting the values of the pixels around it. The kernel size is 3, and cannot be changed.

Parameters:

Return Values:

Example call:

  self.camera.gaussianBlur()

http://www.cs.uml.edu/robots/PyroImages/GaussBefore.gif http://www.cs.uml.edu/robots/PyroImages/GaussAfter.gif

camera.meanBlur

This function blurs the image by changing the color of the pixel being looked at to the mean value of the pixels surrounding it. The number of surrounding pixels being looked at is defined by the kernel parameter. If kernel is 3, then the pixel being looked at is the center of a 3x3 box, shown in the diagram.

http://www.cs.uml.edu/robots/PyroImages/meandiagram.jpg

Parameter:

Return Values:

Example calls:

Before:

http://www.cs.uml.edu/robots/PyroImages/MeanBefore3.gif

  self.camera.meanBlur()

http://www.cs.uml.edu/robots/PyroImages/MeanAfter3.gif

  self.camera.meanBlur(9)

http://www.cs.uml.edu/robots/PyroImages/MeanAfter9.gif

camera.medianBlur

This function blurs the image by changing the color of the pixel being looked at to the median value of the pixels surrounding it. The number of surrounding pixels being looked at is defined by the kernel parameter. If kernel is 3, then the pixel being looked at is the center of a 3x3 box, shown in the diagram.

http://www.cs.uml.edu/robots/PyroImages/mediandiagram.jpg

Parameter:

Return Values:

/!\ Currently, MedianBlur runs very slowly and should only be used for learning about the differnt types of blurs available. Also, the larger the kernel size, the slower it will run.

Example calls:

Before:

http://www.cs.uml.edu/robots/PyroImages/MedianBlurBefore.jpg

  self.camera.medianBlur(5)

http://www.cs.uml.edu/robots/PyroImages/MedianBlurAfter5.jpg

  self.camera.medianBlur(9)

http://www.cs.uml.edu/robots/PyroImages/MedianBlurAfter9.jpg

  self.camera.medianBlur(11)

http://www.cs.uml.edu/robots/PyroImages/MedianBlurAfter11.jpg

camera.maxBlob

This function finds the maximum blob of an image by either mass or area. The color channel and the high and low values are passed in. MaxBlob searches the image and keeps track of the all the blobs in the image. It then returns the upper left and lower right coordinates, as well as the mass of the maximum blob. A white box is then drawn around this max blob for identification purposes during testing.

Parameter:

Return Values:

Example calls:

  self.camera.maxBlob(1,1,255)

http://www.cs.uml.edu/robots/PyroImages/BeforeBlob1.gif http://www.cs.uml.edu/robots/PyroImages/AfterBlob1.gif

  self.camera.maxBlob(2,1,255)

http://www.cs.uml.edu/robots/PyroImages/BeforeBlob2.gif http://www.cs.uml.edu/robots/PyroImages/AfterBlob2.gif

Edge Detection

This function uses the sobel method to detect the edges of an image.

  self.camera.edgeDetection()

http://www.cs.uml.edu/robots/PyroImages/MtDew_blur.jpeg http://www.cs.uml.edu/robots/PyroImages/MtDew_edges.jpeg

camera.saveImage

This function will save the image that is in the processing buffer to a ppm file. Seeing as how ppm files are quite large, you might want to convert the ppm files to a different image format. The best way to do this is to use an image editor (such as xv) and use Save As to save the image in a different format. Another way is to use xview with the following command:

The unix command ppmtogif can also be used to convert your ppm file to the gif format, however, if you try to use ppmtogif to convert your file you may get an error that there are too many colors. You may try the following, but the colors in the resulting image may not match the colors of the original image in some spots, which is why we recommend using an image editing program.

Parameters:

Return Values:

Example call:

  self.camera.saveImage("myPicture.ppm")

Examples

1. This is a demonstration of the robot blurring an image, training on the color in the center of the image, filtering for that color, and then finding the max blob.

from pyrobot.brain import Brain
from pyrobot.brain.behaviors.core import *  # Stop

import time

class CameraTest(Brain):
    def __init__(self, name, robot):
        Brain.__init__(self, name, robot)
        print "initializing camera ..."
        self.getRobot().startService("V4LCamera")
        self.camera = self.getRobot().getService("V4LCamera")
        self.camera.makeWindow()

        print "done initializing camera"

    def step(self):
        self.camera.lockCamera = 1
        self.camera.sleepFlag = 1
        self.camera.sleepTime = 1.0

        print "Blurring Image"
        self.camera.gaussianBlur()

        print "Training on a color"
        self.camera.trainColor()
        print "Trained on color r:", self.camera.histRed,
        print " g:", self.camera.histGreen,
        print " b:", self.camera.histBlue

        print "Filtering Image"
        self.camera.colorFilterOneTol(self.camera.histRed,self.camera.histGreen,self.camera.histBlue )

        print "Blobbing Image"
        self.camera.maxBlob(1, 1, 255)

        self.camera.flag = 0
        sleep(0.5)

        print "\n"

def INIT(robot):
    return CameraTest('CameraTest', robot)

2. In this example, the robot uses superColor to find red, blobs the image, then tracks the largest blob by moving the camera using the PTZ service.

from pyrobot.brain import Brain
from pyrobot.brain.behaviors.core import *  # Stop

import time

class CameraTest(Brain):
    def __init__(self, name, robot):
        Brain.__init__(self, name, robot)
        print "initializing camera ..."
        self.getRobot().startService("V4LCamera")
        self.camera = self.getRobot().getService("V4LCamera")
        self.camera.makeWindow()

        self.getRobot().startService("ptz")
        self.ptz = self.getRobot().getService("ptz")

        self.ptz.pan(0)
        self.ptz.tilt(0)
        self.ptz.zoom(0)

        self.pan = 0
        self.tilt = 0


        print "done initializing camera"

    def step(self):
        self.camera.lockCamera = 1

        self.camera.superColor("red",2)

        print "Blobbing Image"
        self.camera.maxBlob(2, 1, 255, "mass", 0)

        self.camera.lockCamera = 0

        if( self.camera.mass > 10 ):
            self.pan = (( self.camera.min_x + self.camera.max_x ) / 2 -
                        (self.camera.width/2)) / 10
            self.tilt = -1*(( self.camera.min_y + self.camera.max_y ) / 2 -
                            (self.camera.height/2)) / 10

            self.ptz.panTiltRel(self.pan, self.tilt)

            print "PAN IS ", self.pan
            print "TILT IS ", self.tilt

        print "\n"

def INIT(robot):
    return CameraTest('CameraTest', robot)


Exercises

1. Follow that Ball.

2. Pick Up the Trash.

Pyro Modules Table of Contents

Modules

  1. PyroModuleIntroduction

  2. PyroModuleObjectOverview

  3. PyroModulePythonIntro

  4. PyroModuleDirectControl

  5. PyroModuleSequencingControl

  6. PyroModuleBehaviorBasedControl

  7. PyroModuleReinforcementLearning

  8. PyroModuleNeuralNetworks

  9. PyroModuleEvolutionaryAlgorithms

  10. PyroModuleComputerVision

  11. PyroModuleMapping

  12. PyroModuleMultirobot

  13. FurtherReading

Additional Resources

  1. PyroIndex

  2. PyroAdvancedTopics

  3. PyroUserManual

  4. [WWW]Pyro Tutorial Movies

Reference: PyroSiteNotes