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

用Raspberry PI上的C从图像中读取RGB数据,c,linux,raspberry-pi,rgb,C,Linux,Raspberry Pi,Rgb,在网上找了很长时间后,我找不到真正解决我“问题”的办法 我想做什么: 比较C中的两个图像(用Python脚本中的Raspberry Pi摄像头创建)。 我曾在Python中尝试过这一点,但速度太慢(每2张图像+/-1分钟) 所以我想在C中尝试一下。我用Python脚本中的ctypes调用一个C函数。C函数期望得到包含两个图像路径的两个字符串。C函数必须向Python脚本返回一个双变量(差异百分比) 我的尝试: 我将图像存储为.JPG,因此我搜索了一个可以处理JPG格式的c库。我在这里找到了一

在网上找了很长时间后,我找不到真正解决我“问题”的办法


我想做什么:

比较C中的两个图像(用Python脚本中的Raspberry Pi摄像头创建)。 我曾在Python中尝试过这一点,但速度太慢(每2张图像+/-1分钟)

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


我的尝试:

我将图像存储为.JPG,因此我搜索了一个可以处理JPG格式的c库。我在这里找到了一个关于CImg的帖子。我没法把它用在我的树莓皮上。说找不到进口的

#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/cimg.h”
使用名称空间cimg_库;
双重比较图片(常量字符*路径1,常量字符*路径2);
//比较两张图片并返回差值
双重比较图片(常量字符*路径1,常量字符*路径2)
{
cimgimage1(path1);
cimgimage2(path2);
双总差=0.0;
无符号整数x,y;
if(image1==NULL | | image2==NULL)
{
fprintf(stderr,“其中一个映像不存在\n”);
返回-1;
}
如果((image1.width()!=image2.width())| |(image1.height()!=image2.height())
{
fprintf(stderr,“图像的宽度/高度必须匹配!\n”);
返回-1;
}
其他的
{
对于(y=0;y
CImg.h:73:18:致命错误:cstdio:没有这样的文件或目录。 编译终止

经过一番尝试,我放弃了,回到互联网上寻找另一个图书馆。我找到了适用于Raspberry Pi和C的libjpeg8 dev。尽管如此,这对我也没有多大帮助,因为我真的找不到好的教程/文档来说明如何将其用于我的目的



<>我只想比较树莓PI相机所创建的图像,并用快速的方式计算出一个差值(最好是在不到一秒钟内)

你的代码是C++,但是你的错误表明你正在试图把它编译成C程序,因为<代码> CSTDIO < /C>是C++的代码版本:STDIO。 编译命令:

gcc -shared -o mycfile.so -fPIC mycfile.c
正在尝试将
mycfile.c
编译为c(而不是c++),这导致了您的错误。GCC根据扩展名检测文件类型(
.c
用于c,
.cpp
.cxx
.cc
,以及
.c
用于c++)。重命名<代码> MyFrase.c<代码> >代码> MyCf.cpp,链接C++运行时库<代码> STDC++<代码>,运行:

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

我不熟悉CImg,但如果你愿意接受建议,你可以 试一试:

#包括
#包括
#包括
#包括“stb_image.h”
双重比较图片(常量字符*路径1,常量字符*路径2);
双重比较图片(常量字符*路径1,常量字符*路径2)
{
双总差=0.0;
无符号整数x,y;
内部宽度1,高度1,组件1;
无符号字符*image1=stbi_加载(路径1,&width1,&height1,&comps1,0);
内部宽度2,高度2,组件2;
无符号字符*image2=stbi_加载(路径2、&width2、&height2、&comps2,0);
if(image1==NULL | | image2==NULL)
{
fprintf(stderr,“其中一个映像不存在\n”);
返回-1;
}
如果((宽度1!=宽度2)| |(高度1!=高度2))
{
fprintf(stderr,“图像的宽度/高度必须匹配!\n”);
返回-1;
}
其他的
{
对于(y=0;y
根据我学到的技巧,我创建了这个解决方案

#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;
    }
}
#包括
#包括
#包括
#ifndef机顶盒映像的实现
#定义机顶盒映像的实现
#包括“stb_image.h”
#ifndef STBI_断言
#定义STBI_断言(x)
#恩迪夫
#恩迪夫
#定义颜色\u R 0
#定义颜色\u G 1
#定义颜色2
#定义偏移量10
双重比较图片(常量字符*路径1,常量字符*路径2);
双重比较图片(常量字符*路径1,常量字符*路径2)
{
双totalDiff=0.0,数值;
无符号整数x,y;
内部宽度1,高度1,组件1;
无符号字符*image1=stbi_加载(路径1,&width1,&height1,&comps1,0);
内部宽度2,高度2,组件2;
无符号字符*image2=stbi_加载(路径2、&width2、&height2、&comps2,0);
if(image1==NULL | | image2==NULL)
{
返回-1;
}
如果((宽度1!=宽度2)| |(高度1!=高度2))
{
返回-2;
}
其他的
{
对于(y=0;y#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;
    }
}