1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python获取原图GPS位置信息 轻松得到你的活动轨迹

python获取原图GPS位置信息 轻松得到你的活动轨迹

时间:2020-04-19 13:59:30

相关推荐

python获取原图GPS位置信息 轻松得到你的活动轨迹

点击上方“AI搞事情”关注我们

一、图像EXIF信息

介绍

EXIF(Exchangeable image file format,可交换图像文件格式)是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据,如拍摄时间、图像分辨率、感光值、GPS坐标等。

Exif最初由日本电子工业发展协会在1996年制定,版本为1.0。1998年,升级到2.1,增加了对音频文件的支持。2002年3月,发表了2.2版。

Exif可以附加于JPEG、TIFF、RIFF等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。

Exif信息是可以被任意编辑的,因此只有参考的功能。Exif信息以0xFFE1作为开头标记,后两个字节表示Exif信息的长度。所以Exif信息最大为64 kb,而内部采用TIFF格式。

参考自百度百科

查看EXIF信息

windows文件属性

:本文处理图片针对原图

Windows7以上操作系统具备对Exif的原生支持,Windows系统下,可以通过鼠标右键点击图片打开菜单,点击属性并切换到详细信息标签下,即可直接获取图片的EXIF信息。

在线查看器

图虫EXIF查看器

/

改图宝

/exif

我爱斗图(一个表情包网站????)

/tools/exif

exifread 库

exifread模块为python读取图片EXIF信息的库。

exifread模块的下载地址:/pypi/ExifRead

安装exifread库

pip install exifread

主要使用process_file函数进行解析,传入图片文件对象,返回一个包含图片信息的字典。其中,exif中GPS格式为DMS格式,即:D(degree,度)、M(minute,分)、S(second,秒),因此要进行转换才能得到常见的double类型的经纬度值。下面就用python + exifread读取图片的详细信息。

import exifreadwith open('IMG_0618_163339.jpg', 'rb') as f:exif_dict = exifread.process_file(f)print('拍摄时间:', exif_dict['EXIF DateTimeOriginal'])print('照相机制造商:', exif_dict['Image Make'])print('照相机型号:', exif_dict['Image Model'])print('照片尺寸:', exif_dict['EXIF ExifImageWidth'], exif_dict['EXIF ExifImageLength'])# 经度lon_ref = exif_dict["GPS GPSLongitudeRef"].printablelon = exif_dict["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600if lon_ref != "E":lon = lon * (-1)# 纬度lat_ref = exif_dict["GPS GPSLatitudeRef"].printablelat = exif_dict["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600if lat_ref != "N":lat = lat * (-1)print('照片的经纬度:', (lat, lon))for key in exif_dict:print("%s: %s" % (key, exif_dict[key]))

输出:

拍摄时间::06:18 16:33:40照相机制造商:HUAWEI照相机型号:HRY-AL00Ta照片尺寸:3968 2976照片的经纬度:(13.787098884444445, 100.62936401361111)Image ImageWidth: 3968Image ImageLength: 2976Image BitsPerSample: [8, 8, 8]Image Make: HUAWEIImage Model: HRY-AL00TaImage Orientation: 0Image XResolution: 72Image YResolution: 72Image ResolutionUnit: Pixels/InchImage Software: HRY-AL00Ta 9.0.1.130(C00E130R4P1)Image DateTime: :06:18 16:33:40Image YCbCrPositioning: CenteredImage ExifOffset: 290GPS GPSVersionID: [2, 2, 0, 0]GPS GPSLatitudeRef: NGPS GPSLatitude: [13, 47, 847249/62500]GPS GPSLongitudeRef: EGPS GPSLongitude: [100, 37, 45710449/1000000]............................省略

二、经纬度转地址

要想将图片中的经纬度信息转换为详细地址,同样也有很多方法,比如在线查询地图API或者利用python的地理位置信息库:geopy

在线查询

GPS查询网址1

/maps.htm

上文图片经纬度结果

GPS查询网址2

/dingwei.html

地球在线

/

没错,这张图片是我在泰国拍的????

地图API

这里以百度地图API为例,需要去官网注册创建应用获取AK码。

百度地图: 这里以我之前拍的重庆彩车照进行试验,从输出结果上看算是非常精准定位了。

