Page 1 of 1

Merging differences between two images

Posted: 2017-06-12T11:10:52-07:00
by tore000
Hi,

I was wondering what solution is suitable to this problem. I have two images with very similar backgrounds. I want to identify objects in these images that are unique (that is differences between the two images) and then combine them in one single image with a background of either of the original images.
Examples are
http://bio.lundberg.gu.se/tmp/t1.jpg combined with
http://bio.lundberg.gu.se/tmp/t2.jpg should generate something like
http://bio.lundberg.gu.se/tmp/t3.jpg

It could be that the method needs to account for the fact the backgrounds are not completely identical. But to begin with I'm happy with a solution for the case where the backgrounds are identical.

Many thanks!

Re: Merging differences between two images

Posted: 2017-06-12T11:54:54-07:00
by fmw42
If the backgrounds are identical and the images are not jpg (lossy compressed), then it is much easier. You can isolate each color by using -connected-components and either create a mask or save the images with a transparent background. Then composite one onto the other.

Your problem is harder, since you have jpg images that cause the backgrounds and the red and green regions not be consistent.

If you know the two colors you have, you can just use -fuzz XX% -fill black +opaque red -fill white +opaque black to make a mask for the red image. Then composite the red image over the green image using the mask generated from the green image.

You also have a problem that your images are CMYK and composite does not work well with CMYK, only sRGB. So you need to convert or save as sRGB.

Unix syntax:

Code: Select all

convert t2.jpg t1.jpg \
-profile /users/fred/images/profiles/USWebCoatedSWOP.icc -profile /users/fred/images/profiles/sRGB.icc \
\( -clone 1 -fuzz 20% -fill black +opaque red -fill white +opaque black \) \
-compose over -composite result.png
Image

Re: Merging differences between two images

Posted: 2017-06-12T12:29:19-07:00
by tore000
Many thanks for the quick response!
I can well avoid jpg compression and change to RGB, so that is not a problem I think.
In my real application any color could appear in the red and green objects in my example images, those were just examples.
I'm not sure I understand how to implement what you say about "separate those into two masks using -connected-components" , or is that what happens in your code?
How do I get hold of the files USWebCoatedSWOP.icc and sRGB.icc ?
Sorry, many questions ...

Re: Merging differences between two images

Posted: 2017-06-12T13:12:16-07:00
by fmw42
Post examples that are not jpg. Do not convert jpg to some other format, since that will not avoid the change of colors due to the original compression. For example create from scratch the same images in sRGB but save them as PNG. Then I can try to show you how to do it without knowing the colors.

The profiles are available from many online places. You may even have them already on your system. You can search google for them. see http://www.color.org/registry/index.xalter or type your profile in their search box.

Re: Merging differences between two images

Posted: 2017-06-12T15:00:03-07:00
by fmw42
If you have few enough colors in the image, then you can compare the histograms of the two and see which color is not the background colors in each. This should work if the backgrounds are exactly the same or very similar in colors. Then use my technique above to process as per my example.

For example, the following lists the top ten most frequent colors in your image t1:

Code: Select all

convert t1.jpg \
-profile /users/fred/images/profiles/USWebCoatedSWOP.icc \
-profile /users/fred/images/profiles/sRGB.icc \
-format "%c" histogram:info: | sed -n 's/^ *\(.*\): .* \(srgb.*\)$/\1 \2/p' | sed 's/  */ /g' | sort -r -n -k 1,1 | head -n 10
1026 srgb(235,28,36)
66 srgb(237,28,36)
14 srgb(236,29,36)

8 srgb(207,214,235)
7 srgb(236,29,36)
6 srgb(234,29,37)
6 srgb(175,187,222)
6 srgb(173,188,223)
6 srgb(173,182,220)
6 srgb(150,161,208)


You can see that the top 3 are very similar and are your important color. All the rest have very small counts and are thus the background.

So you can get the top color from

Code: Select all

color=`convert t1.jpg \
-profile /users/fred/images/profiles/USWebCoatedSWOP.icc \
-profile /users/fred/images/profiles/sRGB.icc \
-format "%c" histogram:info: | sed -n 's/^ *\(.*\): .* \(srgb.*\)$/\1 \2/p' | sed 's/  */ /g' | sort -r -n -k 1,1 | head -n 1 | cut -d\  -f2`
echo "$color"
srgb(235,28,36)

Now you can go back and process with this color as I did in my first example.

Code: Select all

