• 【Python】批量提取图片经纬度并写入csv文件


    需求

    无人机图片中往往包含经纬度信息,需要一个脚本批量将文件夹中包含经纬度信息的图片提取出来,保存成csv文件。

    经纬度格式解读

    默认情况下,图片采用的WGS84经纬度,默认格式采用的是度分秒格式,另一种格式是十进制格式。

    在这里插入图片描述

    度分秒格式和十进制格式之间的转换规则如下,图源:https://www.jb51.net/article/238397.htm

    • 十进制换度分秒
    • 度分秒换十进制
      在这里插入图片描述

    程序代码

    获取单张图片经纬度

    这里采用exifread库来提取图片的经纬度,同时,对于不包含经纬度的图片,无法直接进行提取,因此先用try–except的方式来进行试探:

    def get_single_gps(img):
        with open(img, 'rb') as f:
            # 直接读取度分秒格式的经纬度数据
            contents = exifread.process_file(f)
            try:
                longitude = contents["GPS GPSLongitude"].values
                has_longitude = True
            except:
                has_longitude = False
            if not has_longitude:
                return '', ''
            else:
                longitude = contents["GPS GPSLongitude"].values
                latitude = contents["GPS GPSLatitude"].values
                # 度分秒转换成十进制数据
                longitude_f = longitude[0].num / longitude[0].den + (longitude[1].num / longitude[1].den / 60) + (
                        longitude[2].num / longitude[2].den / 3600)
                latitude_f = latitude[0].num / latitude[0].den + (latitude[1].num / latitude[1].den / 60) + (
                        latitude[2].num / latitude[2].den / 3600)
                return longitude_f, latitude_f
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    批量获取图片经纬度

    实现单张之后,批量实现加个循环即可:

    def get_gps(img_path):
        img_name = []
        logitude_list = []
        latitude_list = []
        for single_img in os.listdir(img_path):
            img_name.append(single_img)
            longitude, latitude = get_single_gps(img_path + '/' + single_img)
            logitude_list.append(longitude)
            latitude_list.append(latitude)
        return img_name, logitude_list, latitude_list
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    数据写入csv文件

    首先需要创建一个csv文件,设定文件的表头:

    def create_csv(root):
        header = ['img_path', 'Longitude', 'Latitude']
        with open(root + '/gps.csv', 'w', encoding='utf-8-sig', newline="") as f:
            writer = csv.writer(f)
            writer.writerow(header)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后写入数据:

    def write_csv(root, result_list):
        for i in result_list:
            with open(root + '/gps.csv', 'a', encoding='utf-8-sig', newline="") as f:
                writer = csv.writer(f)
                writer.writerow(i)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意这里采用utf-8-sig编码,这是为了防止中文信息输入显示为乱码。

    完整示例代码

    import os
    
    import exifread
    import csv
    
    def get_single_gps(img):
        with open(img, 'rb') as f:
            # 直接读取度分秒格式的经纬度数据
            contents = exifread.process_file(f)
            try:
                longitude = contents["GPS GPSLongitude"].values
                has_longitude = True
            except:
                has_longitude = False
            if not has_longitude:
                return '', ''
            else:
                longitude = contents["GPS GPSLongitude"].values
                latitude = contents["GPS GPSLatitude"].values
                # 度分秒转换成十进制数据
                longitude_f = longitude[0].num / longitude[0].den + (longitude[1].num / longitude[1].den / 60) + (
                        longitude[2].num / longitude[2].den / 3600)
                latitude_f = latitude[0].num / latitude[0].den + (latitude[1].num / latitude[1].den / 60) + (
                        latitude[2].num / latitude[2].den / 3600)
                return longitude_f, latitude_f
    
    
    def get_gps(img_path):
        img_name = []
        logitude_list = []
        latitude_list = []
        for single_img in os.listdir(img_path):
            img_name.append(single_img)
            longitude, latitude = get_single_gps(img_path + '/' + single_img)
            logitude_list.append(longitude)
            latitude_list.append(latitude)
        return img_name, logitude_list, latitude_list
    
    def create_csv(root):
        header = ['img_path', 'Longitude', 'Latitude']
        with open(root + '/gps.csv', 'w', encoding='utf-8-sig', newline="") as f:
            writer = csv.writer(f)
            writer.writerow(header)
    
    
    def write_csv(root, result_list):
        for i in result_list:
            with open(root + '/gps.csv', 'a', encoding='utf-8-sig', newline="") as f:
                writer = csv.writer(f)
                writer.writerow(i)
    
    
    def main(img):
        root = os.getcwd()
        create_csv(root)
        img_name, logitude_list, latitude_list = get_gps(img)
        index = range(len(img_name))
        row_list = [[img_name[i], logitude_list[i], logitude_list[i]] for i in index]
        write_csv(root, row_list)
    
    
    if __name__ == '__main__':
        img = 'E:/Xdu_data/ceshi'
        main(img)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    设定图片文件夹路径,运行之后,可以得到输出结果:

    在这里插入图片描述

  • 相关阅读:
    2023-11-08:用go语言,字符串哈希原理和实现 比如p = 233, 也就是课上说的选择的质数进制 “ 3 1 2 5 6 ...“ 0 1 2 3 4 hash[0] = 3 * p的0
    二叉树基本操作-1
    认识Chrome扩展插件
    观测云产品更新 | 数据转发、监控器告警策略等优化
    Python 图形化界面基础篇:更改字体、颜色和样式
    七、Feign
    Go语言学习(四)-- 流程控制
    RPA流程自动化的优势和好处
    vscode软件上安装 Fitten Code插件及使用
    手把手教你用LVS-DR模式搭建Nginx集群
  • 原文地址:https://blog.csdn.net/qq1198768105/article/details/128159598