Reputation: 307
I am concerned about to find dissimilarities between images as shown in the samples underneath with the black oval shape.
My problem is that some part of image is also variable, but I do not want to consider this part when finding dissimilarities. To overcome this problem I want to make "transparent" that area which is now marked with red color: the variable part Date/Time and the Date/Time edit field should be excluded from comparison as can be seen from image below:
One way is: I can use a “transparent” color to mark image areas that should not be compared. To do this, I need to modify the baseline copy of an image in the following manner:
How to do automate above manual work through coding? I want to implement above behavior in C code.
Upvotes: 1
Views: 1399
Reputation: 34585
If you are providing a rectangle to colour in, why not just ignore a rectangular area in the first place? Here is some pseudo code
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 for several areas to be ignored, which may overlap.
Still not hard: just provide an array of rectangles. It is still going to be easier than going to the trouble of painting out areas when you can check them in the first place.
#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;
}
Program output:
Same
Different
EDIT added another version of the function, comparing 4 pixel components.
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;
}
Upvotes: 3
Reputation: 90213
My suggestion is:
Here are a few answers about comparing images using ImageMagick compare
. They may not apply to your precise question, but thy provide enough theoretical background with practical examples to get you started:
-metric
If I understand your question correctly, you do want to compare only some parts of two images, any you want to exclude other parts from the comparison where you already know there are (uninteresting) differences. Right?
Taking these two images as an example:
BTW, these two images have been born as PDFs, and I could apply the procedure described below to PDF pages too (without a need to convert them to image files first).
You do not necessarily need a transparent mask -- you can use a black (or any color) one too.
Create a green mask of 280x20 pixels size:
convert -size 280x20 xc:green greenmask-280x20.png
Now use composite
to place the mask on top of each of the images:
convert \
https://i.sstatic.net/Q1pyC.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
c.png
convert \
https://i.sstatic.net/JVije.png \
greenmask-280x20.png \
-geometry +32+35 \
-compose over \
-composite \
r.png
The -geometry +32+35
parameter maybe requires some explanation: it tells ImageMagick to place the top left corner of the greenmask 32 pixels to the right and 35 pixels to the bottom of the top left corner of the original image.
The resulting images are here:
An answer that discusses the different compose
methods known to ImageMagick is here:
Now your images are ready for either statistical or visual comparison, provided by ImageMagick's compare
command:
compare c.png r.png -compose src delta.png
The delta.png
shows all pixels in red which are different, the rest is white:
Or, using the most simple compare
command, where the reference image serves as a pale background with red delta pixels on top:
compare c.png r.png delta2.png
Upvotes: 4
Reputation: 16540
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
Upvotes: 0