Working with Image Streams

From Wiki for iCub and Friends
Jump to: navigation, search

Here we give an example of some code which reads a stream of images from a source, performs an operation on them, and generates an output image. We just add a moving blue circle to an image stream.

The code (from directory $YARP_ROOT/example/os/image_process.cpp):

 #include <ace/config.h>
 #include <yarp/os/all.h>
 #include <yarp/sig/all.h>
 using namespace yarp::os;
 using namespace yarp::sig;
 using namespace yarp::sig::draw;
 int main(int argc, char *argv[]) {
   // Initialize network
   Network::init();
   // Make a port for reading and writing images
   BufferedPort<ImageOf<PixelRgb> > port;
   // Get command line options
   Property options;
   options.fromCommand(argc,argv);
   // Set the name of the port (use "/worker" if there is no --name option)
   ConstString portName = options.check("name",Value("/worker")).asString();
   port.open(portName);
   int ct = 0;
   while (true) {
       // read an image from the port
       ImageOf<PixelRgb> *img = port.read();
       if (img==NULL) continue;
       // add a blue circle
       PixelRgb blue(0,0,255);
       addCircle(*img,blue,ct,50,10);
       ct = (ct+5)%img->width();
       // output the image
       port.prepare() = *img;
       port.write();
   }
   Network::fini();
   return 0;
 }

We use CMake to help compile our C++ code. For tips on how to compile files like this, see:

Suppose we have an image source on port /USERNAME/source such as:

 yarpdev --device test_grabber --name /USERNAME/source --mode line --framerate 10

And suppose we have an image viewer on port /view:

 yarpview --name /USERNAME/view

Then we can hook this program up in between as follows:

 ./image_process --name /USERNAME/worker
 yarp connect /USERNAME/source /USERNAME/worker
 yarp connect /USERNAME/worker /USERNAME/view

(On Windows, you'll need to call image_process.exe from the Release or Debug directory).

You should see the normal scrolling line of test_grabber, with a moving circle overlaid.

Accessing individual pixels

Suppose you want to change the above program to find greenish pixels in the image. Here's one way to do it:

 ImageOf<PixelRgb> *img = port.read();
 ...
 for (int x=0; x<img->width(); x++) {
   for (int y=0; y<img->height(); y++) {
     PixelRgb& pixel = img->pixel(x,y);
     // very simple test for greenishness
     // make sure green level exceeds red and blue by a factor of 2
     if (pixel.g>pixel.r*1.2+10 && pixel.g>pixel.b*1.2+10) {
        // there's a greenish pixel at (x,y)!
     }
   }
 }

Return to YARP Tutorial Index