import jsonimport requestsimport exifreadwith open('IMG_1019_164726.jpg', 'rb') as f:exif_dict = exifread.process_file(f)# 经度lon_ref = exif_dict["GPS GPSLongitudeRef"].printablelon = exif_dict["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600if lon_ref != "E":lon = lon * (-1)# 纬度lat_ref = exif_dict["GPS GPSLatitudeRef"].printablelat = exif_dict["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600if lat_ref != "N":lat = lat * (-1)print('照片的经纬度:', (lat, lon))# 调用百度地图api转换经纬度为详细地址secret_key = 'MAsVGINLNyTGiM4UulcaeluCekGnAFxj' # 百度地图api 需要注册创建应用baidu_map_api = 'http://api./reverse_geocoding/v3/?ak={}&output=json&coordtype=wgs84ll&location={},{}'.format(secret_key, lat, lon)content = requests.get(baidu_map_api).textgps_address = json.loads(content)# 结构化的地址formatted_address = gps_address["result"]["formatted_address"]# 国家(若需访问境外POI,需申请逆地理编码境外POI服务权限)country = gps_address["result"]["addressComponent"]["country"]# 省province = gps_address["result"]["addressComponent"]["province"]# 市city = gps_address["result"]["addressComponent"]["city"]# 区district = gps_address["result"]["addressComponent"]["district"]# 语义化地址描述sematic_description = gps_address["result"]["sematic_description"]print(formatted_address)print(gps_address["result"]["business"])

输出

照片的经纬度:(29.564165115277778, 106.54840087888888)重庆市渝中区学田湾正街2号11楼大礼堂,上清寺,大溪沟

geopy库

geopy使python开发人员能够使用第三方地理编码程序和其他数据源(包括谷歌地图,必应地图,Nominatim等),轻松定位全球各地的地址、城市、国家和地标的坐标。

安装

pip install geopy

通过geopy进行经纬度查询

import exifreadfrom geopy.geocoders import Nominatimwith open('IMG_0618_163339.jpg', 'rb') as f:exif_dict = exifread.process_file(f)# 经度lon_ref = exif_dict["GPS GPSLongitudeRef"].printablelon = exif_dict["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600if lon_ref != "E":lon = lon * (-1)# 纬度lat_ref = exif_dict["GPS GPSLatitudeRef"].printablelat = exif_dict["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600if lat_ref != "N":lat = lat * (-1)print('照片的经纬度:', (lat, lon))reverse_value = str(lat) + ', ' + str(lon)geolocator = Nominatim()location = geolocator.reverse(reverse_value)print('照片的经纬度信息:')print((location.latitude, location.longitude))print('照片的地址信息:')print(location.address)

输出

照片的经纬度:(13.787098884444445, 100.62936401361111)照片的经纬度信息:(13.787094791472175, 100.6293647961708)照片的地址信息:กรุงเทพมหานคร, เขตวังทองหลาง, 10310, ประเทศไทย

三、搞事情

一张图片可以暴露你什么时间在什么地方,甚至体现了你当时在做什么,想想有多可怕,不信可以看看这个:

21岁日本女星惨遭猥亵,只因自拍瞳孔倒影暴露住址? |  一张照片是怎么出卖你的!

不过对于个人来说,图片exif信息可以让我们更好地管理自己拍摄的图片库。比如说:

按时间归类

可以通过exif时间信息,将图片归类到不同时间命名的文件夹下。

import osimport exifreadimport shutilimgs_path = 'E:\泰国游'for img in os.listdir(imgs_path):img_path = os.path.join(imgs_path, img)img_file = open(img_path, 'rb')exif_dict = exifread.process_file(img_file)date = exif_dict['EXIF DateTimeOriginal']date = date.values.replace(':', '_')year_month_day = date[:10]target_path = os.path.join('E:\旅游', year_month_day)if not os.path.exists(target_path):os.mkdir(target_path)shutil.copy(img_path, target_path)

旅游地图

下面以本人下半年的手机图片数据进行统计分析,并结合pyecharts和Mapbox进行展示。

pyecharts可视化

pyecharts:一个大神创建的轮子,将python与echarts结合的强大的数据可视化工具。注意版本不同,有些接口调用是有区别的。

pip install pyechartspip install echarts-countries-pypkgpip install pyecharts-jupyter-installer==0.0.3

统计和转换地址的代码,输出为csv文件:

import osimport jsonimport requestsimport pandas as pdimport exifreadfrom geopy.geocoders import Nominatimsecret_key = '###################'def convert_dms2dd(coord_arr):arr = str(coord_arr).replace('[', '').replace(']', '').split(', ')d = float(arr[0])m = float(arr[1])s = float(arr[2].split('/')[0]) / float(arr[2].split('/')[1])dd = float(d) + (float(m) / 60) + (float(s) / 3600)return dddef get_img_infor_tup(photo):img_file = open(photo, 'rb')image_map = exifread.process_file(img_file)img_dict = {}img_dict['Image Name'] = os.path.basename(photo)try:img_dict['width'] = image_map['Image ImageWidth'].printableimg_dict['length'] = image_map['Image ImageLength'].printable# 图片的经度img_longitude = convert_dms2dd(image_map["GPS GPSLongitude"].printable)if image_map["GPS GPSLongitudeRef"].printable != "E":img_longitude = img_longitude * (-1)img_dict['longitude'] = img_longitude# 图片的纬度img_latitude = convert_dms2dd(image_map["GPS GPSLatitude"].printable)if image_map["GPS GPSLatitudeRef"].printable != "N":img_latitude = img_latitude * (-1)img_dict['latitude'] = img_latitudealtitude = image_map['GPS GPSAltitude'].printableif '/' in altitude:altitude = float(altitude.split('/')[0]) / float(altitude.split('/')[1])img_dict['altitude'] = altitude# 照片拍摄时间img_dict['date'] = image_map["EXIF DateTimeOriginal"].printableimg_file.close()# 返回经纬度元组return img_dictexcept Exception as e:img_file.close()print('ERROR:图片中不包含Gps信息')return Nonedef get_detail_infor_by_baidu(lat, lon):baidu_map_api = 'http://api./reverse_geocoding/v3/?ak={0}&output=json&coordtype=wgs84ll&location={1},' \'{2}'.format(secret_key, lat, lon)content = requests.get(baidu_map_api).textgps_address = json.loads(content)return gps_address["result"]def img_data_statistic(imgs_path):info_list = []for file_name in os.listdir(imgs_path):img_path = os.path.join(imgs_path, file_name)info_dict = get_img_infor_tup(img_path)if info_dict is not None:gps_address_dict = get_detail_infor_by_baidu(info_dict['latitude'], info_dict['longitude'])# 省info_dict['province'] = gps_address_dict["addressComponent"]["province"]# 市info_dict['city'] = gps_address_dict["addressComponent"]["city"]# 区info_dict['district'] = gps_address_dict["addressComponent"]["district"]info_dict['formatted_address'] = gps_address_dict["formatted_address"]info_list.append(info_dict)# breakimg_df = pd.DataFrame(info_list)img_df.to_csv('imgInfo.csv', index=False, encoding='utf-8')if __name__ == '__main__':imgs_path = 'E:/photo'img_data_statistic(imgs_path)

可视化,主要是通过pyecharts进行绘图。

import pandas as pdfrom pyecharts.charts import Bardf = pd.read_csv('imgInfo.csv',sep=',')data = df["province"].value_counts()bar = (Bar().add_xaxis(data.index.tolist()).add_yaxis("图片数量", data.values.tolist()).set_global_opts(title_opts=opts.TitleOpts(title="各省分布情况", subtitle='下半年去了哪儿'),xaxis_opts=opts.AxisOpts(name="省份",axislabel_opts={"rotate":45})))bar.render_notebook()

同理,各个城市的统计图。

以及,在地图上进行可视化。

import jsonimport pandas as pdfrom pyecharts import options as optsfrom pyecharts.charts import Geofrom pyecharts.globals import CurrentConfig, NotebookTypeCurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_NOTEBOOKdef is_Chinese(word):for ch in word:if '\u4e00' <= ch <= '\u9fff':return Truereturn Falsedf = pd.read_csv('imgInfo.csv',sep=',')data = df["city"].value_counts()# 找出国外地址,Geo添加自定义点thailand_address = []json_data= {}for city in data.index:if not is_Chinese(city):json_data[city] = df[['longitude','latitude']][df["city"] == city].mean().values.tolist()thailand_address.append(city)json_str = json.dump(json_data, open('thailand.json', 'w', encoding='utf-8'), ensure_ascii=False,indent=4)# 链式调用c = (Geo().add_schema(maptype="world").add_coordinate_json(json_file='thailand.json').add("去过的城市", [list(z) for z in zip(data.index.tolist(), data.values.tolist())],symbol_size = 30, large_threshold = 2000, symbol="pin").set_series_opts(label_opts=opts.LabelOpts(is_show=False)).set_global_opts(title_opts=opts.TitleOpts(title="下半年你去过哪儿")))c.render_notebook()

国内地图展示

Mapbox可视化

可以直接将包含经度和维度的统计数据(csv格式)拖入到网站:

/labs/mbxdataexplorer/

mapbox展示结果

综上,要想自己信息不被泄露,尽量少发原图(●'◡'●)。

长按二维码关注我们

有趣的灵魂在等你

留言请摁

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。