比较某些部分可变但无关紧要的图像
Comparing images in which some parts are variable, but should not matter
我担心发现图像之间存在差异,如下面的黑色椭圆形样本所示。
我的问题是图像的某些部分是也是变量,但我不想在寻找差异时考虑这部分。为了克服这个问题,我想 "transparent" 现在用红色标记的区域:变量部分 Date/Time 和 Date/Time 编辑字段应该被排除在比较之外,从下图:
一种方法是:
我可以使用“透明”颜色来标记不应比较的图像区域。为此,我需要按以下方式修改图像的基线副本:
- 在图像编辑器(例如,在 MSPaint 中)中打开基线图像。
- Select 您将用作“透明”颜色的颜色。
- 将左上角像素的颜色更改为“透明”颜色。
- 使用“透明”颜色填充要从比较中排除的图像区域。
如何通过编码将上述手动工作自动化?我想在 C 代码中实现上述行为。
Normally, such an 'image' as is used in the example is NOT a single image.
Rather it is a large number of images overlaying each other.
Most likely, the 'image' is made of:
the background
the outside border (which has 4 parts)
the upper left icon
the upper border clickable button( three of them)
the text field: Date/Time:
the input field: (for the date/time)
the text field: 'Table:'
the input multi line field/ with initial text 'Customers'
etc etc etc
I.E. that is not a single image but rather many images
that overlay each other
a single image would be something like a .bmp or .tif or .jpg file
如果您要提供一个矩形来着色,为什么不首先忽略一个矩形区域呢?这是一些伪代码
int compareimages (char *im1, char* im2, int wid, int dep, int x0, int y0, int x1, int y1) {
int x, y;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++)
if (x<x0 || x>x1 || y<y0 || y>y1) // if outside rectangle
if im1[y*wid+x] != im2[y*wid+x] // compare pixels
return 0;
return 1;
}
UPDATE 几个要忽略的区域,它们可能重叠。
仍然不难:只需提供一个矩形数组。当您首先检查它们时,它仍然比麻烦地绘制区域更容易。
#include <stdio.h>
#define WID 200
#define DEP 600
typedef struct {
int left;
int top;
int right;
int bot;
} rect;
char image1[WID*DEP];
char image2[WID*DEP];
int inrect (int x, int y, rect r) {
if (x<r.left || x>r.right || y<r.top || y>r.bot)
return 0;
return 1;
}
int compareimages (char *im1, char* im2, int wid, int dep, rect *rarr, int rects) {
int x, y, n, ignore;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++) {
ignore = 0;
for (n=0; n<rects; n++)
ignore |= inrect (x, y, rarr[n]);
if (!ignore)
if (im1[y*wid+x] != im2[y*wid+x]) // compare pixels
return 0;
}
return 1;
}
int main(void) {
rect rectarr[2] = { {10, 10, 50, 50}, { 40, 40, 90, 90 }};
// ... load images ...
// put pixel in one of the rectangles
image1[20*WID+20] = 1;
if (compareimages (image1, image2, WID, DEP, rectarr, 2))
printf ("Same\n");
else
printf ("Different\n");
// put pixel outside any rectangles
image1[0] = 1;
if (compareimages (image1, image2, WID, DEP, rectarr, 2))
printf ("Same\n");
else
printf ("Different\n");
return 0;
}
程序输出:
Same
Different
EDIT 添加了另一个版本的函数,比较 4 个像素分量。
int compareimages (char *im1, char* im2, int wid, int dep, rect *rarr, int rects) {
int x, y, n, ignore;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++) {
ignore = 0;
for (n=0; n<rects; n++)
ignore |= inrect (x, y, rarr[n]);
if (!ignore) {
if (im1[y*wid*4+x] != im2[y*wid*4+x]) // compare pixels
return 0;
if (im1[y*wid*4+x+1] != im2[y*wid*4+x+1])
return 0;
if (im1[y*wid*4+x+2] != im2[y*wid*4+x+2])
return 0;
if (im1[y*wid*4+x+3] != im2[y*wid*4+x+3])
return 0;
}
}
return 1;
}
我的建议是:
- 首先使用 ImageMagick 将解决方案作为命令行实施。
- 一旦成功,将此命令行移植到 ImageMagick 的 C API。
这里有一些关于使用 ImageMagick 比较图像的答案 compare
。它们可能不适用于您的确切问题,但您提供了足够的理论背景和实际示例来帮助您入门:
- ImageMagick compare executable: unrecognized option
-metric
- ImageMagick: “Diff” an Image
如果我对你的问题的理解正确,你只想比较两张图片的某些部分,任何你想从比较中排除你已经知道的其他部分(无趣的)差异。对吗?
以这两张图为例:
顺便说一句,这两张图片已经生成为PDF,我也可以将下面描述的过程应用于PDF页面(无需先将它们转换为图像文件)。
您不一定需要 透明 面具——您也可以使用黑色(或任何颜色)面具。
创建一个 280x20 像素大小的绿色遮罩:
convert -size 280x20 xc:green greenmask-280x20.png
现在使用 composite
将遮罩放在每个图像的顶部:
convert \
http://i.stack.imgur.com/Q1pyC.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
c.png
convert \
http://i.stack.imgur.com/JVije.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
r.png
-geometry +32+35
参数可能需要一些解释:它告诉 ImageMagick 将绿色掩码的左上角放置在原始图像的右侧 32 像素和左上角底部 35 像素处。
生成的图像在这里:
这里有一个讨论 ImageMagick 已知的不同 compose
方法的答案:
现在您的图像已准备好进行 统计 或 视觉 比较,由 ImageMagick 的 compare
命令提供:
compare c.png r.png -compose src delta.png
delta.png
显示所有不同的红色像素,其余为白色:
或者,使用最简单的 compare
命令,其中参考图像用作顶部带有红色增量像素的浅色背景:
compare c.png r.png delta2.png
我担心发现图像之间存在差异,如下面的黑色椭圆形样本所示。
我的问题是图像的某些部分是也是变量,但我不想在寻找差异时考虑这部分。为了克服这个问题,我想 "transparent" 现在用红色标记的区域:变量部分 Date/Time 和 Date/Time 编辑字段应该被排除在比较之外,从下图:
一种方法是: 我可以使用“透明”颜色来标记不应比较的图像区域。为此,我需要按以下方式修改图像的基线副本:
- 在图像编辑器(例如,在 MSPaint 中)中打开基线图像。
- Select 您将用作“透明”颜色的颜色。
- 将左上角像素的颜色更改为“透明”颜色。
- 使用“透明”颜色填充要从比较中排除的图像区域。
如何通过编码将上述手动工作自动化?我想在 C 代码中实现上述行为。
Normally, such an 'image' as is used in the example is NOT a single image.
Rather it is a large number of images overlaying each other.
Most likely, the 'image' is made of:
the background
the outside border (which has 4 parts)
the upper left icon
the upper border clickable button( three of them)
the text field: Date/Time:
the input field: (for the date/time)
the text field: 'Table:'
the input multi line field/ with initial text 'Customers'
etc etc etc
I.E. that is not a single image but rather many images
that overlay each other
a single image would be something like a .bmp or .tif or .jpg file
如果您要提供一个矩形来着色,为什么不首先忽略一个矩形区域呢?这是一些伪代码
int compareimages (char *im1, char* im2, int wid, int dep, int x0, int y0, int x1, int y1) {
int x, y;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++)
if (x<x0 || x>x1 || y<y0 || y>y1) // if outside rectangle
if im1[y*wid+x] != im2[y*wid+x] // compare pixels
return 0;
return 1;
}
UPDATE 几个要忽略的区域,它们可能重叠。
仍然不难:只需提供一个矩形数组。当您首先检查它们时,它仍然比麻烦地绘制区域更容易。
#include <stdio.h>
#define WID 200
#define DEP 600
typedef struct {
int left;
int top;
int right;
int bot;
} rect;
char image1[WID*DEP];
char image2[WID*DEP];
int inrect (int x, int y, rect r) {
if (x<r.left || x>r.right || y<r.top || y>r.bot)
return 0;
return 1;
}
int compareimages (char *im1, char* im2, int wid, int dep, rect *rarr, int rects) {
int x, y, n, ignore;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++) {
ignore = 0;
for (n=0; n<rects; n++)
ignore |= inrect (x, y, rarr[n]);
if (!ignore)
if (im1[y*wid+x] != im2[y*wid+x]) // compare pixels
return 0;
}
return 1;
}
int main(void) {
rect rectarr[2] = { {10, 10, 50, 50}, { 40, 40, 90, 90 }};
// ... load images ...
// put pixel in one of the rectangles
image1[20*WID+20] = 1;
if (compareimages (image1, image2, WID, DEP, rectarr, 2))
printf ("Same\n");
else
printf ("Different\n");
// put pixel outside any rectangles
image1[0] = 1;
if (compareimages (image1, image2, WID, DEP, rectarr, 2))
printf ("Same\n");
else
printf ("Different\n");
return 0;
}
程序输出:
Same
Different
EDIT 添加了另一个版本的函数,比较 4 个像素分量。
int compareimages (char *im1, char* im2, int wid, int dep, rect *rarr, int rects) {
int x, y, n, ignore;
for (y=0; y<dep; y++)
for (x=0; x<wid; x++) {
ignore = 0;
for (n=0; n<rects; n++)
ignore |= inrect (x, y, rarr[n]);
if (!ignore) {
if (im1[y*wid*4+x] != im2[y*wid*4+x]) // compare pixels
return 0;
if (im1[y*wid*4+x+1] != im2[y*wid*4+x+1])
return 0;
if (im1[y*wid*4+x+2] != im2[y*wid*4+x+2])
return 0;
if (im1[y*wid*4+x+3] != im2[y*wid*4+x+3])
return 0;
}
}
return 1;
}
我的建议是:
- 首先使用 ImageMagick 将解决方案作为命令行实施。
- 一旦成功,将此命令行移植到 ImageMagick 的 C API。
这里有一些关于使用 ImageMagick 比较图像的答案 compare
。它们可能不适用于您的确切问题,但您提供了足够的理论背景和实际示例来帮助您入门:
- ImageMagick compare executable: unrecognized option
-metric
- ImageMagick: “Diff” an Image
如果我对你的问题的理解正确,你只想比较两张图片的某些部分,任何你想从比较中排除你已经知道的其他部分(无趣的)差异。对吗?
以这两张图为例:
顺便说一句,这两张图片已经生成为PDF,我也可以将下面描述的过程应用于PDF页面(无需先将它们转换为图像文件)。
您不一定需要 透明 面具——您也可以使用黑色(或任何颜色)面具。
创建一个 280x20 像素大小的绿色遮罩:
convert -size 280x20 xc:green greenmask-280x20.png
现在使用 composite
将遮罩放在每个图像的顶部:
convert \
http://i.stack.imgur.com/Q1pyC.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
c.png
convert \
http://i.stack.imgur.com/JVije.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
r.png
-geometry +32+35
参数可能需要一些解释:它告诉 ImageMagick 将绿色掩码的左上角放置在原始图像的右侧 32 像素和左上角底部 35 像素处。
生成的图像在这里:
这里有一个讨论 ImageMagick 已知的不同 compose
方法的答案:
现在您的图像已准备好进行 统计 或 视觉 比较,由 ImageMagick 的 compare
命令提供:
compare c.png r.png -compose src delta.png
delta.png
显示所有不同的红色像素,其余为白色:
或者,使用最简单的 compare
命令,其中参考图像用作顶部带有红色增量像素的浅色背景:
compare c.png r.png delta2.png