在互联网上找了很长时间后,我找不到真正解决问题的方法"。
我想做什么:
在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相机创建的图像并快速计算差异百分比(最好不到一秒钟)
答案 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;对于不同的颜色)
下面您将看到我的测试环境与基本图像和第二个测试图像的结果。