Running a CMUCam through a Lisp Program May 2009

State of the project:

I have successfully used the foreign-function method in lisp to call a method from another programming language. In my example I used a c file, but under the method it should be able to call something from Java or anything else. Instructing on performing this adaptation are as follows:

_

write C code in file named test.c

#include <stdio.h>

void hoho() {

double v1, v2, m;
v1 = 5.2;
v2 = 7.9;
printf("The mean of %3.2f and %3.2f is \n", v1, v2);
fflush(stdout);

}

at Linux command line:

  cc -c -fPIC test.c -o test.o
  ld -shared -o test.so test.o

at Lisp prompt:

   :ld /home/trclarke/hunswork/test.so
   ;; the following DEFINES the function named HOHO 
   ;; whose defn is in test.c
   (ff:def-foreign-call hoho nil)
   ;; then CALL the function:
   (hoho)

TESTER example:

int process(int x, int y) {

printf("The stuff of %d and %d is: %d\n", x, y, (x * y));
fflush(stdout);
return x*y;

}

(ff:def-foreign-call process ((x :int) (y :int))
       :returning :int)	   
 (process 3 4)

_

With regards to the cmucam, I have successfully hooked it up to a lab computer and run minicom to ensure that the camera is functioning. The next step is to write code calling the camera in a non-Lisp language that can then in turn be called by Lisp. Listed below (under pages sharing code that interfaces with cmucam) is a page showing many examples of programs running the cmucam. There are many example files in many different languages, and any could use be built upon to write a program for our purposes. The best choice I saw seemed to be the first example, which uses Java. The ReadMe file describing how to use this program is contained below.

Interfacing with the camera requires several drivers be installed on the machines. These can be found below under Pages relating to the CMU, and the directions in installing them can be found in the main installation guide. The next thing to be done is write code in a non-Lisp language to do something with the camera. Once that program communicates with the camera and works properly, Lisp can then be used to call the foreign function from within Lisp. At that point the machines will be able to independently run the camera using a Lisp function.

_

Useful Websites:

Regarding Lisp foreign-function interface:

http://www.franz.com/support/documentation/7.0/doc/foreign-functions.htm (my main source)

http://uffi.b9.com/

Regarding creation of a shared object file:

http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.dapip.doc/dapip308.htm

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

Pages relating to the CMUCam:

http://www.cmucam.org/ (main website)

http://www.cmucam.org/wiki/Downloads (downloads, the necessary drivers and such can be found here)

http://www.seattlerobotics.com/CMUcam3_sdk_guide.pdf (main installation guide)

Pages sharing code that interfaces with cmucam:

http://www.cs.cmu.edu/~illah/ROBOCODE/index.html (has many different examples of programs written for a camera)

Clicking on the first “here” in the first paragraph (right below RoboCode) will download a package for interfacing java code with the camera (written for a USB cam, but should work with the cmucams). The ReadMe file pertaining for this package is as follows. It gives examples of basic commands that can be used to communicate with the camera.

16×62 USB Camera Robot Vision Interface Code


by Rob Siemborski rjs3+@andrew.cmu.edu-

low level libraries by Zhenlan Jin zjin@andrew.cmu.edu-

tested by Brennan Sellner bsellner@andrew.cmu.edu-

advisor Illah Nourbakhsh illah@ri.cmu.edu


This directory contains code to access the USB cameras via the

Java Media Framework (JMF).

This code was designed around JMF 2.1.1.

To begin, boot the computer and connect the camera to the USB port.

To use the code, you can examine the application “Driver.java” which

contains simple code to read from the camera and flash a rectangle on the screen image.

It will also report the values of a pixel inside of the-rectangle, to show that you can access

the individual pixel values after grabbing an image.

To use this code in your own application, you will want to copy all of the

class files in this directory to your own code.

In your application, start by getting an instance of the

UsbCamera class:

UsbCamera cam = UsbCamera.getInstance()

This will initialize the camera.

Note that there is only one camera object available in the entire JVM

(getInstance will return references to the same object after the first is created).

To display a window with the camera's current view, simply use the setVisible method:

cam.setVisible(true)

Every time you want to take a new picture,

you can do so with the snap method (this will also update the picture on the screen):-

cam.snap()–

You can do the “get picture” and “update screen” steps separately with:

cam.getFrame();
cam.draw();

Note that grabbing frames at close to the maximum frame rate will increase the lag between the time

that you call getFrame and the time that that particular frame becomes available. You probably don't

ant to pull frames faster than 10 frames/second.

To read any pixel value off of the currently caputured

image, use the getPixel method:-

 int pixel[] = cam.getPixel(30, 30);	    
System.out.println(" r:"+pixel[UsbCamera.RED]+
		       " g:"+pixel[UsbCamera.GREEN]+
		       " b:"+pixel[UsbCamera.BLUE]);

Note the use of the UsbCamera.RED (BLUE, and GREEN) constants to access the array that is returned

by the camera. If an invalid pixel is requested, the function will return a null-reference.

You can also get

“raw” pixel data (which is faster to do) by calling the getRawPixel method. This will return a single integer

that represents the red, blue, and green channels-all at once. To separate them out, we provide some static

methods:

int val = cam.getRawPixel(10,10)

int red = UsbCamera.getRed(val);

int blue = UsbCamera.getBlue(val);

int green = UsbCamera.getGreen(val);

You can get the size of the pixels from the UsbCamera.XSIZE and UsbCamera.YSIZE members.

To aid in debugging, you can draw a rectangle on top of the picture. Do this using the setRect method:

  cam.setRect(x, y, width, height)

The parameters are the x and y coordinates of the upper left-corner, followed by the width and height of the rectangle.

To remove the rectangle, do the following:

  cam.unsetRect();

–Usage Notes:——————–

This code offers no interface to adjust video parameters of the camera-such as brightness, contrast,

auto gain, and auto whitebalance. You will need to do that via other means. If you are in the 16×62

class, please see the “Using The Cameras” text file.

This code was specifically designed to work with

the Logitech Quickcam Messenger cameras used by the 16×62 class. It may need adjustment to use

other USB cameras (specifically in terms of the image size).

To install the necessary parts of this softare on your system, please see the Install.txt file.

Trevor Clarke May 2009