• 【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

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

    在这里插入图片描述

  • 相关阅读:
    Compositional Minimax Optimization学习之路
    CentOS安装nodejs
    2023 年 Arm A-Profile 架构发展
    Golang vs Rust 为后端选择哪种语言?
    迅为RK3568开发板文件互传与OTA升级
    缓存中间件-Redis(二)
    深度学习(PyTorch)——长短期记忆神经网络(LSTM)
    Day46 力扣动态规划 : 392.判断子序列 | 115.不同的子序列
    Vue 官方文档2.x教程学习笔记 1 基础 1.7 条件渲染
    分布式事务解决方案
  • 原文地址:https://blog.csdn.net/qq1198768105/article/details/128159598