Read out RGB data from images with C on Raspberry PI
Question: After looking for a long time on the internet I could not find a real solution
for my "problem".

* * *

**What I want to do:**

Compare 2 images (created with the Raspberry Pi camera in a Python script) in
C. I have tried this in Python but it is too slow (+/- 1 minute per 2 images).

So I would like to try it in C. I call a C function with ctypes from my Python
script. The C function expect to get 2 strings containing the paths of the 2
images. The C function must return a double variable (percentage of
difference) back to the Python script.

* * *

**What I tried:**

I store the images as .JPG, so I searched for a c-library that can handle the
jpg-format. I found a post here on stackoverflow advising CImg. I could not
get that to work on my Raspberry Pi. Said it could not find the imports.

    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include "cimg/CImg.h"
    
    using namespace cimg_library;
    
    double compare_pictures(const char* path1, const char* path2);
    
    // Compares two Pictures and returns the difference value
    double compare_pictures(const char* path1, const char* path2)
    {
        CImg<unsigned char> image1(path1);
        CImg<unsigned char> image2(path2);
        double totalDiff = 0.0;
        unsigned int x, y;
    
        if (image1 == NULL || image2 == NULL)
        {
            fprintf(stderr, "One of the images does not exist\n");
            return -1;
        }
    
        if ((image1.width() != image2.width()) || (image1.height() != image2.height()))
        {
            fprintf(stderr, "width/height of the images must match!\n");
            return -1;
        }
        else 
        {
            for (y = 0; y < image1.height; y++)
            {
                for (x = 0; x < image1.width; x++)
                {
                    totalDiff += fabs((int)image1(x, y, 0, 0) - (int)image2(x, y, 0, 0)) / 255.0;
                    totalDiff += fabs((int)image1(x, y, 0, 1) - (int)image2(x, y, 0, 1)) / 255.0;
                    totalDiff += fabs((int)image1(x, y, 0, 2) - (int)image2(x, y, 0, 2)) / 255.0;
                }
            }
            totalDiff = 100.0 * totalDiff / (double)(image1.width() * image1.height() * 3);
            printf("%lf\n", totalDiff);
            return totalDiff;
        }
    }
    

> CImg.h:73:18: fatal error: cstdio: No such file or directory. compilation
> terminated.

After some tries I gave up and went back to the internet to find another
library. I found libjpeg8-dev which is suitable for the Raspberry Pi and C.
Nonetheless this did not help me much either, because I couldn't really find
good tutorials/documentation how to use it for my purposes.

* * *

I just want to be able to compare images created by the Raspberry Pi camera
and calculate a difference percentage in a fast way (best would be in less
than a second)


Answer: Your code is C++, but your error suggests you are trying to compile it as a C
program because `cstdio` is the C++ version of C's `stdio.h`.

Your compile command:

    
    
    gcc -shared -o mycfile.so -fPIC mycfile.c
    

Is trying to compile `mycfile.c` as C (not C++) which is causing your error.
GCC detects the type of file based upon extension (`.c` for C, `.cpp`, `.cxx`,
`.cc` , and `.C` for C++). Rename `mycfile.c` to `mycfile.cpp`, link the C++
runtime library `stdc++`, and run:

    
    
    gcc -lstdc++ -shared -o mycfile.so -fPIC mycfile.cpp
    

* * *

I am unfamiliar with _CImg_ , but if you're open to suggestions, you can give
[_stb_image.h_](https://github.com/nothings/stb/blob/master/stb_image.h) a
try:

    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #include "stb_image.h"
    
    double compare_pictures(const char* path1, const char* path2);
    
    double compare_pictures(const char* path1, const char* path2)
    {
        double totalDiff = 0.0;
        unsigned int x, y;
    
        int width1, height1, comps1;
        unsigned char * image1 = stbi_load(path1, &width1, &height1, &comps1, 0);
    
        int width2, height2, comps2;
        unsigned char * image2 = stbi_load(path2, &width2, &height2, &comps2, 0);
    
        if (image1 == NULL || image2 == NULL)
        {
            fprintf(stderr, "One of the images does not exist\n");
            return -1;
        }
    
        if ((width1 != width2) || (height1 != height2))
        {
            fprintf(stderr, "width/height of the images must match!\n");
            return -1;
        }
        else 
        {
            for (y = 0; y < height1; y++)
            {
                for (x = 0; x < width1; x++)
                {
                    totalDIff += fabs((int)image1[(x + y*width1) * comps1 + 0] - (int)image2[(x + y*width2) * comps2 + 0]) / 255.0;
                    totalDiff += fabs((int)image1[(x + y*width1) * comps1 + 1] - (int)image2[(x + y*width2) * comps2 + 1]) / 255.0;
                    totalDiff += fabs((int)image1[(x + y*width1) * comps1 + 2] - (int)image2[(x + y*width2) * comps2 + 2]) / 255.0;
                }
            }
            totalDiff = 100.0 * totalDiff / (double)(width1 * height1 * 3);
            printf("%lf\n", totalDiff);
            return totalDiff;
        }
    }
    

