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

2022-12-07 15:26:55 浏览数 (1)

需求

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

经纬度格式解读

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

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

  • 十进制换度分秒
  • 度分秒换十进制

程序代码

获取单张图片经纬度

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

代码语言:javascript复制
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

批量获取图片经纬度

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

代码语言:javascript复制
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

数据写入csv文件

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

代码语言:javascript复制
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)

然后写入数据:

代码语言:javascript复制
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)

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

完整示例代码

代码语言:javascript复制
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)

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

0 人点赞