1

For a project, I'm using the MLX90461 IR camera. And I'm using some C++ code to read the data of the camera.

The data of this camera is stored in an array of 192 elements (16x12 RES). In this array, I store the measured temperature for that pixel.

Next, I convert that temperature to RGB values and store those as well. Because I need 3 values per pixel the array has 576 elements. (192 * 3).

So now I have an array filled with data. And I want to make an image of all this data.

I followed this example and it works great.

Now comes the but... But:

  1. It outputs a .ppm file
  2. The output is just 16x12 pixels

And I want to use the output as a sort of live stream, so the .ppm file type is not really great.

So My questions are.

  1. Is this way of doing things in the right direction?
  2. Is there a way to output a more "common" file type like a .png
  3. Is C++ the best way to do this type of data processing I was thinking to use Python to make an image based on the array.

The end result I'm liking to have is something like this: visualization on display (see GIF below code)

void print_pixels(){
    static uint8_t pixels[576];
    uint16_t l = 0;
    for(int i = 0 ; i < 12 ; i++){ //rows
        for(int j = 0 ; j < 16 ; j++){ // cols
            struct CRGB color = tempToColor(temperatures[j+16*i]);
            pixels[l] = color.r;
            l++;
            pixels[l] = color.g;
            l++;
            pixels[l] = color.b;
            l++;
            printf("T%4.2f,R%i,G%i,B%i : ", temperatures[j+16*i], pixels[l - 3], pixels[l - 2], pixels[l - 1]);
        }
        std::cout << "\n\n";
    }

    FILE *imageFile;
    int height=12,width=16;

    imageFile=fopen("/home/pi/output_IR_camera.ppm","wb");
    if(imageFile==NULL){
        perror("ERROR: Cannot open output file");
        exit(1);
    }
    fprintf(imageFile,"P6\n");               // P6 filetype
    fprintf(imageFile,"%d %d\n",width,height);   // dimensions
    fprintf(imageFile,"255\n");              // Max pixel

    fwrite(pixels,1,576,imageFile);
    fclose(imageFile);

}

struct CRGB tempToColor(float temp) {
    struct CRGB color;
    if (temp > MAX_TEMP) {
        color.r = 255;
        color.g = 0;
        color.b = 255;
    } else if (temp >= MIN_TEMP + PEAK_STEPS * 4) {
        color.r = round(255 * (temp - (MIN_TEMP + PEAK_STEPS * 4.0)) / PEAK_STEPS);
        color.g = 0;
        color.b = 255;
    } else if (temp >= MIN_TEMP + PEAK_STEPS * 3) {
        color.r = 0;
        color.g = round(255 * (6 - (temp - (MIN_TEMP + PEAK_STEPS * 3.0)) / PEAK_STEPS));
        color.b = 255;
    } else if (temp >= MIN_TEMP + PEAK_STEPS * 2) {
        color.r = 0;
        color.g = 255;
        color.b = round(255 * (temp - (MIN_TEMP + PEAK_STEPS * 2.0)) / PEAK_STEPS);
    } else if (temp >= MIN_TEMP + PEAK_STEPS * 1) {
        color.r = round(255 * (6 - (temp - (MIN_TEMP + PEAK_STEPS * 1.0)) / PEAK_STEPS));
        color.g = 255;
        color.b = 0;
    } else if (temp >= MIN_TEMP) {
        color.r = 255;
        color.g = round(255 * ((temp - MIN_TEMP) / PEAK_STEPS));
        color.b = 0;
    } else {
        color.r = 255;
        color.g = 0;
        color.b = 0;
    }
    return color;
}
Stefan de Kraker
  • 333
  • 4
  • 14
  • 1
    OpenCV has some nifty functions like `cv::imwrite` that can be used. Often times, you will find people manipulating visual data (e.g., camera-source or otherwise) using a `cv::Mat` and OpenCV library functions to manipulate said `Mat`. Hope this helps – dddJewelsbbb Jan 02 '21 at 19:48
  • @dddJewelsbbb I wanted to stay away from OpenCV, because, well it's not really a lightweight library. – Stefan de Kraker Jan 02 '21 at 19:59
  • @dddJewelsbbb something like this: https://thecodinginterface.com/blog/opencv-Mat-from-array-and-vector/ What is the output file than? – Stefan de Kraker Jan 02 '21 at 20:13
  • Sort of, that just displays to a screen. The [OpenCV docs](https://docs.opencv.org/master/db/deb/tutorial_display_image.html) have an example of writing to a file. OpenCV is very frequently used when manipulating, moving or otherwise processing image data. I am sure there are other options out there for you. If you feel like writing out a PNG, and don't want the overhead of OpenCV, you can probably look into [libpng](http://www.libpng.org/pub/png/libpng.html). – dddJewelsbbb Jan 02 '21 at 20:30
  • What output do you actually want? A web-page? An X11 window? What OS are you using? Do you want the output on a different PC? Multiple PCs? How about throwing the image into **Redis** then you can pick it up from any machine and display it using any language - completely independently. – Mark Setchell Jan 02 '21 at 21:00
  • well, the output is not really important to me. I have a simple webserver running on the pi and I wanted to show the IR image on there. But I think a .ppm file is not really the best chose for a website. Something like a .png would work better. Also, the output is maxed 2 pc / phones in this case. – Stefan de Kraker Jan 02 '21 at 21:13
  • You can easily resize a PPM file and convert to PNG with **ImageMagick** like this `convert input.ppm -resize 160x120 output.png` or with **NetPBM** which is smaller and lighter weight, or with **PIL/Pillow** if you like **Python**. – Mark Setchell Jan 02 '21 at 21:18

0 Answers0