c++imagecamerasaveximea

How to store images in c++ with Ximea


I have a superSpeed usb 3.0 Ximea camera and I'm trying to code an application with a Ximea camera that consists on computer vision and machine learning.

I've been able to alocate the frames captured by the camera in it's buffer but I can find the way to save those images or frames as an JPEG or BMP file. I don't know if it's just a command line in my script or I need some kind of libraries to do it.

The images are aquired using these commands:

#define EXPECTED_IMAGES 10
for (int images=0;images < EXPECTED_IMAGES;images++)
{
    // getting image from camera
    stat = xiGetImage(xiH, 5000, &image);
    HandleResult(stat,"xiGetImage");
    printf("Image %d (%dx%d) received from camera\n", images, (int)image.width, (int)image.height);

}

As I can extract the data from the images, I suppose that the frame is still in the buffer, but I can't figure out the way to save it as a JPEG or BMP file in the computer.

I would appreciate any help with the code.

Thank you!


Solution

  • Aha, saving the image. I think you might have gotten the answer by now. But here is mine, and I hope this will be useful for anyone working with machine vision cameras. I have been working with XIMEA for quite a while now. XIMEA API does not include any functions to save images from the buffer to hard drive. So, you need to write your own function or use some library to save out images. And I think, essentially it all comes down to whether it's RAW or compressed image and what kind of image format you want to save out. ie. BMP, JPEG, PNG, PGM, EXR ......

    Let's make couple assumptions first.

    1. Here I assume you want to save out 8bit per pixel RAW image having a resolution of 1024*1024. The size of the image will be 8bit * 1024 * 1024 = 8388608bit = 1048576btye ~= 1MB

    2. By looking at your code, you are using XIMEA API in C++.

    Okay...... Here are two ways I used most often to save out images from XIMEA.

    1. Writing all the image pixels to a binary file with a proper header according to the format you want to save out. Here is an example saving a data to a PGM format image.

      FILE *file;
      char fileName = "example.pgm";
      char *image;
      int width = 1024;
      int height = 1024;
      int byte_per_pixel = 1;
      int max_pixel_value = 255;
      file = fopen (fileName , "w+bx");
      if(file == NULL){
          fprintf(stderr, "Cannot open %s\n", fileName);
          return -1;
      }
      size_t n = 0;
      n += fprintf(file, "P5\n# Comment goes here!\n%d %d\n%d\n", width, height, max_pixel_value);
      n += fwrite(image, 1, width * height * byte_per_pixel, file);
      fclose (fileToSave);

      Saving image to PGM may seem easy but when you need to save an image having pixel depth higher than 8bit, you need to deal with endianness issue, since PGM big-endian format. Here is a link to Netpbm formats if you want to read more about it. https://en.wikipedia.org/wiki/Netpbm_format

      And also, other formats may have way more complicated data structure then you cannot just simply put down a header. So, using an image library or OpenCV will be a lot less cumbersome.

    2. The handy OpenCV imwrite. Since you are gonna deal with pixels, OpenCV is a good library to have. OpenCV is a powerful library helps you with manipulating matrixes easier than ever. And it comes with a lot of useful stuff like GPU accelerated OpenCV functions. Back to the topic, imwrite can save images to many formats. Here is an example I wrote to save RAW data to PNG format.

      string fileName = "example.png";
      char *image;
      int width = 1024;
      int height = 1024;
      int byte_per_pixel = 1;
      int max_pixel_value = 255;
      cv::Mat img_raw = cv::Mat(height, width, CV_8UC1, image);
      vector compression_params;
      compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
      compression_params.push_back(0);
      cv::imwrite(PNGFileName, img_raw, compression_params);

      imwirte will determine what kind of format you want to save out based on the filename extension. And just a couple lines of code. OpenCV saves out the image for you effortlessly. Here is a link to OpenCV documentation of imwirte, http://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite

    I hope my answer can help you and others are wondering how to save out images.