OpenCV for Python 实战(一):获取图片拍摄GPS地址并自动添加水印

Hello 我们在OpenCV每天的基础博客当中已经更新了很多了,那么今天我们就来结合前几天的内容。做一个获取属性然后添加对应属性的水印。那让我们赶快开始吧~

文章目录

  • 图片EXIF
  • Python 获取EXIF
    • exifread库
    • 使用方法
    • 转换成文字地址
  • 添加水印
    • cv2.putText()
  • 每日总结

图片EXIF

可能很多人并没有听说过这个专有名词,这是一个专门储存相片的相关信息的地方。大家一般在操作的时候右键打开属性,点击“详细信息”就会出现这样的界面了~
在这里插入图片描述

今天咱们就来详细了解一下什么是EXIF啦~

EXIF是指Exchangeable Image File

Format(可交换图像文件格式)的缩写。它是一种存储在数字照片中的元数据格式,包含了照片的各种信息,如拍摄时间、相机型号、曝光参数、GPS坐标等。EXIF数据可以为摄影师、设计师、摄影爱好者等提供了有用的信息,同时也为照片的管理和编辑提供了便利。

EXIF数据通常被存储在JPEG、TIFF和RAW等图像文件格式中,通过使用相机或其他设备的内置工具或第三方软件,可以轻松查看和编辑这些数据。在数字摄影中,EXIF数据对于了解照片的拍摄环境和条件非常有用,例如确定曝光设置、焦距、ISO感光度等。

除了基本的拍摄信息外,EXIF数据还可以包含版权信息、作者、拍摄地点等更多信息。这使得照片的归档、共享和管理更加方便。然而,也需要注意保护个人隐私,因为可能包含有关拍摄者或拍摄地点的敏感信息。

而今天,咱们需要获取的就是这个GPS信息

在这里插入图片描述

Python 获取EXIF

exifread库

实际上,我们有很多方法获取其中的信息。但是为了让我们的程序变得更加简单,我们在这里使用第三方库帮我们完成这个读取的操作。

安装代码pip install exifread

在这里插入图片描述

使用方法

我们只需要使用process_file()这个函数就可以直接获取属性

import exifreadtag = exifread.process_file(open("./LFS.jpg","rb"))
print(tag)

在这里插入图片描述

现在我们来获取一下['GPS GPSLatitude']这是咱们的纬度信息。我们可以看到这是一个EXIFread库当中定义的数据类型。
在这里插入图片描述
我们使用printable将其转换成str数据

在这里插入图片描述

再用split(",")分割成列表类型方便读取

在这里插入图片描述

然后咱们先获取度的数据,用replace()代替多余的“[”

import exifreadlatitude = int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60
longitude = int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60
print(longitude,latitude)

同理咱们编写代码,咱们也就成功地获取了经纬值
在这里插入图片描述

转换成文字地址

在这里我们选择百度地图的web工具,具体使用方法见百度地图的文档,咱们这里就直接提供源码了哈~

import exifread,requests,jsonlatitude = int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60
longitude = int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60
message = json.loads(requests.get("https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="+str(latitude)+","+str(longitude)).text)
direction = message["result"]["addressComponent"]["province"] + message["result"]["addressComponent"]["city"] + message["result"]["addressComponent"]["district"] + message["result"]["addressComponent"]["town"]
print(direction)

在这里插入图片描述

添加水印

cv2.putText()

cv2.putText()是OpenCV(开源计算机视觉库)中的一种方法,用于向图像或视频帧添加文本。它需要以下参数:

  • image:需要添加文本的输入图像或帧
  • text:要添加的文本字符串
  • org:一个表示文本起始坐标的元组(x,y)
  • fontFace:字体类型(可以从预定义的字体列表中选择)
  • fontScale:字体大小(乘以字体厚度的比例因子)
  • color:BGR格式的文本颜色(例如,绿色为(0,255,0))
  • thickness:用于绘制文本的线条粗细(可以为负数以获得填充文本)
  • lineType:用于绘制文本的线条类型(例如,cv2.LINE_AA表示反锯齿线)

该方法返回一个添加了文本的图像。

在这里插入图片描述

但是我们要注意的是,OpenCV只能显示英文,无法显示中文。所以我们使用施加魔法pip install opencv-python-rolling下载OpenCV v5.0版本

在这里插入图片描述
OK 轻松获得了咱们的图片
在这里插入图片描述

在这里插入图片描述

import exifread,requests,json,cv2
cv2.imwrite("水印添加.jpg",cv2.putText(img = cv2.imread("./LFS.jpg"),text = json.loads(requests.get("https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60)+","+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60)).text)["result"]["addressComponent"]["province"] + json.loads(requests.get("https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60)+","+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60)).text)["result"]["addressComponent"]["city"] + json.loads(requests.get("https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60)+","+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60)).text)["result"]["addressComponent"]["district"] + json.loads(requests.get("https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60)+","+str(int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60)).text)["result"]["addressComponent"]["town"],org = (400,400),fontFace = cv2.FONT_HERSHEY_SIMPLEX,thickness = 20,fontScale = 10,color = (255,255,255)))

