Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十二 简单图片添加水印效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十二 简单图片添加水印效果

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之十二 简单图片添加水印效果

一、简单介绍

二、简单图片添加水印效果实现原理

三、简单图片添加水印效果案例实现简单步骤

四、注意事项


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

这里使用 Python  基于 OpenCV 进行视觉图像处理,......

二、简单图片添加水印效果实现原理

给图片添加水印是指在图片上叠加额外的标识、文字、图形或者其他图像,以表明该图片的归属、来源、版权信息或者其他附加信息的过程。水印通常以半透明的方式显示在图片的某个位置,可以防止未经授权的复制和使用,并且可以提升图片的专业性和美观度。添加水印的过程可以通过图像处理技术来实现,包括图像叠加、透明度调整、文字绘制等。

  1. 添加文字水印 (add_watermark_text)

    • 原理:在原始图像上绘制指定的文字,作为水印。
    • 实现方法:使用 OpenCV 的 cv2.putText() 函数在图像上添加文字。
  2. 添加图片水印 (add_watermark_image)

    • 原理:将水印图片叠加到原始图像的指定位置。
    • 实现方法:将水印图片的 BGR 通道与原始图像的相应区域进行叠加,同时考虑水印图片的 alpha 通道,控制水印的透明度。

涉及的一些函数说明:

  1. cv2.putText()

    • 函数功能:在图像上绘制文本。
    • 参数:
      • image:要绘制文本的图像。
      • text:要绘制的文本内容。
      • org:文本的起始坐标,即文本左下角的坐标。
      • font:字体类型,默认为 cv2.FONT_HERSHEY_SIMPLEX
      • font_scale:字体缩放因子。
      • font_color:文本颜色,格式为 BGR。
      • thickness:文本线条粗细。
    • 返回值:无。
    • 注意事项:根据 org 参数确定文本的起始位置,确保文本不会超出图像范围。
  2. Array slicing (数组切片)

    • 函数功能:用于在图像上获取指定位置的子图像。
    • 参数:用于指定图像区域的坐标和大小。
    • 返回值:返回指定区域的子图像。
    • 注意事项:确保指定的区域不会超出图像范围。
  3. cv2.addWeighted()

    • 函数功能:对两个图像进行加权求和,实现图像叠加效果。
    • 参数:
      • src1:第一个输入图像。
      • alpha:第一个输入图像的权重。
      • src2:第二个输入图像。
      • beta:第二个输入图像的权重。
      • gamma:结果图像的亮度值,添加到加权和上。
    • 返回值:返回加权和后的图像。
    • 注意事项:通过调整 alphabeta 参数可以控制两个图像的显示比例,通过 gamma 参数可以调整结果图像的亮度。

三、简单图片添加水印效果案例实现简单步骤

1、编写代码

2、运行效果

3、具体代码

"""
简单图片添加水印效果
"""import cv2def add_watermark_text(image, text, position='bottom-right', x=None, y=None, font=cv2.FONT_HERSHEY_SIMPLEX,font_scale=1.0, font_color=(255, 255, 255), thickness=1):"""简单添加文字水印效果:param image::param text::param position::param x::param y::param font::param font_scale::param font_color::param thickness::return:"""# 复制原始图像,以免修改原始图像result = image.copy()# 确定水印文本的位置text_size, _ = cv2.getTextSize(text, font, font_scale, thickness)image_height, image_width = image.shape[:2]if position == 'top-left':text_position = (10, text_size[1] + 10)elif position == 'top-right':text_position = (image_width - text_size[0] - 10, text_size[1] + 10)elif position == 'bottom-left':text_position = (10, image_height - 10)elif position == 'center':text_position = ((image_width - text_size[0]) // 2, (image_height + text_size[1]) // 2)else:  # 默认为 'bottom-right'text_position = (image_width - text_size[0] - 10, image_height - 10)# 如果用户指定了位置,则使用用户指定的位置if x is not None and y is not None:text_position = (x, y)# 添加水印文本cv2.putText(result, text, text_position, font, font_scale, font_color, thickness)return resultdef add_watermark_image(image, watermark_image, position='bottom-right', x=None, y=None):"""简单添加图片水印效果:param image::param watermark_image::param position::param x::param y::return:"""# 复制原始图像,以免修改原始图像result = image.copy()# 确定水印图片的位置watermark_height, watermark_width = watermark_image.shape[:2]image_height, image_width = image.shape[:2]if position == 'top-left':watermark_position = (0, 0)elif position == 'top-right':watermark_position = (image_width - watermark_width, 0)elif position == 'bottom-left':watermark_position = (0, image_height - watermark_height)elif position == 'center':watermark_position = ((image_width - watermark_width) // 2, (image_height - watermark_height) // 2)else:  # 默认为 'bottom-right'watermark_position = (image_width - watermark_width, image_height - watermark_height)# 如果用户指定了位置,则使用用户指定的位置if x is not None and y is not None:watermark_position = (x, y)# 获取水印图片的 alpha 通道watermark_alpha = watermark_image[:, :, 3] / 255.0# 提取水印图片的 BGR 通道watermark_bgr = watermark_image[:, :, :3]# 将水印图片叠加到原始图像上for c in range(3):result[watermark_position[1]:watermark_position[1] + watermark_height,watermark_position[0]:watermark_position[0] + watermark_width, c] = \(1 - watermark_alpha) * result[watermark_position[1]:watermark_position[1] + watermark_height,watermark_position[0]:watermark_position[0] + watermark_width, c] + \watermark_alpha * watermark_bgr[:, :, c]return resultdef main():# 调用函数并指定输入图像、水印和输出图像文件路径input_image_path = "Images/DogFace.jpg"watermark_path = "Images/Watermark.png"output_image_path = "Images/DogFace_Watermark.jpg"image = cv2.imread(input_image_path)# 设置窗口属性,并显示图片cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)cv2.imshow('Dog', image)output_image = add_watermark_text(image, "Water mark", x=200, y=300, font_scale=2.0, thickness=2)# 保存处理后的图像# 设置窗口属性,并显示图片cv2.namedWindow("add_watermark_text", cv2.WINDOW_KEEPRATIO)cv2.imshow("add_watermark_text", output_image)watermark = cv2.imread(watermark_path, cv2.IMREAD_UNCHANGED)output_image = add_watermark_image(image, watermark, position="center")# 保存处理后的图像# 设置窗口属性,并显示图片cv2.namedWindow("add_watermark_image", cv2.WINDOW_KEEPRATIO)cv2.imshow("add_watermark_image", output_image)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == "__main__":main()

