Snapshot with libpixyusb?

Added by Jim Remington about 2 years ago

It has been stated in the forum that libpixyusb API allows one to obtain a still image from the camera, but I can't find anything in the libpixyusb API reference documentation that indicates how that might be done. Can someone provide or post a simple example, along the lines of hello_pixy?

Second question: can one set the exposure time? If not, what are the meaning and effects of the two parameters (gain and compensation) in the set_exposure_compensation call in the libpixyusb API?

Thanks in advance! Jim Remington


Replies (33)

RE: Snapshot with libpixyusb? - Added by Hemanand Ramasamy over 1 year ago

I have done the Bayer Interpolation based on the code used in PixyMon and this the result I got. The colors are not identifiable.

img.bmp (250.1 kB)

RE: Snapshot with libpixyusb? - Added by Jim Remington over 1 year ago

It looks like the interpolation was not done correctly. Post the code.

RE: Snapshot with libpixyusb? - Added by Hemanand Ramasamy over 1 year ago

#include <stdio.h>

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <iostream>
#include "pixy.h" 

void interpolateBayer(unsigned int width, unsigned int x, unsigned int y, unsigned char *pixel, unsigned int &r, unsigned int &g, unsigned int &b);

void handle_SIGINT(int unused)
{
    printf("\nBye!\n");
  exit(0);
}

int main(int argc, char * argv[])
{
  int      index;
  int      blocks_copied;
  int      pixy_init_status;

  signal(SIGINT, handle_SIGINT);

  pixy_init_status = pixy_init();
  printf("initialized Pixy - %d\n", pixy_init_status);

  if(!pixy_init_status == 0)
  {
    printf("pixy_init(): ");
    pixy_error(pixy_init_status);
    return pixy_init_status;
  }

  {
    unsigned char *pixels;
    uint32_t frame[200][320];
    uint32_t r[200][320];
    uint32_t g[200][320];
    uint32_t b[200][320];
    char rgb[200][320];
    int32_t response, fourcc;
    int8_t renderflags;
    int return_value, res;
    uint16_t width, height;
    uint32_t  numPixels;
    unsigned char current_frame[72000];

     uint8_t gain;
    uint16_t compensation;

    uint8_t* pgain;
    uint16_t* pcomp;

    return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);   
    printf(" STOP returned %d response %d\n", return_value, response);

    return_value = pixy_cam_get_exposure_compensation(&gain, &compensation);
    printf("getECV returned %d values: 0, 0x%02x, 0x%04x\n",return_value,gain, compensation);

    pixy_command("cam_setAEC", UINT8(0x01), END_OUT_ARGS,  &response, END_IN_ARGS);
    printf("response %d",response);
    pixy_command("cam_setAWB", UINT8(0x01), END_OUT_ARGS,  &response, END_IN_ARGS);
    printf("response %d",response);

    response = 0;
    return_value = pixy_command("cam_getFrame",  // String id for remote procedure
                                 0x01, 0x21,      // mode
                                 0x02,   0,        // xoffset
                                 0x02,   0,         // yoffset
                                 0x02, 320,       // width
                                 0x02, 200,       // height
                                 0,              // separator
                                 &response,      // pointer to mem address for return value
                                &fourcc,  //for some reason these 5 args are needed, contrary to the docs
                                &renderflags,
                                &width,
                                &height,
                                &numPixels,
                                 &pixels,        // pointer to mem address for returned frame
                                 0);

    fprintf(stderr,"getFrame return value %d response %d\n", return_value, response);
    printf("returned w %d h %d npix %d \n",width,height,numPixels);

    if(return_value != 0) return return_value;

    return_value = pixy_cam_get_exposure_compensation(&gain, &compensation);
    printf("getECV returned %d values: 0, 0x%02x, 0x%04x\n",return_value,gain, compensation);

   unsigned int i,j,ind,start;

   unsigned long avg=0;
   for(i=0; i<numPixels; i++) avg += pixels[i];
   avg = avg/numPixels;
   printf(" average pixel value %d \n",avg);

   for (i=0; i<8; i++) {
        for (j=0; j<8; j++) {
        ind=i*width+j;
        printf(" %02x",pixels[ind]);
        }
    printf("\n"); 
    }

    memcpy(&current_frame, pixels,numPixels);

   FILE *fp;
  for (i=0; i<200; i++) {
      for(j=0; j<320; j++){
        ind = i * 320 + j;
        frame[i][j] = pixels[ind];
      }
    }

    for(i=0; i<200; i++){
      r[i][0] = r[i][319] = b[i][0] = b[i][319] = b[i][0] = b[i][319] = 0 ;
    }

    for(j=0; j<320; j++){
      r[0][j] = r[119][j] = b[0][j] = b[119][j] = b[0][j] = b[119][j] = 0 ;
    }

    uint32_t rx, gx, bx;
    for (i=1; i<199; i++) {
      pixels++;
      for(j=1; j<319; j++, pixels++){
          interpolateBayer(320, j, i, pixels, rx, gx, bx);
          r[i][j] = rx;
          g[i][j] = gx;
          b[i][j] = bx;
      }
      pixels++;
    }

    FILE *r_file;
    FILE *g_file;
    FILE *b_file;
    FILE *x_file;

    r_file =fopen("r.txt", "w");
    g_file =fopen("g.txt", "w");
    b_file =fopen("b.txt", "w");
    x_file =fopen("z.txt", "w");

    for (i=0; i<200; i++) {
      fprintf(r_file,"{");
      fprintf(g_file,"{");
      fprintf(b_file,"{");

      for(j=0; j<320; j++){
        if(j == 319){
          fprintf(r_file, "%d", r[i][j]);
          fprintf(g_file, "%d", g[i][j]);
          fprintf(b_file, "%d", b[i][j]);
        }else{
          fprintf(r_file, "%d ,", r[i][j]);
          fprintf(g_file, "%d ,", g[i][j]);
          fprintf(b_file, "%d ,", b[i][j]);
        }
        ind = i * 320 + j;
        fprintf(x_file, "%d,", frame[i][j] );

      }

      fprintf(r_file,"},");
      fprintf(g_file,"},");
      fprintf(b_file,"},");
    }  

    fclose(r_file);
    fclose(g_file);
    fclose(b_file);
    fclose(x_file);

    fp=fopen("/home/pi/dump.img","w");
        if(fp != NULL) {
        fwrite(bgrOutputDat, 1, numPixels, fp);
        fclose(fp);
        printf("wrote dump.img\n Done!\n");
        }
        else perror("file allocation failure");

  }

   exit(0);

}