正常长度代码

import exifread,requests,json,cv2latitude = int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLatitude'].printable.split(",")[1])/60
longitude = int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[0].replace("[","")) + int(exifread.process_file(open("./LFS.jpg","rb"))['GPS GPSLongitude'].printable.split(",")[1])/60
message = json.loads(requests.get("https://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="+str(latitude)+","+str(longitude)).text)
direction = message["result"]["addressComponent"]["province"] + message["result"]["addressComponent"]["city"] + message["result"]["addressComponent"]["district"] + message["result"]["addressComponent"]["town"]
cv2.imwrite("水印添加.jpg",cv2.putText(img = cv2.imread("./LFS.jpg"),text = direction,org = (400,400),fontFace = cv2.FONT_HERSHEY_SIMPLEX,thickness = 20,fontScale = 10,color = (255,255,255)))

每日总结

我们使用了EXIFread库获取了图片的经纬值,然后通过Requests访问百度地图的API获得了我们的实际地位,用json库转换之后,用最新版的OpenCV的putText()方法获得了添加水印后的图像。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【001 操作系统】什么是线程、进程?线程进程的区别是什么?

一、什么是线程、进程? 进程:进程是资源分配的基本单位,它是程序执行时的一个实例,在程序运行时创建。 在Linux环境下,每个进程有自己各自独立的 4G 地址空间,大家互不干扰对方,如果两个进程之间…

基于大模型的Text2SQL微调的实战教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

Homography单应性矩阵

1. Homography 单应性概念 考虑 同一个平面(比如书皮)的两张图片,红点表示同一个物理坐标点在两张图片上的各自位置。在 CV 术语中,我们称之为对应点。 Homography 就是将一张图像上的点映射到另一张图像上对应点的3x3变换矩阵. 因为 Homography 是一个 …

Python模块requests基本用法

简介 Python 的 requests 模块是一个流行的第三方库,用于发送HTTP请求。它提供了一组简洁且易于使用的API,使得在Python中进行网络通信变得更加简单和灵活。 目录 1. 基本概念 1.1. HTTP 协议 1.2. GET 请求 1.3. POST 请求 1.4. get 和 post 的区别…

java本地socket服务端暴露至公网访问【内网穿透】

前言 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于恒川的日常汇报系列,大家有兴趣的可以看一看 📘相关专栏C语言初…

蓝桥杯专题-真题版含答案-【生命之树】【消除尾一】【密码脱落】【生日蜡烛】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

【Java项目实战-牛客社区】--idea maven配置

第一 IDEA集成Maven插件,并配置Maven 以下步骤中,重点关注红色方框的配置 第二 IDEA 创建 Maven 项目 步骤一:创建模块,选择Maven,点击Next 步骤二:填写模块名称,坐标信息,点击finis…

