Перезаписать GPS-координаты в Image Exif с помощью Python 3.6 - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь преобразовать геотеги изображений так, чтобы изображения и наземные контрольные точки находились в одной и той же системе координат внутри моего программного обеспечения (Pix4D mapper).

Ответ здесь говорит:

Данные Exif стандартизированы, а данные GPS должны быть закодированы с использованием географические координаты (минуты, секунды и т. д.), описанные выше вместо дроби. Если он не закодирован в этом формате в exif тег, он не будет прилипать.

Вот мой код:

import os, piexif, pyproj
from PIL import Image

img = Image.open(os.path.join(dirPath,fn))
exif_dict = piexif.load(img.info['exif'])

breite = exif_dict['GPS'][piexif.GPSIFD.GPSLatitude]
lange = exif_dict['GPS'][piexif.GPSIFD.GPSLongitude]

breite = breite[0][0] / breite[0][1] + breite[1][0] / (breite[1][1] * 60) + breite[2][0] / (breite[2][1] * 3600)
lange = lange[0][0] / lange[0][1] + lange[1][0] / (lange[1][1] * 60) + lange[2][0] / (lange[2][1] * 3600)
print(breite) #48.81368778730952
print(lange) #9.954511162420633
x, y = pyproj.transform(wgs84, gk3, lange, breite) #from WGS84 to GaussKrüger zone 3 
print(x) #3570178.732528623
print(y) #5408908.20172699
exif_dict['GPS'][piexif.GPSIFD.GPSLatitude] = [ ( (int)(round(y,6) * 1000000), 1000000 ), (0, 1), (0, 1) ]

exif_bytes = piexif.dump(exif_dict) #error here
img.save(os.path.join(outPath,fn), "jpeg", exif=exif_bytes)

Я получаю struct.error: аргумент вне диапазона в методе dump. Оригинальный тег GPSInfo выглядит так: {0: b'\x02\x03\x00\x00', 1: 'N', 2: ((48, 1), (48, 1), (3449322402, 70000000)), 3: 'E', 4: ((9, 1), (57, 1), (1136812930, 70000000)), 5: b'\x00', 6: (3659, 10)}

Я предполагаю, что должен записать значения и правильно их кодировать перед записью, но понятия не имею, что делать.

1 Ответ

0 голосов
/ 14 февраля 2019

Похоже, вы уже используете PIL и Python 3.x, но не уверены, что хотите продолжать использовать piexif, но в любом случае вам может быть проще сначала преобразовать градусы, минуты и секунды в десятичную. Похоже, вы уже пытаетесь это сделать, но если поместить это в отдельную функцию, это может быть более понятным и учитывает направление.

Вот пример:

def get_decimal_from_dms(dms, ref):

    degrees = dms[0][0] / dms[0][1]
    minutes = dms[1][0] / dms[1][1] / 60.0
    seconds = dms[2][0] / dms[2][1] / 3600.0

    if ref in ['S', 'W']:
        degrees = -degrees
        minutes = -minutes
        seconds = -seconds

    return round(degrees + minutes + seconds, 5)

def get_coordinates(geotags):
    lat = get_decimal_from_dms(geotags['GPSLatitude'], geotags['GPSLatitudeRef'])

    lon = get_decimal_from_dms(geotags['GPSLongitude'], geotags['GPSLongitudeRef'])

    return (lat,lon)

geotags в этом примере - это словарь с GPSTAGS в качестве ключей вместо цифровых кодов для удобства чтения. Вы можете найти более подробную информацию и полный пример из этого поста в блоге: Начало работы с геокодированием Exif Image Metadata в Python 3

...