在Raspberry PI上使用C读取图像中的RGB数据

时间:2014-11-13 14:49:21

标签: c linux raspberry-pi rgb

在互联网上找了很长时间后,我找不到真正解决问题的方法"。


我想做什么:

在C中比较2张图像(使用Python脚本中的Raspberry Pi相机创建)。 我在Python中试过这个但速度太慢(每2张图片+/- 1分钟)。

所以我想在C中尝试。我用Python脚本中的ctypes调用C函数。 C函数期望获得包含2个图像的路径的2个字符串。 C函数必须将双变量(差异的百分比)返回给Python脚本。


我尝试了什么:

我将图像存储为.JPG,因此我搜索了一个可以处理jpg格式的c库。我在stackoverflow上发现了一篇帖子,建议CImg。我无法在Raspberry Pi上工作。说它找不到进口货。

#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:致命错误:cstdio:没有这样的文件或目录。   编译终止。

经过一些尝试,我放弃了,回到互联网上寻找另一个图书馆。我找到了适合Raspberry Pi和C的libjpeg8-dev。尽管如此,这对我也没什么帮助,因为我无法找到好的教程/文档如何将它用于我的目的。


我只是希望能够比较Raspberry Pi相机创建的图像并快速计算差异百分比(最好不到一秒钟)

2 个答案:

答案 0 :(得分:1)

您的代码是C ++,但是您的错误表明您正在尝试将其编译为C程序,因为cstdio是C&#39; stdio.h的C ++版本。

您的编译命令:

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

尝试将mycfile.c编译为导致错误的C(不是C ++)。 GCC根据扩展名检测文件类型(.c代表C,.cpp.cxx.cc.C代表C ++)。将mycfile.c重命名为mycfile.cpp,链接C ++运行时库stdc++,然后运行:

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

我不熟悉 CImg ,但如果你对建议持开放态度,你可以 试试stb_image.h

#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;
    }
}

答案 1 :(得分:1)

通过我获得的提示,我创建了这个解决方案。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifndef STB_IMAGE_IMPLEMENTATION
    #define STB_IMAGE_IMPLEMENTATION
    #include "stb_image.h"

    #ifndef STBI_ASSERT
        #define STBI_ASSERT(x)
    #endif
#endif

#define COLOR_R 0
#define COLOR_G 1
#define COLOR_B 2
#define OFFSET 10

double compare_pictures(const char* path1, const char* path2);

double compare_pictures(const char* path1, const char* path2)
{
    double totalDiff = 0.0, value;
    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)
    {
        return -1;
    }

    if ((width1 != width2) || (height1 != height2))
    {
        return -2;
    }
    else
    {
        for (y = 0; y < height1; y++)
        {
            for (x = 0; x < width1; x++)
            {
                // Calculate difference in RED 
                value = (int)image1[(x + y*width1) * comps1 + COLOR_R] - (int)image2[(x + y*width2) * comps2 + COLOR_R];
                if (value < OFFSET && value > (OFFSET * -1)) { value = 0; }
                totalDiff += fabs(value) / 255.0;

                // Calculate difference in GREEN 
                value = (int)image1[(x + y*width1) * comps1 + COLOR_G] - (int)image2[(x + y*width2) * comps2 + COLOR_G];
                if (value < OFFSET && value > (OFFSET * -1)) { value = 0; }
                totalDiff += fabs(value) / 255.0;

                // Calculate difference in BLUE
                value = (int)image1[(x + y*width1) * comps1 + COLOR_B] - (int)image2[(x + y*width2) * comps2 + COLOR_B];
                if (value < OFFSET && value > (OFFSET * -1)) { value = 0; }
                totalDiff += fabs(value) / 255.0;
            }
        }
        totalDiff = 100.0 * totalDiff / (double)(width1 * height1 * 3);
        return totalDiff;
    }
}

感谢cpburnz指出使用stb_image.h

stb_image.h易于使用。我在使用stb_image.h时添加了2个应该添加的定义(正如我在.h文件中的注释中注意到的那样)


尚未达到最佳的差异率。我创建了一个测试环境来优化颜色检查。

我创建了一些10x10图像。 - 基本图像,完全是红色的(255,0,0) - 测试图像1,其中包含红色(255,0,0)和绿色(0,255,0) - 测试图像2,其中包含红色(255,0,0)和白色(255,255,255)

大部分时间255被视为255,254或253.而0被视为0,1,2。 我创建了一个OFFSET(10),用于过滤这些微小颜色差异的结果。

我在c中创建了一个小项目,它打印出两个图像的所有红色,绿色和蓝色值以及差异。还有图像之间差异的视觉表现。 (a&#39;。&#39;对于相同的颜色和&#39; +&#39;对于不同的颜色)

下面您将看到我的测试环境与基本图像和第二个测试图像的结果。

Result of my test environment with the base image and the red/white image