【问题标题】:Extract GPS data using python and PIL is failing使用 python 和 PIL 提取 GPS 数据失败
【发布时间】:2022-07-25 05:56:21
【问题描述】:

这段代码来自https://www.blog.pythonlibrary.org,和其他的类似,同样的失败,这是给出的错误代码

    from PIL import Image
    from PIL.ExifTags import TAGS, GPSTAGS   
    filename="screenshot.jpg"
    
    def get_exif(image_file_path):
        exif_table = {}
        image = Image.open(image_file_path)
        info = image.getexif()
        for tag, value in info.items():
            decoded = TAGS.get(tag, tag)
            exif_table[decoded] = value
            print (f'Tag={tag}, Value={value}, decoded= {decoded}')
        print (f'exif table is {exif_table}')
        gps_info = {}
        for key in exif_table['GPSInfo'].keys():
            decode = GPSTAGS.get(key,key)
            gps_info[decode] = exif_table['GPSInfo'][key]
        return gps_info
         
    if __name__ == "__main__":
        exif = get_exif(filename)
        print(exif)

错误信息是:

Traceback(最近一次调用最后一次):

exif_t​​able['GPSInfo'].keys() 中的键: AttributeError: 'int' 对象没有属性 'keys'

我了解 GPSInfo 的值本身就是文件另一部分的键,该文件本身具有关于纬度和经度的键和值。在这个图像文件的情况下 GPSInfo 是 90。我假设它是一个整数,这就是导致问题的原因,但是由于示例代码出现在互联网上的多个地方,我看不出真正的问题是什么

我在 gps_info={} 语句之前添加了一些打印行。这准确地显示了这条线 for key in exif_table['GPSInfo'].keys(): 正在处理

标签=34853,值=90,解码= GPSInfo 标签=296,值=2,解码= ResolutionUnit 标签=531, 值=1, 解码= YCbCrPositioning'标签=282, 值=96.0, 解码= XResolution 标签=283,值=96.0,解码= YResolution exif 表是 {'GPSInfo': 90, 'ResolutionUnit': 2, “YCbCrPositioning”:1,“XResolution”:96.0, 'Y分辨率':96.0}

标签 34853 正确地等同于 GPSInfo。该文件中GPSInfo的值为90。

我知道在文件的位置 90 处,人们会期望找到一串代表 GPS 坐标的键值数据的值,因此“for key in exif_t​​able ['GPSInfo'].keys(): “陈述。我认为它失败了,因为 exif_t​​able["GPSInfo"] 的值为 90 并且被视为整数,而不是字典。看起来好像少了一个步骤,但作为它广泛发布的代码,我认为它必须工作,而且是我有问题

【问题讨论】:

  • 是时候使用调试器了 - 在导致错误的行设置断点并检查 exif_tableexif_table['GPSInfo'] 包含的内容。
  • TDG - 我添加了一些结果和值来显示正在发生的事情
  • 我是否可以从缺乏答案的情况下假设这段代码真的不起作用?我会尝试联系发布者并请他们解释它是如何工作的

标签: python gps python-imaging-library


【解决方案1】:

可能与EXIF版本有关。

我遇到了同样的问题,尽管我没有找到枕头的解决方案,但我确实找到了解决方法,感谢这篇文章:https://medium.com/spatial-data-science/how-to-extract-gps-coordinates-from-images-in-python-e66e542af354

解决方法使用exif包而不是枕头,但如果你需要最后一个,应该有一种方法来组合它们。

我的代码不起作用:

import PIL.Image
import PIL.ExifTags
from gmplot import gmplot
from geopy.geocoders import Nominatim
import webbrowser
import os

filename = 'IMG_1874'
input = f'{filename}.jpg'
output = f'{filename}-location.html'

img = PIL.Image.open(input)

exif = {
    PIL.ExifTags.TAGS[k]: v
    for k, v in img.getexif().items()
    if k in PIL.ExifTags.TAGS
}

north = exif['GPSInfo'][2]
east = exif['GPSInfo'][4]

lat = ((north[0] * 60 + north[1]) * 60 + north[2]) / 3600
lon = ((east[0] * 60 + east[1]) * 60 + east[2]) / 3600

gmap = gmplot.GoogleMapPlotter(lat, lon, 12)
gmap.marker(lat, lon, 'red')
gmap.draw(output)

address = Nominatim(user_agent='GetLoc')
location = address.reverse(f'{lat}, {lon}')

print(location.address)

webbrowser.open(f'file:///{os.getcwd()}/{output}', new=1)

使用 exif 包的解决方法:

from exif import Image
from gmplot import gmplot
from geopy.geocoders import Nominatim
import webbrowser
import os

def decimal_coords(coords, ref):
    decimal_degrees = coords[0] + coords[1] / 60 + coords[2] / 3600
    if ref == 'S' or ref == 'W':
        decimal_degrees = -decimal_degrees
    return decimal_degrees

filename = 'IMG_1874'
input = f'{filename}.jpg'
output = f'{filename}-location.html'

with open(input, 'rb') as src:
    img = Image(src)
    print (src.name, img)

lat = decimal_coords(img.gps_latitude, img.gps_latitude_ref)
lon = decimal_coords(img.gps_longitude, img.gps_longitude_ref)

gmap = gmplot.GoogleMapPlotter(lat, lon, 12)
gmap.marker(lat, lon, 'red')
gmap.draw(output)

address = Nominatim(user_agent='GetLoc')
location = address.reverse(f'{lat}, {lon}')

print(location.address)

webbrowser.open(f'file:///{os.getcwd()}/{output}', new=1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-23
    • 2014-08-13
    • 2019-08-31
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    相关资源
    最近更新 更多