四、注意事项

1、确保水印文本位置不会超出图像范围,可以根据指定的位置参数调整水印的位置。

2、考虑水印图片的 alpha 通道,以防止水印添加后出现黑色边框或不透明度不一致的情况。

3、可以根据需要调整水印图片的显示位置和透明度参数。

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

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

相关文章

吴恩达机器学习笔记:第 7 周-12支持向量机(Support Vector Machines)12.4-12.6

目录 第 7 周 12、 支持向量机(Support Vector Machines)12.4 核函数 1 第 7 周 12、 支持向量机(Support Vector Machines) 12.4 核函数 1 回顾我们之前讨论过可以使用高级数的多项式模型来解决无法用直线进行分隔的分类 问题: 为了获得上图所示的判定边界&…

非线性特征曲线线性化插补器(CODESYS 完整ST代码)

1、如何利用博途PLC和信捷PLC实现非线性特征曲线的线性化可以参考下面文章链接: 非线性特征曲线线性化(插补功能块SCL源代码+C代码)_scl直线插补程序-CSDN博客文章浏览阅读382次。信捷PLC压力闭环控制应用(C语言完整PD、PID源代码)_RXXW_Dor的博客-CSDN博客闭环控制的系列文章…

C++ 封装

1.封装 cpp认为万事万物都可以封装 封装将属性和行为作为一个整体,表现生活中的事物。 将属性和行为加以权限控制。 语法: class 类名{ 访问权限: 属性或者行为 } //学生类 class Student { public:void setName(string name) {m_name name;}vo…

更改docker镜像下载地址

一.简介 使用指令 sudo docker info 查看本机的docker镜像下载地址为 由于本机的var文件空间不足,因此,想更改他的存储地址,如下 二.开始操作 1.停止Docker服务: 执行命令 sudo systemctl stop docker 以及 sudo systemctl s…

Linux Debian安装教程

Debian 是一个免费的开源操作系统,是最古老的 Linux 发行版之一,于 1993 年由 Ian Murdock 创建。它采用了自由软件协议,并且由志愿者社区维护和支持。Debian 的目标是创建一个稳定、安全且易于维护的操作系统,以自由软件为基础&a…

Python学习笔记 - 正则表达式

前言 正则表达式(Regular Expression,在代码中常简写为 regex、regexp、RE 或 re)是预先定义好的一个“规则字符串”,通过这个“规则字符串”可以匹配、查找、替换那些符合“规则”的文本,也就是说正则表达式针对的目标…

鸿蒙原生应用元服务-访问控制(权限)开发Stage模型向用户申请授权

一、向用户申请授权 当应用需要访问用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等,应该向用户请求授权。这需要使用 user_grant 类型权限。在此之前,应用需要进行权限校验,以判断当前…

【华为OD机试】围棋的气【C卷|100分】

题目描述 围棋棋盘由纵横各19条线垂直相交组成,棋盘上一共19 x 19 = 361 个交点, 对弈双方一方执白棋,一方执黑棋,落子时只能将棋子置于交点上。 “气”是围棋中很重要的一个概念,某个棋子有几口气,是指其上下左右方向四个相邻的交叉点中, 有几个交叉点没有棋子,由此可…

Ubuntu22.04搭建CLion C++开发环境

Ubuntu22.04搭建CLion C开发环境 文章目录 Ubuntu22.04搭建CLion C开发环境1.首先下载CLion2.配置c环境3.创建快捷方式Reference 1.首先下载CLion 进入官网https://www.jetbrains.com/clion/download/#sectionlinux 然后进入自己存放这个压缩包的路径中, sudo mkd…

算法打卡day46|动态规划篇14| Leetcode 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

算法题 Leetcode 1143.最长公共子序列 题目链接:1143.最长公共子序列 大佬视频讲解:1143.最长公共子序列视频讲解 个人思路 本题和718. 最长重复子数组很相像,思路差不多还是用动态规划。区别在于这题不要求是连续的了,但要有相对顺序 解…

k8s高可用集群部署介绍 -- 理论

部署官网参考文档 负载均衡参考 官网两种部署模式拓扑图和介绍 介绍两种高可用模式 堆叠 拓扑图如下(图片来自k8s官网): 特点:将etcd数据库作为控制平台的一员,由于etcd的共识算法,所以集群最少为3个&…

雪花算法改造: 兼容JS截短位数的53bit分布式ID生成器

一、基本介绍 雪花算法是一种生成分布式ID的算法。此种算法由Twitter创建,并应用于推文的ID。 一个SnowFlake有64位: • 符号位(1) :正数0,负数1。一般生成的ID 都为正数,所以默认为0. • 时…