void interpolateBayer(unsigned int width, unsigned int x, unsigned int y, unsigned char *pixel, unsigned int &r, unsigned int &g, unsigned int &b)
{
  if (y & 1)
  {
    if (x & 1)
    {
      r = *pixel;
      g = (*(pixel - 1) + *(pixel + 1) + *(pixel + width) + *(pixel - width)) >> 2;
      b = (*(pixel - width - 1) + *(pixel - width + 1) + *(pixel + width - 1) + *(pixel + width + 1)) >> 2;
    }
    else
    {
      r = (*(pixel - 1) + *(pixel + 1)) >> 1;
      g = *pixel;
      b = (*(pixel - width) + *(pixel + width)) >> 1;
    }
  }
  else
  {
    if (x & 1)
    {
      r = (*(pixel - width) + *(pixel + width)) >> 1;
      g = *pixel;
      b = (*(pixel - 1) + *(pixel + 1)) >> 1;
    }
    else
    {
      r = (*(pixel - width - 1) + *(pixel - width + 1) + *(pixel + width - 1) + *(pixel + width + 1)) >> 2;
      g = (*(pixel - 1) + *(pixel + 1) + *(pixel + width) + *(pixel - width)) >> 2;
      b = *pixel;
    }
  }
}

I took those RGB arrays and used

            Bitmap bmp = new Bitmap(width, height);

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {

                    System.Drawing.Color color = System.Drawing.Color.FromArgb(rx[y, x],gx[y, x],bx[y, x]);

                    bmp.SetPixel(x, y, color);

                }
            }

RE: Snapshot with libpixyusb? - Added by Jim Remington over 1 year ago

I believe you are on the right track. I got as far as you did with the interpolation, but did not try to write an RGB file. It appeared there was an indexing error, (as it does in the .bmp file you posted). If you are off by 1 in either direction, the result is hopeless.

I suggest to take a snapshot of a white card through a red, green or blue filter and check the indexing by printing out some raw pixel values, before and after interpolation.

On posting code, the "pre" (preformatted) button to encapsulate the code seems to work best. The "Inline Code" button does not work. Note that the posted code in the previous post has some characters reinterpreted as html. Can you edit it to change that?

