How to handle EXIF rotation

So, one of the more common issues we have in Hasty concerns EXIF rotation. Essentially, you look at an image locally - and it looks fine. You upload it to Hasty, and suddenly its orientation is off. What happened?
So to explain why you need to know about EXIF.

EXIF is metadata that is captured by a device. Often for JPG images. What's important here is the metadata for orientation. For example, you might take a photo with your phone. The photo itself has one orientation, but the phone might add an instruction to rotate the phone with 270 degrees.

This is problematic if you are in machine learning. Different tools and frameworks handle EXIF rotation differently. Some ignore it (Hasty, among others). To be on the safe side, we recommend that you convert your images to use the EXIF rotation, then rotate the image to the correct orientation natively, and then remove the EXIF rotation metadata.

This leads to the question: How?

There are many ways to do so, but we recommend JHEAD.

With it, you can easily do this operation through your terminal. Just open it, navigate to the right folder and point it to the right folder like so:

json
      jhead -autorot *.jpeg/jpg
OR
jhead -autorot *
    

Doing this will rotate the images according to EXIF specifications, and then remove EXIF rotation data. This way, any program, device, or ML model will see the images the same way as you intended.

Another approach is via Python:

python
      from PIL import Image, ExifTags
import os
​
folder = 'path_to_your_folder'
for image in os.listdir(folder):
    print(image)
    filepath = f"{folder}/{image}"
    try:
        image=Image.open(filepath)
        for orientation in ExifTags.TAGS.keys():
            if ExifTags.TAGS[orientation]=='Orientation':
                break  
        exif = image._getexif()
        if exif[orientation] == 3:
            image=image.rotate(180, expand=True)
        elif exif[orientation] == 6:
            image=image.rotate(270, expand=True)
        elif exif[orientation] == 8:
            image=image.rotate(90, expand=True)
        image.save(filepath)
        image.close()
    except (AttributeError, KeyError, IndexError):
        # cases: image don't have getexif
        pass
    

Boost model performance quickly with AI-powered labeling and 100% QA.

Learn more
Last modified