Compare images with different orientation efficiently

Started by rafael, July 30, 2012, 09:34:48 AM

Previous topic - Next topic

rafael

Hi,

I am a newbie to perl and to exif information so I apologize if the question is basic.

I have written an issue where I have a lot of image files being backed up to a central folder regularly. My wife is occasionally taking the images and rotating some, then putting them into folders based on the date they were taken. This means when images are then backed up again they are creating duplicates. I wrote a perl script to check each image and sort them into the folders according to the DateTimeOriginal date and it's all working well. When there are images with the same name I am comparing the images pixel by pixel using Image::Compare.

I have an issue trying to compare the images where she has changed the orientation. I want to be able to compare the rotated image with the newly backed up image without relying on the filename being unique. Is there any way to do this without having to iterate over every possible orientation of the newly backed up image and comparing it pixel by pixel to the original before being satisfied the image is the different?

Any help would be appreciated!
Thanks

Phil Harvey

If the images contain a unique tag (like ImageUniqueID), then you could use this to determine if it is the same image.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

pb

In case you are not already aware of this, note that images that are rotated will not necessarily be the same even if rotated back to their original orientation.  That is because if they are jpeg images, rotation can be done either with or without a decode-encode cycle.  If a decode-rotate-encode operation occurs, the new encoding is likely to change the data.  When you rotate back, the two images will not be pixel-by-pixel identical.  That means you need to set a threshold for Image::Compare, which you will probably have to determine by trial and error.

Also, in that case, it means you are not backing up exactly duplicate images.

If the rotation is by an angle other than a multiple of 90 degrees, comparing images will be nontrivial, unless the angle is known in advance.  (Some applications might conceivably encode into metadata.)

If you are using jpeg images, you should make sure to use a lossless jpeg rotation (for n*90 rotations), which you can do via exiftoolgui, or with other programs like Irfanview and I believe also Picasa.

--peter

Edit:  I should add that in principle, pixel by pixel compare can be quite efficient, because it only has to run long enough to find the first mismatched pixel.  With a theshold, it conceivably could be a lot slower, but probably isn't on a real picture mix.

Also, it would be (conceptually) a simple hack to extend Image::Compare so that an image need not be first rotated before it can be compared, an expensive operation.  Instead, just iterate along x in one image, and y in the other, mutatis mutandi the 4 different possible n*90 orientations.  Unless the images are very unusual (like I dunno pictures of a starry sky on a dark night), this would still be very fast, since mismatches would occur almost immediately in 3 of the 4 orientations.