# SoftBank Robotics documentation What's new in NAOqi 2.8?

# Processing images

<< return to C++ examples

## Principle

This section explains how to implement an access to NAO’s images when the module is remote.

To retrieve the images, subscribe as usual using a proxy to ALVideoDevice, and specify the framerate, resolution etc.

The image buffer and metadata is returned within an AnyValue. This example shows how to parse the fields of the AnyValue.

## Example: ImageService

This example implements a module retrieving images optimally. As an example, the image is stored in a RAW ppm image file.

The whole example is available here: `imageservice.zip`

### Camera definitions:

`cameradefs.h`

    #pragma once

    /** \file cameradefs.hpp
     *  \brief vision defines
     */

    namespace qi
    {
      namespace camera
        {
        /**
        *Camera Model ID
        */
        const int kOV5640  = 3;

        /**
        *Camera Index
        */
        const int kTopCamera = 0;
        const int kBottomCamera = 1;

        /**
        *Format of the image
        */
        const int k16VGA = 4; // 2560*1920
        const int k4VGA  = 3; // 1280* 960
        const int kVGA   = 2;  // 640* 480
        const int kQVGA  = 1;  // 320* 240

        /**
        *ColorSpace
        */
        const int kYuvColorSpace = 0;
        const int kyUvColorSpace = 1;
        const int kyuVColorSpace = 2;
        const int kRgbColorSpace = 3;
        const int krGbColorSpace = 4;
        const int krgBColorSpace = 5;
        const int kHsyColorSpace = 6;
        const int khSyColorSpace = 7;
        const int khsYColorSpace = 8;
        const int kYUV422ColorSpace = 9;
        const int kYUVColorSpace = 10;
        const int kRGBColorSpace = 11;
        const int kHSYColorSpace = 12;
        const int kBGRColorSpace = 13;     // for opencv ease of use
        const int kYYCbCrColorSpace = 14;  // for tiff io implementation
        const int kH2RGBColorSpace = 15;   // H from HSY to RGB in fake colors
        const int kHSMixedColorSpace = 16; // HS and (H +S)/2

        /**
         * Parameter Id (used for camera registers configuration)
         */
        const int kCameraBrightnessID             = 0;
        const int kCameraContrastID               = 1;
        const int kCameraSaturationID             = 2;
        const int kCameraHueID                    = 3;
        const int kCameraGainID                   = 6;
        const int kCameraHFlipID                  = 7;
        const int kCameraVFlipID                  = 8;
        const int kCameraAutoExpositionID         = 11;
        const int kCameraAutoWhiteBalanceID       = 12;
        const int kCameraExposureID               = 17;
        const int kCameraSharpnessID              = 24;
        const int kCameraBacklightCompensationID  = 34;
        const int kCameraAverageLuminanceID       = 39;
        const int kCameraAutoFocusID              = 40;
        const int kCameraFocusID                  = 43;

      } //namespace camera
    } // namespace qi

### Header:

`imageservice.h`

    #pragma once

    #include <qi/anyobject.hpp>
    #include <qi/session.hpp>

    #include <string>

    class ImageService
    {
      public:

        ImageService(qi::SessionPtr session);

        ~ImageService();

        void imageProcessing();

      private:
        qi::SessionPtr  _session;
        qi::AnyObject   _alvideodevice;
        std::string     _camera;
    };

### Source:

`imageservice.cpp`

    #include "imageservice.h"
    #include "cameradefs.h"

    #include <qi/anyobject.hpp>
    #include <qi/log.hpp>

    #include <fstream>

    qiLogCategory("imageService");

    ImageService::ImageService(qi::SessionPtr session)
      :_session(session)
    {
      _alvideodevice = session->service("ALVideoDevice");
      _camera = _alvideodevice.call<std::string>("subscribe", "CameraTop", qi::camera::kVGA, qi::camera::kRGBColorSpace, 5);
    }

    ImageService::~ImageService() {
      try {
        _alvideodevice.call<std::string>("unsubscribe", _camera);
      }
      catch (...) {
        qiLogError() << "Error while unsubscribing";
      }
    }

    void ImageService::imageProcessing() {
      /** Retrieve a pointer to the image. */
      qi::AnyValue imageData = _alvideodevice.call<qi::AnyValue>("getImageRemote",
                                                                  _camera);

      /** Parse the AnyValue **/

      int width = imageData.at(0).to<int>();
      int height = imageData.at(1).to<int>();
      int colorspace = imageData.at(3).to<int>();

      qiLogInfo() << "Got an image: width=" << width << ", height=" <<
              height << ", colorspace=" << colorspace;

      long long timestamp =
          (imageData.at(4).to<long long>() * 1000000LL + imageData.at(5).to<long long>()) * 1000LL;

      qiLogInfo() << "Image timestamp: " << timestamp << " ns";

      float leftAngle = imageData.at(8).to<float>();
      float topAngle = imageData.at(9).to<float>();
      float rightAngle = imageData.at(10).to<float>();
      float bottomAngle = imageData.at(11).to<float>();

      qiLogInfo() << "Image angles: " << leftAngle << ", " << topAngle << ", "
                                      << rightAngle << ", " << bottomAngle;

      /** Get the image buffer **/
      std::pair<char*, size_t> imageBuffer = imageData.at(6).content().asRaw();

      qiLogInfo() << "Image size: " << imageBuffer.second << " bytes";

      /** Do whatever processing you want...    **/
      /** Here, writing raw image into a ppm file **/

      std::ofstream outfile("/tmp/testimage.ppm",std::ofstream::binary);

      outfile << "P6\n"
          << width << " " << height << "\n"
          << "255\n";

      outfile.write(imageBuffer.first, imageBuffer.second);
      outfile.close();

    }

    QI_REGISTER_MT_OBJECT(ImageService, imageProcessing);

### Main:

`main.cpp`

    #include <qi/applicationsession.hpp>
    #include <boost/shared_ptr.hpp>
    #include "imageservice.h"

    int main(int argc, char* argv[])
    {
      qi::ApplicationSession app(argc, argv);
      app.startSession();
      qi::SessionPtr session = app.session();
      session->registerService("ImageService", qi::AnyObject(boost::make_shared<ImageService>(session)));
      app.run();
      return 0;
    }

### CMakeLists.txt:

`CMakeLists.txt`

    cmake_minimum_required(VERSION 2.8)
    project(imageservice)
    find_package(qibuild)

    set(_srcs
      main.cpp
      cameradefs.h
      imageservice.h
      imageservice.cpp
    )

    qi_create_bin(imageservice SRC ${_srcs} DEPENDS QI)

Glossary Site map Index Support Contact Legal Notices