有时候需要给图片增加地理信息,比如在用无人机影像做3维建模或者正射影像时,可以将无人机的gps写入图片,然后用ODM快速完成三维模型与正射影像生成。
ODM的使用方法可以参看下面这篇博客。
https://blog.csdn.net/weixin_43162240/article/details/102952913
图片exif信息对比
在做处理之前可以通过图片属性查看是否含有gps信息。看这个例子里面图片信息是不包含exif信息的。
在做了以下操作后可以看到图片属性里面已经加上了gps信息.
实践代码
这里主要调用piexif库来实现,所以需要先安装piexif。
$ pip install piexif
代码中写有详细的注释。就不做额外说明了。
这里是通过pos数据批量修改图片,所以需要一个pos.csv文件,图片目录,以及图片输出存放的目录。并且对应pos数据的列号修改main函数中的lng, lat, alt的item序号。
#ecoding:utf-8
import datetime
from PIL import Image
import piexif
import csv
import os
def main(csv_path, image_root, save_root):
csv_data = open(csv_path, "r")
reader = csv.reader(csv_data)
# 读取csv的每一行,跳过标题行
for item in reader:
if reader.line_num <= 1:
continue
lng = float(item[1])
lat = float(item[2])
alt=float(item[4])
# 将经纬度与相对航高转为exif可用的经纬度与行高
# exif需要的航高输入为(20000,2)格式,表示高度为20000/100米
# exif需要的经度与维度为((12, 1), (20,1), (41000, 1000))格式表示12度20分41秒
lng_exif = format_latlng(lng)
lat_exif = format_latlng(lat)
alt_exif = (int(100*round(alt,2)),100)
_dict = {"alt": alt_exif, "lng":
lng_exif, "lat": lat_exif, "lng_ref":'W', "lat_ref":'N'}
image_path = os.path.join(image_root, item[-1])
save_path = os.path.join(save_root, item[-1])
# 修改图片的exif
read_modify_exif(image_path, save_path, _dict)
print('{} finished'.format(item[-1]))
def format_latlng(latlng):
"""经纬度十进制转为分秒"""
degree = int(latlng)
res_degree = latlng - degree
minute = int(res_degree * 60)
res_minute = res_degree * 60 - minute
seconds = round(res_minute * 60.0,3)
return ((degree, 1), (minute,1), (int(seconds*1000), 1000))
def read_modify_exif(image_path,save_path, _dict):
""" 读取并且修改exif文件"""
img = Image.open(image_path) # 读图
exif_dict = piexif.load(img.info['exif']) # 提取exif信息
exif_dict['GPS'][piexif.GPSIFD.GPSAltitude] = _dict['alt'] # 修改高度,GPSAltitude是内置变量,不可修改
exif_dict['GPS'][piexif.GPSIFD.GPSLongitude] = _dict['lng'] # 修改经度
exif_dict['GPS'][piexif.GPSIFD.GPSLatitude] = _dict['lat'] # 修改纬度
exif_dict['GPS'][piexif.GPSIFD.GPSLongitudeRef] = _dict['lng_ref'] # odm需要读取,一般为’W'
exif_dict['GPS'][piexif.GPSIFD.GPSLatitudeRef] = _dict['lat_ref'] # 一般为‘N'
exif_bytes = piexif.dump(exif_dict)
print('alt:{} lng:{} lat:{}'.format(exif_dict['GPS'][piexif.GPSIFD.GPSAltitude], exif_dict['GPS'][piexif.GPSIFD.GPSLongitude], exif_dict['GPS'][piexif.GPSIFD.GPSLatitude]))
img.save(save_path, "jpeg", exif=exif_bytes) # 保存
def check_folder(path_list):
"""输入为文件夹列表,文件夹不存在则创建"""
for path in path_list:
if not os.path.exists(path):
os.mkdir(path)
if __name__ == "__main__":
csv_path = '/home/dennis/pure_python/odm/exif_write/exif_data/from/pos.csv'
image_root = '/home/dennis/pure_python/odm/exif_write/exif_data/from'
save_root = '/home/dennis/pure_python/odm/exif_write/exif_data/to'
check_folder([csv_path, image_root, save_root])
main(csv_path, image_root, save_root)