用OpenCV给图像加水印,为图像添加个性

news/2024/12/17 2:20:39/

一、引言

在数字时代,保护图片的版权和标识越来越重要。无论是企业的Logo,还是个人作品的水印,都可以有效地标记和保护图像内容。本篇博客将介绍如何使用OpenCV为图片添加水印或Logo。我们将通过简单的代码示例,帮助你快速掌握这一技术,让你的图片更加独特与专业。

二、实验原理

通过将原始图片转换成灰度图,并进行二值化处理,去除背景部分,得到一个类似掩膜的图像。然后将这个二值化图像与另一张图片中要添加水印的区域进行“与”运算,使得目标物体的形状出现在要添加水印的区域。最后,将得到的目标物体图像与要添加水印的区域进行相加,就完成了添加水印的操作。

三、实验代码

3.1 功能简介

用于对两个数组(通常是图像)进行按位与(bitwise AND)操作的函数。

cv2.bitwise_and(src1, src2, mask=None, dst=None)

3.2 参数详解

src1: 
第一个输入数组(图像),它可以是单通道或多通道的。

src2:
 第二个输入数组(图像),它必须与 src1 有相同的尺寸和类型,或者是可以与 src1 进行广播的数组。

mask: 
操作掩码,这是一个可选参数。如果提供,它必须是一个单通道的二进制数组(即只包含 0 和 255 的值)。在运算过程中,只有当掩码对应位置的值为 255 时,src1 和 src2 对应位置的像素才会进行按位与运算;否则,结果数组在该位置的像素值将被设置为 0。

dst: 
输出数组,这是一个可选参数。如果提供,运算结果将存储在这个数组中;如果未提供,函数将创建一个新的数组来存储结果。
 

3.3 功能简介

用于对两个数组(图像)进行逐元素相加操作的函数

cv2.add(src1, src2, dst=None, mask=None, dtype=None)

3.4 参数详解

src1: 
第一个输入数组(图像)。

src2: 
第二个输入数组(图像),它必须与 src1 有相同的尺寸和类型,或者可以与 src1 进行广播。

dst: 
输出数组,这是一个可选参数。如果提供,运算结果将存储在这个数组中;如果未提供,函数将创建一个新的数组来存储结果。

mask: 
操作掩码,这是一个可选参数。如果提供,它必须是一个单通道的二进制数组(只包含0和255的值,或者布尔数组)。在运算过程中,只有当掩码对应位置的值为255(或True)时,src1和src2对应位置的像素才会进行相加运算;否则,结果数组在该位置的像素值将保持不变(或者根据dtype参数可能被设置为其他值)。

dtype: 
输出数组的可选深度(数据类型),当两个输入数组具有相同深度时,这个值将被忽略。它可以是-1,此时输出数组和输入数组有相同的深度,或者它可以是cv2.CV_8U、cv2.CV_16U、cv2.CV_32F等,用于指定输出数组的数据类型。

3.5 代码实现

在奥特曼图片中添加水印

水印图片:

 原图:

import cv2# 输入两张图
img = cv2.imread("./dijia.jpg")
logo = cv2.imread("./logo.png")# 对logo图进行灰度化和二值化 得到白底的掩膜
logo_gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
_, logo_binary = cv2.threshold(logo_gray,70,255,cv2.THRESH_BINARY_INV)# 在原图中 选取和logo图同等大小的 你想插入logo的位置
ROI = img[310:310+logo.shape[0], 340:340+logo.shape[1]]# 将ROI和logo的掩膜进行位于运算
ROI_logo= cv2.bitwise_and(ROI,ROI,mask = logo_binary)# 将处理后的ROI区域 与 原始的logo 融合
img_logo = cv2.add(ROI_logo,logo)# 将融合后的图像 在要添加logo的原图中替换
img[310:310+logo.shape[0], 340:340+logo.shape[1]] = img_logocv2.imshow('image',img)
cv2.imshow('ROI_logo',ROI_logo)
cv2.waitKey(0)

四、实验现象

五、结语

通过本篇博客,我们一起探索了如何使用OpenCV为图片添加水印或Logo。虽然最后我给奥特曼的图片加了个水印,但这只是一个小小的示例。掌握了这个技巧,你可以将它应用到任何图片上,为你的作品增添个性与保护。希望你们在实践中收获更多,动手试试吧!


http://www.ppmy.cn/news/1555740.html

相关文章

Debezium OracleDefaultValueConverter 分析

Debezium OracleDefaultValueConverter 分析 目录 1. 概述2. 核心功能3. 类型映射4. 特殊处理5. 最佳实践6. 使用示例7. 总结1. 概述 OracleDefaultValueConverter 是 Debezium Oracle 连接器中负责处理列默认值转换的核心类。它主要用于将 Oracle 数据库中的列默认值转换为 …

Linux系统操作03|chmod、vim

上文: Linux系统操作02|基本命令-CSDN博客 目录 六、chmod:给文件设置权限 1、字母法 2、数字法(用的最多) 七、vim:代码编写和文本编辑 1、启动和退出 1️⃣启动 2️⃣退出 2、vim基本操作 六、chmod&#x…

基于单片机和测频法的频率计设计及proteus仿真

摘要: 传感器广泛应用在自动化测量中,该文利用 51 单片机 2 个 16 位定时器和测量频率中的测频法设计了测量方波的频率计,并用LCD1602 液晶显示频率、 proteus 仿真,测试结果表明设计思路正确、误差小。 关键词: 单片机;测频法;频率计; proteus 1 概述 传感器能感受到…

《Vue进阶教程》第七课:computed()函数详解(下)

往期内容: 《Vue零基础入门教程》合集(完结) 《Vue进阶教程》第一课:什么是组合式API 《Vue进阶教程》第二课:为什么提出组合式API 《Vue进阶教程》第三课:Vue响应式原理 《Vue进阶教程》第四课&#…

我在广州学 Mysql 系列之 数据“表”的基本操作

ℹ️大家好,我是😆练小杰,今天主要讲得是Mysql数据表的基本操作内容~~ 昨天讲了“Mysql 数据“库“的基本操作”~~ 想要了解更多🈶️MYSQL 数据库的命令行总结!!! “真相永远只有一个”——工藤…

【Redis】Redis 缓存更新策略

1. 更新策略三种方式 缓存更新是redis为了节约内存而设计出来的一个东西,主要是因为内存数据宝贵,当我们向redis插入太多数据,此时就可能会导致缓存中的数据过多,所以redis会对部分数据进行更新,或者把他叫为淘汰更合…

私有云dbPaaS为何被Gartner技术成熟度曲线标记为“废弃”?

当云计算席卷而来,基于云基础设施的数据库部署也改变了数据库。在传统的私有化部署(On-premises)和公有云部署(Public Cloud)之间,不断融合的混合IT(Mixed IT)形式成为最常见的企业级…

[计算机网络]IP地址推行的“书同文,车同轨”

硬件地址无法直接转换的故事 在很久很久以前,网络世界就像一个庞大的帝国,各个村落(网络)都有自己的语言(硬件地址)。每个村落都有自己的规则和习惯,村里的每户人家(设备&#xff0…