1

I'm new to Python so forgive my ignorance If I don't have all the info correct. I am trying to add a GeoTag to a photo in TIFF format using the tifffile and numpy library however I am getting the following error


  File "C:\Users\alanw\anaconda3\lib\site-packages\tifffile\tifffile.py", line 2998, in __init__
    raise ValueError(f'invalid mode {mode!r}')

ValueError: invalid mode 'r+'

As far as I know, the piexif library is also used to add a geotag, however, I also received an error when using this library. Below is the code I used:

import tifffile
import numpy as np

# Define the GPS position
lat = (37.7749, 0, 0)  # latitude in degrees, minutes, seconds
lon = (-122.4194, 0, 0)  # longitude in degrees, minutes, seconds

# Convert the GPS coordinates to rational format
lat_rational = np.array(lat, dtype=np.uint32) * [1e6, 60, 3600]
lon_rational = np.array(lon, dtype=np.uint32) * [1e6, 60, 3600]

# Create the GPS tag data
gps_data = {
    0x0002: 'GPSLatitude',
    0x0004: 'GPSLongitude',
    0x0001: 'GPSLatitudeRef',
    0x0003: 'GPSLongitudeRef',
    0x0005: 'GPSAltitudeRef',
    0x0006: 'GPSAltitude',
    0x0007: 'GPSTimeStamp',
    0x0011: 'GPSDOP',
}
gps_data[0x0002] = lat_rational.tolist()
gps_data[0x0004] = lon_rational.tolist()
gps_data[0x0001] = 'N' if lat[0] >= 0 else 'S'
gps_data[0x0003] = 'E' if lon[0] >= 0 else 'W'

# Load the TIFF image and add the GPS tag data
filename = "image_2_normalized.tiff"
with tifffile.TiffFile(filename, mode='r+') as tif:
    gps_ifd = tifffile.TiffPage(gps_data).as_imagej()
    tif.pages[0].tags['GPSTag'] = tifffile.TiffFrame(gps_ifd)

I'm completely new to the subject of metadata so if anyone is able to help me I would be extremely grateful for your generous assistance.

Adrian
  • 35
  • 4
  • The code for the library indicates that that should be considered a valid option: https://github.com/cgohlke/tifffile/blob/master/tifffile/tifffile.py#L3962 so, make sure you have the latest version of Python and that library. – Random Davis Mar 24 '23 at 18:40
  • Not sure what you actually want to do, but `exiftool` should be able to alter TIFF tags without decompressing/recompressing your data. Python bindings are also available https://stackoverflow.com/a/70708133/2836621 – Mark Setchell Mar 24 '23 at 19:33
  • @MarkSetchell Hi. After your comment I tried add GeoTag based on exiftool. It worked well on .jpg format but I need to do this for thousend images in .tiff format uint16. To be honest my first attempt was based on using this code however I did not get the expected result: https://stackoverflow.com/questions/54196347/overwrite-gps-coordinates-in-image-exif-using-python-3-6 So if anyone knows how to do this I would greatly appreciate your help. – Adrian Mar 25 '23 at 14:12
  • Maybe you could share a representative TIFF file (via Google Drive or similar) along with 3-4 tags and values you want inserted and folks can try their hand at it. – Mark Setchell Mar 25 '23 at 15:53
  • @MarkSetchell Of course, I am already making it available. There are three sample images in .TIFF uint16 format on Google Drive. In the .txt file there are latitude and longitude coordinates (degrees, minutes, seconds) Google Drive: https://drive.google.com/drive/folders/19yD_AlLiwOMLdYhSVfmSXEa_aFNp8ve7?usp=sharing – Adrian Mar 25 '23 at 16:09

2 Answers2

1

sorry for the long lack of response but I struggled with this for a long time and succeeded. Below I want to present my solution written in python. The code adds coordinates to all images. The images I had are hyperspectral images, while the coordinates are added for each channel.

lat = "52.2297 N"
lon = "21.0122 E"
title="Senop-HSC2"

# directory to tiff file
folder_path = "path/to/image"

for filename in os.listdir(folder_path):
    if filename.endswith("normalized.tiff"):
        # construct director path
        image_path = os.path.join(folder_path, filename)
        # print(image_path)
        
        #command to add gps tag
        command = ["exiftool", "-GPSLatitude={}".format(lat), "-GPSLongitude={}".format(lon), "-Title={}".format(title), "-n", "-u", "-m", image_path]

        subprocess.call(command)
        
        original_tiff_path = os.path.join(folder_path, filename + "_original")
        
        os.remove(original_tiff_path)
Adrian
  • 35
  • 4
0

You don't appear to have provided the text file with the tags you wish to set, so I guessed based on your question.

Here I set the lat/lon and their references per your example above:

lat=37.7749
lon=122.4194
latref=N
lonref=W
exiftool -exif:gpslatitude="${lat}"  -exif:gpslatituderef="${latref}" \
         -exif:gpslongitude="${lon}" -exif:gpslongituderef="${lonref}" image.tif 

That results in these tags in the output file:

exiftool image.tif

ExifTool Version Number         : 12.50
File Name                       : image.tif
...
...
Image Width                     : 1024
Image Height                    : 1024
Bits Per Sample                 : 16
Compression                     : Uncompressed
Photometric Interpretation      : BlackIsZero
...
...
Software                        : tifffile.py
GPS Version ID                  : 2.3.0.0
GPS Latitude Ref                : North
GPS Longitude Ref               : West
Image Size                      : 1024x1024
Megapixels                      : 1.0
GPS Latitude                    : 37 deg 46' 29.64" N
GPS Longitude                   : 122 deg 25' 9.84" W
GPS Position                    : 37 deg 46' 29.64" N, 122 deg 25' 9.84" W
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432