显示图片
显示结果没有原图清晰
from skimage import io
import matplotlib.pyplot as plt
img=io.imread('F:\Vue\kool.jpg')
io.imshow(img)
plt.show()
查看RGB参数
图片的像素可以右击点【属性】,选择【详细信息】就可以看图片的具体信息。
我用手机拍的一张照片,发原图到电脑上。用这种方法可以查看拍摄时间,拍摄地经纬度,手机型号等。
from skimage import io
import matplotlib.pyplot as plt
img=io.imread('F:\Vue\img\kool.jpg')
print(img.shape)
for i in img[0]:
print(i)
'''
第一个打印结果:(3059, 2448, 3)
我的kool.jpg文件,分辨率是2448x3059。
所以img.shape 的输出结果代表图片高3059像素,宽2448像素,每个像素有3个参数。这里的参数是RGB数值,即构成这个像素的三个RGB数值
所以这张图片可以看作是一张3059行2448列的表,每个表格里都有三个数
第二个循环打印结果如下,我这里截取了前五个:
[218 217 215]
[219 218 216]
[220 219 217]
[220 219 217]
[220 219 217]
... ...
len(img[0])=2448,上面这些就是第一行里面的像素参数
第一行的第一个像素点,R(red)218、G(green)217、B(blue)215
第一行的第二个像素点,R219、G218、B216 ......
'''
查看图片详细信息
import exifread
def getImgInfo(img_path):
img_read = open(img_path, 'rb')
img_exif = exifread.process_file(img_read)
if img_exif:
for item in img_exif:
print("{0}:{1}".format(item,img_exif[item]))
else:
print("图像信息为空,可能是上传的不是原图")
if __name__ == '__main__':
img_path = 'F:\Vue\img\qq_20210916_190641.jpg'
getImgInfo(img_path)
大多数图片都能读出来信息来,除非这张图片很“干净”或者不是原图。
获取图片信息
import exifread
import pprint
def getImgInfo(img_path):
img_read = open(img_path, 'rb')
img_exif = exifread.process_file(img_read)
imgInfo = {}
if img_exif:
# for item in img_exif:
# print("{0}:{1}".format(item,img_exif[item]))
imgInfo['图片宽度'] = str(img_exif['Image ImageWidth'])
imgInfo['图片高度'] = str(img_exif['Image ImageLength'])
imgInfo['手机品牌'] = str(img_exif['Image Make'])
imgInfo['手机型号'] = str(img_exif['Image Model'])
imgInfo['手机版本号'] = str(img_exif['Image Software'])
imgInfo['拍摄时间'] = str(img_exif['Image DateTime'])
imgInfo['纬度方向'] = str(img_exif['GPS GPSLatitudeRef'])
lat = str(img_exif["GPS GPSLatitude"])[1: -1].replace("/", ",").split(",")
imgInfo["纬度"] = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
imgInfo['经度方向'] = str(img_exif['GPS GPSLongitudeRef'])
lng = str(img_exif["GPS GPSLongitude"])[1: -1].replace("/", ",").split(",")
imgInfo["经度"] = float(lng[0]) + float(lng[1]) / 60 + float(lng[2]) / float(lng[3]) / 3600
# 还有一个GPS GPSAltitudeRef参数, 但不知道它的数值是啥意思
imgInfo['高度'] = str(img_exif['GPS GPSAltitude'])
return imgInfo
if __name__ == '__main__':
img_path = 'F:\Vue\img\qq_20210916_190641.jpg'
imgInfo = getImgInfo(img_path)
if imgInfo== {} :
print("图像信息为空,可能是上传的不是原图")
else:
pprint.pprint(imgInfo)
得出坐标后可以用一个在线工具查看位置。https://www.toolzl.com/tools/gps.html。
但在转换时要选择原始GPS属性,因为其他的会有偏差。其他几个我都做了对比,还原度最高的那个就是GPS属性,百度高德都不太准,毕竟自己拍的照片还是知道位置在哪的。
高德的转换工具:https://lbs.amap.com/tools/picker
最终整合
接下来是使用高德提供的API来直接输出结果,有兴趣的可以研究一下怎么把偏差给修正。
这里是需要先在高德开放平台上申请一个 Web 服务的应用,获得一个秘钥Key 用于逆地理编码 API。
import exifread
import pprint
import requests
import json
import math
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626 # π
a = 6378245.0 # 长半轴
ee = 0.00669342162296594323 # 扁率
def wgs84togcj02(lng, lat):
"""
WGS84转GCJ02(火星坐标系)
:param lng:WGS84坐标系的经度
:param lat:WGS84坐标系的纬度
:return:
"""
if out_of_china(lng, lat): # 判断是否在国内
return lng, lat
dlat = transformlat(lng - 105.0, lat - 35.0)
dlng = transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic = math.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [mglng, mglat]
def gcj02towgs84(lng, lat):
"""
GCJ02(火星坐标系)转GPS84
:param lng:火星坐标系的经度
:param lat:火星坐标系纬度
:return:
"""
if out_of_china(lng, lat):
return lng, lat
dlat = transformlat(lng - 105.0, lat - 35.0)
dlng = transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic = math.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic = math.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [lng * 2 - mglng, lat * 2 - mglat]
def transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
math.sin(2.0 * lng * pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(lat * pi) + 40.0 *
math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
math.sin(lat * pi / 30.0)) * 2.0 / 3.0
return ret
def transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
math.sin(2.0 * lng * pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(lng * pi) + 40.0 *
math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
return ret
def out_of_china(lng, lat):
"""
判断是否在国内,不在国内不做偏移
:param lng:
:param lat:
:return:
"""
if lng < 72.004 or lng > 137.8347:
return True
if lat < 0.8293 or lat > 55.8271:
return True
return False
# 获取图片信息
def getImgInfo(img_path):
img_read = open(img_path, 'rb')
img_exif = exifread.process_file(img_read)
imgInfo = {}
if img_exif:
imgInfo['图片宽度'] = str(img_exif['Image ImageWidth'])
imgInfo['图片高度'] = str(img_exif['Image ImageLength'])
imgInfo['手机品牌'] = str(img_exif['Image Make'])
imgInfo['手机型号'] = str(img_exif['Image Model'])
imgInfo['手机版本号'] = str(img_exif['Image Software'])
imgInfo['拍摄时间'] = str(img_exif['Image DateTime'])
imgInfo['纬度方向'] = str(img_exif['GPS GPSLatitudeRef'])
lat = str(img_exif["GPS GPSLatitude"])[1: -1].replace("/", ",").split(",")
imgInfo["纬度"] = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
imgInfo['经度方向'] = str(img_exif['GPS GPSLongitudeRef'])
lng = str(img_exif["GPS GPSLongitude"])[1: -1].replace("/", ",").split(",")
imgInfo["经度"] = float(lng[0]) + float(lng[1]) / 60 + float(lng[2]) / float(lng[3]) / 3600
# 还有一个GPS GPSAltitudeRef参数, 但不知道它的数值是啥意思
imgInfo['高度'] = str(img_exif['GPS GPSAltitude'])
return imgInfo
# 获取地址信息
def getAddress(imgInfo):
if imgInfo:
# 高德API只能识别到小数点后的6位,但好像它会自动将多余的裁掉
# print("%.6f" % imgInfo["经度"])
latitude = imgInfo["纬度"]
longitude = imgInfo["经度"]
# 注意:由于gps获取的坐标在国内高德等主流地图上逆编码不够精确,这里需要转换为火星坐标系
# WGS84转GCJ02(火星坐标系)
mglng, mglat = wgs84togcj02(longitude, latitude)
url = 'https://restapi.amap.com/v3/geocode/regeo?key={}&location={}' # 详见高德逆解析地理API文档
location = '{},{}'.format(mglng, mglat)
api_key = '将你的Key粘贴到这里'
resp = requests.get(url.format(api_key, location))
data = json.loads(resp.text)
address = data.get('regeocode').get('formatted_address')
return data,address
else:
return 0,0
if __name__ == '__main__':
img_path = 'F:\Vue\img\qq_20210916_190641.jpg'
imgInfo = getImgInfo(img_path)
data, address = getAddress(imgInfo)
if imgInfo == {} :
print("图像信息为空,可能是上传的不是原图")
else:
pprint.pprint(imgInfo)
print('---------------------------')
print(f"拍摄地址:{address}")
参考资料:
https://blog.csdn.net/qq_36685813/article/details/102573196?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_utm_term~default-0.no_search_link&spm=1001.2101.3001.4242