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查看器
https://exif.tuchong.com/
改圖寶
https://www.gaitubao.com/exif
我愛斗圖(一個表情包網站????)
https://www.52doutu.cn/tools/exif
exifread 庫
exifread模塊為python讀取圖片EXIF信息的庫。
exifread模塊的下載地址:https://pypi.python.org/pypi/ExifRead
安裝exifread庫
主要使用process_file函數進行解析,傳入圖片文件對象,返回一個包含圖片信息的字典。其中,exif中GPS格式為DMS格式,即:D(degree,度)、M(minute,分)、S(second,秒),因此要進行轉換才能得到常見的double類型的經緯度值。下面就用python + exifread讀取圖片的詳細信息。
import exifreadwith open('IMG_20190618_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]))輸出:
拍攝時間:2019:06:18 16:33:40 照相機制造商:HUAWEI 照相機型號:HRY-AL00Ta 照片尺寸:3968 2976 照片的經緯度:(13.787098884444445, 100.62936401361111) Image ImageWidth: 3968 Image ImageLength: 2976 Image BitsPerSample: [8, 8, 8] Image Make: HUAWEI Image Model: HRY-AL00Ta Image Orientation: 0 Image XResolution: 72 Image YResolution: 72 Image ResolutionUnit: Pixels/Inch Image Software: HRY-AL00Ta 9.0.1.130(C00E130R4P1) Image DateTime: 2019:06:18 16:33:40 Image YCbCrPositioning: Centered Image ExifOffset: 290 GPS GPSVersionID: [2, 2, 0, 0] GPS GPSLatitudeRef: N GPS GPSLatitude: [13, 47, 847249/62500] GPS GPSLongitudeRef: E GPS GPSLongitude: [100, 37, 45710449/1000000] ............................省略二、經緯度轉地址
要想將圖片中的經緯度信息轉換為詳細地址,同樣也有很多方法,比如在線查詢、地圖API或者利用python的地理位置信息庫:geopy。
在線查詢
GPS查詢網址1
http://www.gpsspg.com/maps.htm
GPS查詢網址2
http://www.gzhatu.com/dingwei.html
地球在線
https://www.earthol.com/
沒錯,這張圖片是我在泰國拍的????
地圖API
這里以百度地圖API為例,需要去官網注冊創建應用獲取AK碼。
百度地圖:http://lbsyun.baidu.com 這里以我之前拍的重慶彩車照進行試驗,從輸出結果上看算是非常精準定位了。
輸出
照片的經緯度:(29.564165115277778, 106.54840087888888) 重慶市渝中區學田灣正街2號11樓 大禮堂,上清寺,大溪溝geopy庫
geopy使python開發人員能夠使用第三方地理編碼程序和其他數據源(包括谷歌地圖,必應地圖,Nominatim等),輕松定位全球各地的地址、城市、國家和地標的坐標。
安裝
pip install geopy通過geopy進行經緯度查詢
import exifread from geopy.geocoders import Nominatimwith open('IMG_20190618_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 os import exifread import 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)旅游地圖
下面以本人2019年下半年的手機圖片數據進行統計分析,并結合pyecharts和Mapbox進行展示。
pyecharts可視化
pyecharts:一個大神創建的輪子,將python與echarts結合的強大的數據可視化工具。注意版本不同,有些接口調用是有區別的。
統計和轉換地址的代碼,輸出為csv文件:
import os import json import requests import pandas as pd import exifread from 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.map.baidu.com/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 pd from 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='19年下半年去了哪兒'),xaxis_opts=opts.AxisOpts(name="省份",axislabel_opts={"rotate":45})) ) bar.render_notebook()同理,各個城市的統計圖。
以及,在地圖上進行可視化。
import json import pandas as pd from pyecharts import options as opts from pyecharts.charts import Geo from pyecharts.globals import CurrentConfig, NotebookType CurrentConfig.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="2019下半年你去過哪兒")) ) c.render_notebook()國內地圖展示
Mapbox可視化
可以直接將包含經度和維度的統計數據(csv格式)拖入到網站:
https://www.mapbox.cn/labs/mbxdataexplorer/
綜上,要想自己信息不被泄露,盡量少發原圖(●'?'●)。
長按二維碼關注我們
有趣的靈魂在等你
留言請摁
總結
以上是生活随笔為你收集整理的python获取原图GPS位置信息,轻松得到你的活动轨迹的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PaddleHub人像分割模型:AI人像
- 下一篇: 【opencv系列05】OpenCV4.