RE: Snapshot with libpixyusb? - Added by Hemanand Ramasamy over 1 year ago

Sorry about the code my first time.. Alright I ll work on the part you told me .

RE: Snapshot with libpixyusb? - Added by Hemanand Ramasamy about 1 year ago

I am sorry for such a delay I resolved the issue and everything works perfectly I have added with this the working code.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <math.h>  
#include "pixy.h" 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <ctime>

using namespace cv;
using namespace std;

void interpolateBayer(unsigned int width, unsigned int x, unsigned int y, unsigned char *pixel, unsigned int &r, unsigned int &g, unsigned int &b);
Mat renderBA81(uint8_t renderFlags, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame);
Mat getImage();

int main(int argc, char * argv[])
{
    int pixy_init_status;
    int return_value;
    int32_t response;

    pixy_init_status = pixy_init();

    if(!pixy_init_status == 0)
    {
        printf("pixy_init(): ");
        pixy_error(pixy_init_status);
        return pixy_init_status;
    }

    return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS); 
    return_value = pixy_rcs_set_position(1, 900);
    return_value = pixy_rcs_set_position(0, 500);

    Mat image = getImage();
}

Mat getImage()
{
    unsigned char *pixels;
    int32_t response, fourcc;
    int8_t renderflags;
    int return_value, res;
    uint16_t rwidth, rheight;
    uint32_t  numPixels;
    uint16_t height,width;
    uint16_t mode;

    return_value = pixy_command("run", END_OUT_ARGS, &response, END_IN_ARGS);   
    return_value = pixy_command("stop", END_OUT_ARGS, &response, END_IN_ARGS);

    return_value = pixy_command("cam_getFrame",  // String id for remote procedure
                                 0x01, 0x21,      // mode
                                 0x02,   0,        // xoffset
                                 0x02,   0,         // yoffset
                                 0x02, 320,       // width
                                 0x02, 200,       // height
                                 0,            // separator
                                 &response, &fourcc, &renderflags, &rwidth, &rheight, &numPixels, &pixels, 0);

    return renderBA81(renderflags,rwidth,rheight,numPixels,pixels);
}

inline void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pixel, uint8_t* r, uint8_t* g, uint8_t* b)
{
    if (y&1)
    {
        if (x&1)
        {
            *r = *pixel;
            *g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2;
            *b = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2;
        }
        else
        {
            *r = (*(pixel-1)+*(pixel+1))>>1;
            *g = *pixel;
            *b = (*(pixel-width)+*(pixel+width))>>1;
        }
    }
    else
    {
        if (x&1)
        {
            *r = (*(pixel-width)+*(pixel+width))>>1;
            *g = *pixel;
            *b = (*(pixel-1)+*(pixel+1))>>1;
        }
        else
        {
            *r = (*(pixel-width-1)+*(pixel-width+1)+*(pixel+width-1)+*(pixel+width+1))>>2;
            *g = (*(pixel-1)+*(pixel+1)+*(pixel+width)+*(pixel-width))>>2;
            *b = *pixel;
        }
    }

}

Mat renderBA81(uint8_t renderFlags, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame)
{
    uint16_t x, y;
    uint8_t r, g, b;
    Mat imageRGB;

    frame += width;
    uchar data[3*((height-2)*(width-2))];

    uint m = 0;
    for (y=1; y<height-1; y++)
    {
        frame++;
        for (x=1; x<width-1; x++, frame++)
        {
            interpolateBayer(width, x, y, frame, &r, &g, &b);
            data[m++] = b;
            data[m++] = g;
            data[m++] = r;
        }
        frame++;
    }

    imageRGB =  Mat(height - 2,width -2, CV_8UC3, data);

    return imageRGB;
}

RE: Snapshot with libpixyusb? - Added by Elia Schoen 23 days ago

Hi all!
I know that this post is an old discussion, but I'd like to know where I have to write this code to try it.
I read that a program is needed (QT Project, I think) to compile libpixyusb and other. It is the program to use?

RE: Snapshot with libpixyusb? - Added by Edward Getz 23 days ago

Hello Elia,
This page explains how to get started with libpixyusb (it's what's being used in this topic discussion.)

http://cmucam.org/projects/cmucam5/wiki/Building_the_libpixyusb_example_on_Linux

Hope this helps!

Edward

« Previous 1 2 (26-33/33)