【技术面试】Java八股文业余选手-下篇(持续更新)

文章目录 5. RocketMQ 消息中间件、RabbitMQ、ActiveMQ【√】5.1 RocketMQ 6. Kafka 大数据量消息中间件、ElasticSearch、ZooKeeper【√】6.1 Kafka【√】6.2 ElasticSearch 7. 分布式、研发提效、高并发、线程安全【√】7.1 分布式与集群【√】7.2 高并发、线程安全【】7.3 研…

【JavaScript】实现网页中的选项卡

一、简易选项卡 以下是实现一个简单选项卡的代码。代码中有注释。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

Airbnb 引入 HTTP Streaming,网页性能得到大幅度提升

Airbnb 通过引入HTTP Streaming来提升网站的页面加载性能。他们将测试的每个页面&#xff08;包括主页&#xff09;的首次内容绘制&#xff08;First Contentful Paint&#xff0c;FCP&#xff09;时间降低了大约 100 毫秒。他们还最小化了后端慢查询对加载时间的影响。 Airbn…

Docker概述 镜像-容器基本操作

Docker 概述 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。 Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自足…

Docker 安装 和 GPU 支持

一、Docker安装过程&#xff08;ubuntu18.04环境&#xff09; 清华镜像 docker 安装&#xff1a;docker-ce | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 1、由于apt官方库里的docker版本可能比较旧&#xff0c;所以先卸载可能存在的旧版本&…

MySQL(一)基本架构、SQL语句操作、试图

MySQL系列文章 MySQL&#xff08;一&#xff09;基本架构、SQL语句操作、试图 MySQL&#xff08;二&#xff09;索引原理以及优化 MySQL&#xff08;三&#xff09;SQL优化、Buffer pool、Change buffer MySQL&#xff08;四&#xff09;事务原理及分析 MySQL&#xff08;五&a…

异步任务——CompletabelFuture

本专栏学习内容又是来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 在学习CompletableFuture之前&#xff0c;必须要先了解一下Future Future 概念 Future接口&#xff08;FutureTask实现类&#xff09;定义了操作异步任务执行的一些方法&#xff0c;如获取异…

前端学习——Vue (Day2)

指令补充 指令修饰符 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…

每月进度总结 7月1日~7月22日

一个月已经过了三分之二了&#xff0c;感觉这个月是在学校学的很多。也是最充实的三个星期。其中也有发呆&#xff0c;也有过懊悔&#xff0c;今天状态为什么这么差&#xff0c;就学了这一点。但是还有学到知识的喜悦。总之是认识到了自己的很多不足&#xff0c;也找到了相对正…

【笔试强训选择题】Day28.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&#xff…

基础 | 日志 | 体系介绍

INDEX 总览图上图的说明 总览图 上图的说明 日志体系的结构大约可以概括为 日志门面日志绑定层日志实现日志桥接层 slf4j 是 日志门面&#xff0c;所谓日志门面可以理解为日志总接口 slf4j-log4j、log4j-slf4j-impl 是 日志绑定层&#xff0c;日志绑定层的作用是将 日志门面…

C#using关键字的使用方法

这篇日志记录下C#中using关键字的使用方法。 Using的使用大致分别以下三种&#xff1a; 1&#xff1a;using指令&#xff08;命名空间&#xff09; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; …

【stable diffusion】保姆级入门课程03-Stable diffusion(SD)图生图-涂鸦(绘图)的用法

目录 0.本章素材 1.涂鸦有什么用 2.涂鸦的使用场景是什么 3.操作面板 4.提示词与涂鸦 5.涂鸦与重绘幅度 6.涂鸦的其他用法(自由创作) 7.课后训练 0.本章素材 Realistic Vision V3.0模型(真实系模型)百度网盘链接&#xff1a;https://pan.baidu.com/s/1HkSKW2t4L6wMg…