I would like to create a program that compares two images. It must take in 2 folders, each full of pictures and each picture in one folder has a pair in the other folder (with the same filename) ex: folder1 has 3 pictures: [a.png, b.png, c.png], and folder2 has 3 pictures: [a.png, b.png, c.png]. I would like to take folder1/a and compare it to folder2/a. I do not know where to start.
-
7Do you want to compare filenames or the content of the image? – anthonyvd Jan 23 '12 at 20:49
-
1if you want to find just identical images you can compare the CRC32 of the file. If you want a fully fledged image comparer I guess you'll need something more (decoding the image to raw pixels and compare pixel by pixel) – BigMike Jan 23 '12 at 20:49
-
Compare files or images? – L.B Jan 23 '12 at 20:49
-
4If there are no constraints on what tools you use, i.e., it isn't homework, you could just run `diff` on the two directories. – Jan 23 '12 at 20:54
-
Take a look at how the image comparison tool in TortoiseSvn works (from a user standpoint). That'll give you an idea of the theory of operation that a good image diff program could have. From there, you have to implement it :) – antiduh Jan 23 '12 at 21:06
-
@BigMike: Using CRC32 risks false positives and unnecessarily reads both entire files. `cmp` or equivalent can stop reading as soon as it sees a difference. – Keith Thompson Jan 24 '12 at 11:27
-
@KeithThompson: sure, but I've done scan collecting for years and the cases of false positives (both size & crc32 equals) were near zero. (Scan collecting is a picture based collection using official CSV stating image size & CRC32). Regarding optimization, is still faster than comparing pixel by pixel, is not the best solution I know, but is a good trade off in between. – BigMike Jan 24 '12 at 11:42
3 Answers
You mentioned images
instead of file
so I assume you don't want to compare raw data but the image pixels and you may also want to have threshold for difference between images
Easiet way to do that is compare two images using PIL. PIL has a histogram
function, you can use that to get histogram for both images and then getting a RMS(root mean square) e.g.
import ImageChops
import math, operator
def rmsdiff(im1, im2):
"Calculate the root-mean-square difference between two images"
h = ImageChops.difference(im1, im2).histogram()
# calculate rms
return math.sqrt(reduce(operator.add,
map(lambda h, i: h*(i**2), h, range(256))
) / (float(im1.size[0]) * im1.size[1]))
copied from http://effbot.org/zone/pil-comparing-images.htm
once you have a function which returns rmsdiff, you can use that in another function which iterates thru all files e.g.
def diff_folder(folder1, folder2):
for path1 in glob.glob(folder1+"/*.png"):
filename = os.path.basename(path1)
path2 = os.path.join(folder2, filename)
if not os.path.exists(path2):
continue
im1 = Image.open(path1)
im2 = Image.open(path2)
diff = rmsdiff(im1, im2)
if diff > threshold:
print "different"

- 85,954
- 40
- 175
- 219
C #, Python or C? take a look at :
How to compare Image objects with C# .NET?
Compare two images the python/linux way
Good luck

- 1
- 1

- 4,167
- 8
- 39
- 80
Here is a C# solution, which compares the files using a binary file comparison. However, the images might contain meta information that differs, even if the pictures look the same. Therefore, it might be appropriate to first open the image as image and not just as file to make the comparison.
public void CompareImages()
{
var dir1 = new DirectoryInfo(@"C:\path1");
FileInfo[] files1 = dir1.GetFiles("*.png");
var dir2 = new DirectoryInfo(@"C:\path2");
FileInfo[] files2 = dir2.GetFiles("*.png");
Dictionary<string, FileInfo> files2Dict = files2.ToDictionary(f => f.Name);
foreach (FileInfo f1 in files1) {
FileInfo f2;
bool equal = true;
if (files2Dict.TryGetValue(f1.Name, out f2) && f1.Length == f2.Length) {
byte[] image1 = GetFileBytes(f1);
byte[] image2 = GetFileBytes(f2);
for (int i = 0; i < image1.Length; i++) {
if (image1[i] != image2[i]) {
equal = false;
break;
}
}
} else {
equal = false;
}
Console.WriteLine(f1.Name + ": " + (equal ? "Images are equal" : "Images are NOT equal"));
}
}
private static byte[] GetFileBytes(FileInfo f)
{
using (FileStream stream = f.OpenRead()) {
byte[] buffer = new byte[f.Length];
stream.Read(buffer, 0, (int)f.Length);
return buffer;
}
}

- 104,806
- 13
- 138
- 188