convert t2.jpg t1.jpg \
-profile /users/fred/images/profiles/USWebCoatedSWOP.icc -profile /users/fred/images/profiles/sRGB.icc \
\( -clone 1 -fuzz 20% -fill black +opaque "$color: -fill white +opaque black \) \
-compose over -composite result.png

Re: Merging differences between two images

Posted: 2017-06-13T00:39:21-07:00
by tore000
Many thanks for these suggestions! I'm afraid that in the application I have in mind the images are photographs and contain a lot of colors - and not necessarily one most abundant color. Could there be any other solution to the problem?

You asked for sample images that are png and rgb. Here are two images where the differing objects also have multiple colors :
http://bio.lundberg.gu.se/tmp/t1.png
http://bio.lundberg.gu.se/tmp/t2.png

All best

Re: Merging differences between two images

Posted: 2017-06-13T16:11:20-07:00
by fmw42
Do you have a full background image with no other objects in it? If so, then it becomes very simple; otherwise, it is very hard and I have no solution right away. You can do a -compose difference -composite -threshold 0 and get a binary image that is white where the two object are and black otherwise. -connected components can separate the two white objects or simply give you the bounding boxes, but then I do not know which image to apply which bounding box to cut out the important features to composite it onto one of the two images.

Conceivably, you can cut out two regions from both images using the bounding boxes and compare the colors of the cropped images to the background and throw out the subsections that more closely match the background.

Re: Merging differences between two images

Posted: 2017-06-13T16:40:37-07:00
by snibgo
When you have just two images, such as t1.png and t2.png, it is easy to find what pixels need changing to change one image into the other:

Code: Select all

convert t1.png t2.png -compose Difference -composite c.png
c.png is black where the pixels are the same; otherwise some other colour.

In c.png, the non-black area top-left correspond to pixels that are "foreground" in t1.png and "background" in t2.png. I have used human intelligence to determine this. How can a computer determine this?

With a bit of effort, we can find statistics for the area that is certainly background (the pixels that are the same in both images). These statistics could be: mean and SD in R,G and B channels.

Then we get the same statistics for the top-left area that has changed in t1 and t2. One of these has statistics very similar to the background, and the other has (with luck) statistics that are very different. From that, we know whether t1 or t2 has background in that position.

Likewise for the area bottom-right.

As Fred says, the task is far simpler if we have an image we know it is entirely background. Then any pixels that are different must be foreground.

Or we might have three (or more) different images. Then majority rules: if a given pixel is identical in two or more images, that's the background colour in that position. (This rule needs adjusting if the foreground object can move slightly.)

Re: Merging differences between two images

Posted: 2017-06-14T00:19:20-07:00
by tore000
Many thanks snibgo and fmw42! I could actually use a background image if that makes the problem much simpler. Sorry for not realizing this. I've put the background up here, together with the previous images:

http://bio.lundberg.gu.se/tmp/background.png
http://bio.lundberg.gu.se/tmp/t1.png
http://bio.lundberg.gu.se/tmp/t2.png

I would be extremely grateful if you could inform me what code to use for this case. As you probably have realized already, I'm not that experienced with IM.

(BTW, I use ImageMagick version 6.7.5-7)

Re: Merging differences between two images

Posted: 2017-06-14T09:17:32-07:00
by fmw42
This works for me on IM 6.9.8.10 Q16. Your version of IM is rather old, at about 230 versions old. I would suggest you upgrade if this does not work. Here I get the absolute difference between t2 and the background and threshold it so that any non-black (perfect match) becomes white. Then I use the b/w mask to composite t2 onto t1. See http://www.imagemagick.org/Usage/compose/

Unix syntax:

Code: Select all

convert t1.png t2.png \
\( -clone 1 background.png -compose difference -composite -threshold 0 \) \
-compose over -composite t12background_result.png
Windows syntax:

Code: Select all

convert t1.png t2.png ^
( -clone 1 background.png -compose difference -composite -threshold 0 ) ^
-compose over -composite t12background_result.png
Image

Re: Merging differences between two images

Posted: 2017-06-14T11:22:27-07:00
by tore000
Fantastic! This also works for photographs that I tested with slightly different backgrounds, provided that I use a different threshold value, like 10%.
Many thanks fmw42!

Re: Merging differences between two images

Posted: 2017-06-14T11:25:02-07:00
by fmw42
tore000 wrote: 2017-06-14T11:22:27-07:00 Fantastic! This also works for photographs that I tested with slightly different backgrounds, provided that I use a different threshold value, like 10%.
Many thanks fmw42!
Yes, adjust the threshold to accommodate non-identical backgrounds. The main issue will be if your patterns contain colors that match the background at the same locations. You may get spots of wrong color.