Search code examples
javascriptpepper

Pepper: strange image from camera


I want to show an image in the tablet of Pepper from his camera. I have done the Javascript code to process and show the image in a web view. The problem is that the image showed is strange:

enter image description here

I have written this code based on this example:

var CAMERA_ID = 'fger';

QiSession(function (session) {

session.service('ALMemory').then(function (ALMemory) {
  // Listener to Choregraphe APP
  ALMemory.subscriber('PepperQiMessaging/totablet').then(function(subscriber) {
    subscriber.signal.connect(toTabletHandler);
  });
  // Says to Choregraphe that I'm listening with the id QR
  ALMemory.raiseEvent('PepperQiMessaging/fromTabletResponse', 'QR');
  // Video receiver function
  session.service('ALVideoDevice').then(playVideo);

  });
});

 // This is the important part
 function playVideo(video) {
    video.subscribeCamera(
      CAMERA_ID,
      0, // cameraId kTop kBottom kInfred(color:17)
      1, // Image of 640*480px
      11, //RGB
      10 // framerate 1~30
    ).then(function(result){
      video.getImageRemote(result).then(function(image) {

        if (image) {
          var canvas = $('canvas')[0].getContext('2d');

          var width = image[0];
          var height = image[1];
          var nb = image[2];
          var imageData = image[6];
          var read = 0;

          var img = canvas.createImageData(width, height);
          var pixs = img.data;
          var binary = window.btoa(imageData);

          var len = imageData.length;
          var m = len/nb;

          // Transformations to get the image in RGB
          for (var i = 0; i < m; i++) {
            pixs[i*4] = binary.charCodeAt(i*nb);
            pixs[i*4+1] = binary.charCodeAt(i*nb+1);
            pixs[i*4+2] = binary.charCodeAt(i*nb+2);
            pixs[i*4+3] = 255;
          }

          canvas.putImageData(img, 0, 0);
        }

        video.unsubscribe(CAMERA_ID);

      });
    });
  }

What I have to do to solve this problem?


Solution

  • At the end I found the solution. I found another example that it worked for me (the image is greyscale).

    This is the algorithm to transform the bytes received form the camera to an image:

    function getImage(ALVideoDevice, subscriberId) {
      ALVideoDevice.getImageRemote(subscriberId).then(function (image) {
        if(image) {
          var imageWidth = image[0];
          var imageHeight = image[1];
          var imageBuf = image[6];
    
          if (!context) {
            context = document.getElementById('canvas').getContext('2d');
          }
          if (!imgData || imageWidth != imgData.width || imageHeight != imgData.height) {
            imgData = context.createImageData(imageWidth, imageHeight);
          }
          var data = imgData.data;
    
          for (var i = 0, len = imageHeight * imageWidth; i < len; i++) {
            var v = imageBuf[i];
            data[i * 4 + 0] = v;
            data[i * 4 + 1] = v;
            data[i * 4 + 2] = v;
            data[i * 4 + 3] = 255;
          }
    
          context.putImageData(imgData, 0, 0);
        }
    
        if(previewRunning) {
          setTimeout(function() { getImage(ALVideoDevice, subscriberId) }, 100);
        }
      });
    }
    

    Here is the complete Choregraphe project and the complete code.