比较一些部分是可变的图像,但不应该重要

时间:2015-03-05 15:25:04

标签: c imagemagick

我担心会发现图像之间的差异,如下面的样本和黑色椭圆形状所示。

我的问题是图像的某些部分是也是变量,但我不想在发现不相似性时考虑这部分。为了克服这个问题,我想让“透明”区域现在用红色标记:可变部分日期/时间和日期/时间编辑字段应从比较中排除,如下图所示:

enter image description here

一种方法是: 我可以使用“透明”颜色来标记不应该比较的图像区域。为此,我需要以下列方式修改图像的基线副本:

  • 在图像编辑器中打开基线图像(例如,在MSPaint中)。
  • 选择您将用作“透明”颜色的颜色。
  • 将左上角像素的颜色更改为“透明”颜色。
  • 使用“透明”颜色填充要从比较中排除的图像区域。

如何通过编码自动完成上述手动工作?我想在C代码中实现上述行为。

3 个答案:

答案 0 :(得分:3)

如果要提供一个颜色矩形,为什么不首先忽略一个矩形区域?这是一些伪代码

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

编辑添加了该功能的另一个版本,比较了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;
}

答案 1 :(得分:3)

我的建议是:

  1. 首先使用ImageMagick将解决方案作为命令行实现。
  2. 一旦这样做,将此命令行移植到ImageMagick的C API。
  3. 以下是使用ImageMagick compare比较图像的一些答案。它们可能不适用于您的确切问题,但您提供了足够的理论背景和实际示例来帮助您入门:

    如果我理解你的问题,你确实只想比较两个图像的某些部分,你想要从比较中排除其他部分,你已经知道存在(无趣的)差异。正确?

    以这两张图片为例:

    compare.png

    reference.png

    顺便说一下,这两张图片已经以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像素放在原始图像左上角的底部。

    结果图像在这里:

    c.png

    r.png

    讨论ImageMagick已知的不同compose方法的答案如下:

    现在,您的图像已准备好进行统计可视比较,由ImageMagick的compare命令提供:

    compare c.png r.png -compose src delta.png
    

    delta.png显示所有不同的红色像素,其余为白色:

    delta.png

    或者,使用最简单的compare命令,其中参考图像用作顶部带有红色增量像素的苍白背景:

    compare c.png r.png  delta2.png
    

    delta2.png

答案 2 :(得分:0)

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