Appendix A. Advanced Shell Tips

Chapter 2 introduced the SimpleCV shell and some of the most common commands. This appendix covers a few additional tricks for working with the shell, including:

  • Macros to automate tasks

  • Timing to test the performance on scripts

Not all vision system developers need to know this, but power users may find that these tricks help streamline the development process.

Macro Magic

Chapter 2 described the SimpleCV shell as a tool for testing small snippets of code. However, when working with more than a few lines of code, it is often convenient to create reusable blocks of code. This is done with macros. Macro means big. In the case of a shell, this means a big block of code. Obviously, big is a relative term, in this case contrasted with the “micro” size of a few lines of code. Macros are most appropriate when testing or using the same block of code repeatedly. For example, macros are great for automatically setting up the camera object, loading a few images, or other repetitive initialization tasks.

Note

Macros probably sound a bit like functions. However, macros do not take any parameters. The closest thing to a parameter with a macro is to create variables outside of the macro, set those variables to a desired value, and then reference those variables from inside the macro.

The SimpleCV shell already has macro support built in. Shell macros are created from the history of previously used commands. These commands are bundled together into a single macro. A macro can be thought of as a shortcut versus using the up-arrow to look up and execute a bunch of previously entered commands. Therefore, the first step in constructing the macro is to run the commands to be included in the macro. For example, in the SimpleCV shell, perform the following basic camera setup:

>>> from SimpleCV import Camera
>>> cam = Camera()
>>> img = cam.getImage()

Notice that each line of code entered in the shell has a line number associated with it. For example, the first line of code is labeled with SimpleCV:1. The previously entered example should look like Figure A-1.

Notice the line numbering for each shell command

Figure A-1. Notice the line numbering for each shell command

Although the line numbers for the commands are displayed in the SimpleCV prompt, the commands are interlaced with the output of those commands. However, on most systems, the history function lists all previous commands and their line number.

>>> history  1
1: from SimpleCV import Camera  2
2: cam = Camera()
3: img = cam.getImage()
4: _ip.magic("history ")
1

Enter the history command to output the list of previous commands.

2

The following will be output, showing the previous commands.

Your actual line numbers may vary from the above description if you issued other commands during your shell session. However, the overall format should look similar. In particular, you should see the previously entered commands to initialize the camera and snap a picture. The next step is to create a macro to easily initialize the camera and grab a picture. In our example, the commands involved correspond to the line numbers 1 through 3. To create the macro, use the macro command with the name to give the new marcro and the appropriate line numbers to include in the macro. For example, to create a macro named quickinit, and have it execute the commands from lines 1 through 3:

>>> macro quickinit 1-3 1
Macro `quickinit` created. To execute, type its name (without quotes). 2
Macro contents:
from SimpleCV import Camera
cam = Camera()
img = cam.getImage()
1

Enter the word macro, followed by the name of the macro and the line numbers to include in the macro.

2

The remaining shows the output from the macro command, including a list of all the commands that are included in the macro.

The macro is now created. To execute it, simply type the macro’s name:

>>> quickinit  1
>>> img.show()  2
1

The quickinit macro was created in the previous code block.

2

The img object was created by the quickinit macro.

To see a list of previously created macros, type the macro command with no parameters:

>>> macro
['quickinit']

Because only one macro was previously created, only one is displayed. If more are created, they would also be listed there. If you want to save a macro to use in other sessions, you can use the store command. In addition, to see a list of all the commands that were included in a previously created macro, use the print command followed by the name of the macro. To show the commands from the previously created quickinit macro:

>>> print quickinit  1
from SimpleCV import Camera  2
cam = Camera()
img = cam.getImage()
1

The print command followed by a macro name lists all of the commands in a macro.

2

This is an output of the print macro command.

The above example is probably a bit inefficient. It is not necessary to import the Camera library every time. In fact, the SimpleCV shell automatically loads all of SimpleCV’s libraries, so no import statement is even needed. Fortunately, it is possible to edit a previously created macro using the edit command.

>>> edit quickinit

Caution

On many Mac and Linux systems, the default editor for the edit command is VI. VI is not the world’s easiest editor for casual users. For more information on using VI, visit http://www.vim.org and click on the link for their documentation. It can be easy to get stuck on even basic commands like saving or quitting. As a quick hint to those who may be stuck, press i when in VI in order to enter insert mode to edit the file. To exit insert mode, press escape to be switched back to command mode. From command mode, save the changes and quit VI by entering :wq (as in write-quit).

Run and Edit Python Scripts

The SimpleCV shell can also be used to work with external Python scripts. This can be helpful when testing and debugging files. For example, assume that the photo booth demo from Chapter 2 is saved in a file named photobooth.py. To run this from inside the shell, simply type:

>>> run photobooth.py

This will startup and run the photo booth application. To stop the execution, either click the close button on the window, or hit Control-C from inside the shell.

Notice that the messages in the application appear in a very small font in the middle of the screen. Wouldn’t it be better to increase the font size and put the message in the corner? It is easy to open and edit files directly in the shell. In fact, this was already demonstrated earlier. Simply type:

>>> edit photobooth.py

This opens the editor. Now go down to line 13 and change the previous drawText() command to:

img.drawText("Starting app.  Left click to save photo", 0, 0, fontsize=50, color=Color().getRandom())

Next, go to line 30 to find the other drawText() command and change it to:

img.drawText("Took a photo.  Click the mouse to take another.", 0, 0, fontsize=50, color=Color().getRandom())

Now save and exit. The shell will save the file and instantly relaunch the program. This is rather convenient when repeatedly jumping back and forth between editing a file and then running to test the file.

Timing

Some of the feature detection and template matching algorithms can be complex and computationally intensive algorithms. When time matters, it is important to understand how long it takes a program to execute. For example, consider a security camera designed to detect people walking into a room. If the program takes five seconds just to process one image, then a person could sneak by between frames. Or another case where speed would matter would be a camera on an assembly line that needs to capture and process images fast enough to keep up with the flow of products. Fortunately, it is fairly easy to test a program, identify the bottlenecks, and tune the program to better align with the software design requirements.

The timeit function is used to time a given function. To see a basic example of how this works, consider a basic blob detection example. This appears to run pretty quickly, but how fast? Use the timeit() function to find out:

>>> img = Image('logo')
>>> %timeit blobs = img.findBlobs(100)  1
1

Notice that timeit was added to the beginning of this line. As a result, this line of code will be timed.

The timeit function actually runs the specified line of code 100 times and find the best times. The output from the function will be something like: 100 loops, best of 3: 2.12 ms per loop. This means that it takes 2.12 milliseconds to run that snippet of code. (Actual output will vary from computer to computer.) Not too bad.

But still, the logo image is kind of small. It it relatively easy to find blobs on a small image because there is less data to process. What about for a larger image? For example, an HD camera could be capturing images that are 1920×1280. How much longer will that take? The SimpleCV shell does not ship with a 1920×1280 version of an image, but it is possible to fake one by scaling the built-in image to those dimensions.

>>> img = Image('logo')
>>> imgHD = img.resize(1920, 1280)  1
>>> %timeit blobs = imgHD.findBlobs(100)
1

This scales the image to 1920×1280.

In this case, the computing time was 41.7 ms. Once again, the actual output time will vary, but it will probably require about 20 times more processing time than the original image. 40 milliseconds is still pretty quick, but this is a single line of code on a pretty simple image.

Tip

Need to speed up a program? One trick is to shrink the image size. For example, a 640×480 image is a lot easier to process than a full HD image.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset