简体   繁体   中英

Python getting image folder lat and lon to df

I tried to build a code in python to go over all photos in folder and get the exif info (only the date and the GPS info are relevant) . I found a code online but it gives me an error. code :

def find_images(image_dir, extensions=None):
    default_extensions = ('jpg', 'jpeg')
    if extensions is None:
        extensions = default_extensions
    elif isinstance(extensions, str):
        extensions = (extensions,)
    for root, dirs, filenames in os.walk(image_dir):
        for filename in filenames:
#             print(filename, filename.split('.', 1))
            if filename.split('.', 1)[-1].lower() in extensions:
                yield os.path.join(root, filename)
            
def process_exif_data(image):
    decoded_exif = {}
    with Image.open(image) as image_file:
        exif_data = image_file._getexif()
        if exif_data is None:
            return None
        for tag, value in exif_data.items():
            decoded = TAGS.get(tag, tag)
            if decoded == "GPSInfo":
                decoded_exif.update(decode_gps_data(value))
            else:
                decoded_exif[decoded] = value

    # This could be done with a dict comprehension and a ternary expression too
    return decoded_exif
    

def decode_gps_data(info):
    gps_tags = {GPSTAGS.get(k, k): v for k, v in value.items}

    lat, long = get_coordinates(gps_tags)
    gps_tags['lat'] = lat
    gps_tags['lon'] = lon

    return gps_tags

def get_coordinates(gps_tags):
    coords = {'Latitude': 'N', 'Longitude': 'E'}
    for coord, nominal_ref in coords.items():
        c = gps_tags.get("GPS%s" % coord, None)
        c_ref = gps_tags.get("GPS%sRef" % coord, None)

        if c and c_ref:
            yield _convert_to_degrees(c, c_ref, nominal_ref)
        else:
            yield None
            
def _convert_to_degrees(value, ref, nominal_ref=None):
    if nominal_ref is None:
        nominal_ref = ('N', 'E',)
    elif isinstance(nom, str):
        nominal_ref = (nominal_ref, )
    ref = 1 if ref in nominal_ref else -1
    return ref * sum(float(v[0]) / float(v[1]) / 60 ** i for i, v in enumerate(value))
                        
def extract_important_data(image_data, important_datalabels=('lat', 'lon', 'DateTimeOriginal')):
    if image_data is None:
        return None
    return {key: image_data.get(key, None) for key in important_datalabels}
                        
def extract_info(images, important_datalabels=('lat', 'lon', 'DateTimeOriginal')):
    for image_path in images:
        print(image_path)
        exif_data = process_exif_data(image_path)
        important_data = extract_important_data(exif_data)
        if important_data:
            yield image_path, important_data
                        
def get_photos_info(image_dir, filename=None, important_datalabels=('lat', 'lon', 'DateTimeOriginal')):
    if image_dir is None:
        image_dir='.'

    images = find_images(image_dir)
    info = extract_info(imgs, important_datalabels=important_datalabels)
    result_df = pd.DataFrame(columns = important_datalabels)
    for image_path, item in info:
        result_df.loc[image_path] = item
    if 'DateTimeOriginal' in important_datalabels:
        date_format = '%Y:%m:%d %H:%M:%S'
        result_df['DateTimeOriginal'] = pd.to_datetime(result_df['DateTimeOriginal'], format=date_format)

    if filename:
        result_df.to_excel(filename)

    return result_df

empty_df = pd.DataFrame
empty_df = get_photos_info(r"C:\Users\dor h\OneDrive\Desktop\study\Final project")

error :

AttributeError                            Traceback (most recent call last)
<ipython-input-32-0aaf3d855413> in <module>
    123 
    124 empty_df = pd.DataFrame
--> 125 empty_df = get_photos_info(r"C:\Users\dor h\OneDrive\Desktop\study\Final project")
    126 # print(empty_df)

<ipython-input-32-0aaf3d855413> in get_photos_info(image_dir, filename, important_datalabels)
    111     info = extract_info(imgs, important_datalabels=important_datalabels)
    112     result_df = pd.DataFrame(columns = important_datalabels)
--> 113     for image_path, item in info:
    114         result_df.loc[image_path] = item
    115     if 'DateTimeOriginal' in important_datalabels:

<ipython-input-32-0aaf3d855413> in extract_info(images, important_datalabels)
     99     for image_path in images:
    100         print(image_path)
--> 101         exif_data = process_exif_data(image_path)
    102         important_data = extract_important_data(exif_data)
    103         if important_data:

<ipython-input-32-0aaf3d855413> in process_exif_data(image)
     48 def process_exif_data(image):
     49     decoded_exif = {}
---> 50     with Image.open(image) as image_file:
     51         exif_data = image_file._getexif()
     52         if exif_data is None:

D:\paython\lib\site-packages\PIL\Image.py in open(fp, mode)
   2816         exclusive_fp = True
   2817 
-> 2818     prefix = fp.read(16)
   2819 
   2820     preinit()

AttributeError: 'JpegImageFile' object has no attribute 'read'

I read somewhere that the problem is I'm trying to open an already open jpg file but I don't see where I'm doing so also I don't know how to solve that.

tnx in advance

It appears that in the line info = extract_info(imgs, important_datalabels=important_datalabels) , imgs is a typo, and should instead be images .

Why this gives you the specific error mode you are seeing depends on what imgs is. The variable imgs must be defined somewhere in your notebook, otherwise your code would raise a NameError. imgs is probably a list or iterator containing some kind of object that Image.open() doesn't expect; this would cause it to fail when it tries to use the object's read method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM