OpenCV图像上加数字水印示例

news2025/5/13 8:07:45

OpenCV计算机视觉开发实践:基于Qt C++ - 商品搜索 - 京东

14.1  基本概念

当今,生成式人工智能(Artificial Intelligence Generated Content,AIGC)的火爆引燃了数字水印,说实话数字水印并不是一项新的技术,但是这时候某些公司拿出来宣传一下特别应景,相应股票价格蹭蹭地涨。数字水印是什么呢,顾名思义,和我们在PDF中打的水印作用差不多,起到明确版权、防伪验真的作用。但是不同于传统肉眼可见的水印,数字水印也叫隐藏式水印,能够在人眼几乎无法察觉的情况下,将水印信息秘密嵌入到音频、图像或视频中去。数字水印除了减少对画质的影响外,有个重要的功能就是保护著作权,使得盗版者无法感知水印存在,让版权鉴定的溯源变得更轻松。

提到数字水印,有个经典案例经常被提到,阿里巴巴的一名员工擅自将网页截图外传,造成很大的恶劣影响,阿里巴巴利用数字水印,很快就定位到这名员工,这名员工还奇怪,发的时候我还特意留意图片上没有水印,怎么就能定位到我呢。可见数字水印的强大,数字水印于无形中发挥着强大作用。

数位水印(Digital Watermark),是指将特定的信息嵌入数字信号中,数字信号可能是音频、图片或是视频等。若要拷贝有数位水印的信号,所嵌入的信息也会一并被拷贝。数位水印可分为浮现式和隐藏式两种,前者是可被看见的水印(Visible Watermarking),其所包含的信息可在观看图片或视频时同时被看见。一般来说,浮现式的水印通常包含版权拥有者的名称或标志。

隐藏式的水印是以数字数据的方式加入音频、图片或视频中,但在一般的状况下无法被看见。隐藏式水印的重要应用之一是保护版权,期望能借此避免或阻止数字媒体未经授权的复制和拷贝。隐写术(Steganography)也是数位水印的一种应用,双方可利用隐藏在数字信号中的信息进行沟通。数字照片中的注释数据能记录照片拍摄的时间、使用的光圈和快门,甚至是相机的厂牌等信息,这也是数位水印的应用之一。某些文件格式可以包含这些称为metadata的额外信息。

本节将主要讨论基于OpenCV技术的图片数字水印技术。

14.1.1  数字水印的特点

数字水印是一种信息隐藏技术,它利用人体感官的限制,将数字信号,如图像、文字、符号、数字等一切可以作为标记、标识的信息与原始数据(如图像、音频、视频数据)紧密结合并隐藏其中,并可以经历一些不破坏源数据价值的操作而能保存下来。

一般地,数字水印应具有如下的基本特性:

(1)可证明性:水印应能为受到版权保护的信息产品的归属提供完全和可靠的证据。

(2)不可感知性:不可感知包含两方面的意思,一个指视觉上的不可感知性(对听觉也是同样的要求),即因嵌入水印导致图像的变化对观察者的视觉系统来讲应该是不可察觉的,最理想的情况是水印图像与原始图像在视觉上一模一样,这是绝大多数水印算法所应达到的要求;另一方面水印用统计方法也是不能恢复的,比如对于大量的用同样方法和水印处理过的信息产品,即使使用统计方法也无法提取水印或确定水印的存在。

(3)鲁棒性:鲁棒性即健壮性,它对水印而言极为重要。一个鲁棒性强的数字水印应该能够承受大量的、不同的物理和几何失真,包括有意的(如恶意攻击)或无意的(如图像压缩、滤波、扫描与复印、噪声污染、尺寸变化等)。但易碎水印技术恰恰与之相反,其鲁棒性很低,它所保护信息的微小变化都会引起水印被破坏。

14.1.2  图像数字水印

如果嵌入载体图像内的信息是秘密信息,就实现了信息隐藏;如果嵌入载体图像内的信息是版权信息,就能够实现版权认证;如果嵌入载体图像内的信息是身份信息,就可以实现数字签名,等等。所以,被嵌入载体图像内的信息也被称为数字水印信息。

14.1.3  数字水印原理

最低有效位(Least Significant Bit,LSB)指的是一个二进制数中的第0位(即最低位)。最低有效位信息隐藏指的是,将一个需要隐藏的二值图像信息嵌入载体图像的最低有效位,即将载体图像的最低有效位层替换为当前需要隐藏的二值图像,从而实现将二值图像隐藏的目的。由于二值图像处于载体图像的最低有效位上,所以对于载体图像的影响非常不明显,其具有较高的隐蔽性。

这种信息隐藏也被称为数字水印,通过该方式可以实现信息隐藏、版权认证、身份认证等功能。例如,如果嵌入载体图像内的信息是秘密信息,就实现了信息隐藏;如果嵌入载体图像内的信息是版权信息,就能够实现版权认证;如果嵌入载体图像内的信息是身份信息,就可以实现数字签名,等等。所以,被嵌入载体图像内的信息也被称为数字水印信息。

数字水印信息可以是文本、视频、音频等多种形式,这里我们仅讨论数字水印信息是二值图像的情况。

最低有效位水印的实现包含嵌入过程和提取过程,下面对具体的实现方法进行简单介绍,分别包含嵌入过程和提取过程。

14.1.4  嵌入过程

嵌入过程完成的操作是,将数字水印信息嵌入载体图像内,其主要步骤如下。

1)载体图像预处理

读取原始载体图像,并获取载体图像的行数M和列数N。

2)建立提取矩阵

建立一个M×N大小、元素值均为254的提取矩阵(数组),用来提取载体图像的高七位。

3)保留载体图像的高七位,将最低位置零

为了实现该操作,需要将载体图像与元素值均为254的提取矩阵进行按位与运算。将一个值在[0,255]之间的像素值P与数值254进行按位与运算,则会将像素值P的最低有效位置零,只保留其高七位。

4)水印图像处理

有些情况下需要对水印进行简单处理。例如,当水印图像为8位灰度图的二值图像时,就需要将其转换为二进制二值图像,以方便将其嵌入载体图像的最低位。

5)嵌入水印

将原始载体图像进行“保留高七位、最低位置零”的操作后,我们得到一幅新的图像,将新图像与水印图像进行按位或运算,就能实现将水印信息嵌入原始载体图像内的效果。

6)显示图像

完成上述处理后,分别显示原始载体图像、水印图像、含水印图像。

14.1.5  提取过程

提取过程将完成数字水印的提取,具体步骤如下。

1)含水印载体图像处理

读取包含水印的载体图像,获取含水印载体图像的大小M×N。

2)建立提取矩阵

定义一个与含水印载体图像等大小的值为1的矩阵(数组)作为提取矩阵。

3)提取水印信息

将含水印载体图像与提取矩阵进行按位与运算,提取水印信息。

4)计算去除水印后的载体图像

有时需要删除包含在水印载体图像内的水印信息。通过将含水印载体图像的最低有效位置零,即可实现删除水印信息。

5)显示图像

根据需要,分别显示提取出来的水印图像、删除水印信息的载体图像。

14.2  相关函数

用OpenCV来实现数字水印功能,需要使用一些位操作函数,我们需要先了解一下这些函数。

1. bitwise_and函数

bitwise_and函数是OpenCV中的位运算函数之一,用于对两幅二值图像进行按位“与”操作。具体来说,对于每个像素,将两幅输入图像相应位置的像素值分别进行按位“与”运算,输出的结果图像的对应像素值即为这两幅输入图像对应像素值的按位与结果。

cv2.bitwise_and() 函数的语法如下:

void bitwise_and(InputArray src1, InputArray src2,

OutputArray dst, InputArray mask = noArray());

其中,src1和src2表示要进行按位“与”操作的两幅输入图像;mask是可选参数,如果指定了掩膜,则只对掩膜对应位置的像素进行按位“与”操作。dst表示按位“与”运算的结果。

【例14.1】创建空白图像进行按位与操作

(1)打开Qt Creator,新建一个控制台项目,项目名称是test。

(2)在main.cpp中输入代码如下:

#include "opencv2/opencv.hpp"
using namespace cv;

int main()
{
    //空白图像创建
    Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
    Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);
    //在图像内添加矩阵
    rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0);
    rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);
    imshow("m1", m1);
    imshow("m2", m2);
    Mat dst;
    bitwise_and(m1, m2, dst); //进行与操作,结果存于dst中
    imshow("result", dst);
    waitKey();
    return 0;
}

通过bitwise_and函数我们得到与操作的结果dst,类似的,如果要进行或操作和异或操作,则只要调用bitwise_or(m1, m2, dst);和bitwise_xor(m1, m2, dst);即可。

运行程序,运行结果如图14-1所示。

图14-1

再看个示例,对现有图片进行按位与操作,代码如下:

【例14.2】对现成图像进行按位与操作

(1)打开Qt Creator,新建一个控制台项目,项目名称是test。

(2)在main.py中输入代码如下:

#include "opencv2/opencv.hpp"
using namespace cv;

int main()
{
    Mat dog,cat,img_and;
    resize(imread("cat.png"),cat, Size(400, 360));
    resize(imread("dog.png"),dog, Size(400, 360));
    bitwise_and(cat,dog,img_and); //与运算 1 & 1 = 1, 其它为0
    imshow("result",img_and);
    waitKey(0);
    return 0;
}

运行结果如图14-2所示。

图14-2

可以看出,与运算结果最终会变小,最后的图像也会偏暗。

2. bitwise_or函数

在OpenCV中进行或运算使用bitwise_or函数,声明如下:

void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray());

其中输入参数src1和src2可为灰度图或彩色图,src1和src2大小需一样;输出参数dst存放或运算的结果,尺寸和类型与src保持一致;掩膜mask可通俗理解为一个遮罩,只对mask设定的有效区域进行操作。

或运算 0 | 0 = 0,其他情况为1,下面将猫和狗图片进行或运算。

【例14.3】对现成图像进行按位或操作

(1)打开Qt Creator,新建一个控制台项目,项目名称是test。

(2)在main.cpp中输入代码如下:

#include "opencv2/opencv.hpp"
using namespace cv;

int main()
{
    Mat dog,cat,img_and;
    resize(imread("cat.png"),cat, Size(400, 360));
    resize(imread("dog.png"),dog, Size(400, 360));
    bitwise_or(cat,dog,img_and); //或运算 1 & 1 = 1, 其它为0
    imshow("result",img_and);
    waitKey(0);
    return 0;
}

运行结果如图14-3所示。

图14-3

可以看出,或运算最终结果会变大,最后的图像也就偏亮了。

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

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

相关文章

Python爬虫从入门到实战详细版教程Char01:爬虫基础与核心技术

1.1 什么是网络爬虫? 1.1.1 定义与分类 网络爬虫:互联网世界的“信息捕手” 网络爬虫(Web Crawler),又称网络蜘蛛或网络机器人,是一种通过预设规则自动访问网页、提取数据的程序系统。从技术视角看,其核心任务是通过模拟浏览器行为向目标服务器发起请求,解析网页内容…

Day-1 漏洞攻击实战

实训任务1 漏洞攻击实战一 使用 御剑 得到网站后台地址 数据库登录与日志配置​​ 使用默认密码 root:root 登录phpMyAdmin,执行 SHOW VARIABLES LIKE general% 查看日志状态。 开启日志功能:set global general_log "ON";(配图&…

AOSP Android14 Launcher3——RecentsView最近任务数据加载

最近任务是Launcher中的一个重要的功能,显示用户最近使用的应用,并可以快速切换到其中的应用;用户可以通过底部上滑停顿进入最近任务,也可以在第三方应用底部上滑进最近任务。 这两种场景之前的博客也介绍过,本文就不…

基于深度学习的校园食堂菜品智能结算系统

校园食堂菜品智能结算系统说明文档 1. 系统概述 本系统是一款基于YOLO深度学习算法的校园食堂菜品智能结算平台,旨在通过计算机视觉技术实现食堂菜品的自动识别与结算,提高结算效率,减少人工成本,优化用户体验。系统采用PyQt5框…

【UniApp】Vue2 scss 预编译器默认已由 node-sass 更换为 dart-sass

从 HBuilderX 4.56 ,vue2 项目也将默认使用 dart-sass 预编译器。 vue2开发者sass预处理注意: sass的预处理器,早年使用node-sass,也就是vue2最初默认的编译器。 sass官方推出了dart-sass来替代。node-sass已经停维很久了。 另…

AI 硬件定制:开启智能新时代的钥匙

AI 硬件定制:开启智能新时代的钥匙 在科技飞速发展的当下,人工智能(AI)已不再是遥不可及的概念,它正以惊人的速度融入我们生活的方方面面。从智能手机中的语音助手,到工厂里的自动化生产线,AI 的身影无处不在。而在这股 AI 浪潮中,AI 硬件定制正逐渐崭露头角,成为推动…

SpringBoot中配置文件的加载顺序

下面的优先级由高到低 命令行参数java系统属性java系统环境变量外部config文件夹的application-{profile}.ym文件外部的application-{profile}.ym文件内部config文件夹的application-{profile}.ym文件内部的application-{profile}.ym文件外部config文件夹的application.ym文件外…

hooker frida版just_trust_me.js 2025升级 支持boringssl unpinning

曾几何时,我翻版了 Xposed 的 just_trust_me.apk, just_trust_me.js 脚本仿佛是一张通行证,让我们在 SSL Pinning 的高墙前轻松穿越。 但时代变了。BoringSSL、Cronet、静态 inline hook、动态 verify callback……一切都变得更加隐蔽和棘手…

React Article模块

实现基础文章发布 安装富文本编辑器 使用useEffect钩子函数获取到channelList,对channelList函数进行一个遍历 渲染到option 实现表单校验 1给Form组件绑定onFinish()函数 拼接表单数据 上传封面 onChange函数获得的参数

机器学习第二篇 多变量线性回归

数据集:世界幸福指数数据集中的变量有幸福指数排名、国家/地区、幸福指数得分、人均国内生产总值、健康预期寿命、自由权、社会支持、慷慨程度、清廉指数。我们选择GDP per Capita和Freedom,来预测幸福指数得分。 文件一:linear,…

C语言对n进制的处理

先看一道题目: 从键盘获取一个正整数,如果把它转为16进制的数字,那么它是一个几位数呢?如果把它转为28进制又是一个几位数呢? 在讲这个题目之前,我们先要了解进制转换 什么是进制转换? 简单来说,进制就是数位的表示方法。 十进制(常用&am…

Ubuntu数据连接访问崩溃问题

目录 一、分析问题 1、崩溃问题本地调试gdb调试: 二、解决问题 1. 停止 MySQL 服务 2. 卸载 MySQL 相关包 3. 删除 MySQL 数据目录 4. 清理依赖和缓存 5.重新安装mysql数据库 6.创建程序需要的数据库 三、验证 1、动态库更新了 2、头文件更新了 3、重新…

Spark-Streaming简介和核心编程

Spark-Streaming简介 概述:用于流式数据处理,支持Kafka、Flume等多种数据输入源,可使用Spark原语运算,结果能保存到HDFS、数据库等。它以DStream(离散化流)为抽象表示,是RDD在实时场景的封装&am…

Docker 快速入门教程

1. Docker 基本概念 镜像(Image): 只读模板,包含创建容器的指令 容器(Container): 镜像的运行实例 Dockerfile: 用于构建镜像的文本文件 仓库(Repository): 存放镜像的地方(如Docker Hub) 2. 安装Docker 根据你的操作系统选择安装方式:…

【锂电池SOH估计】BP神经网络锂电池健康状态估计,锂电池SOH估计(Matlab完整源码和数据)

目录 效果一览程序获取程序内容研究内容基于BP神经网络的锂电池健康状态估计研究摘要关键词1. 引言1.1 研究背景1.2 研究意义1.3 研究目标2. 文献综述2.1 锂电池SOH估计理论基础2.2 传统SOH估计方法2.3 基于BP神经网络的SOH估计研究进展2.4 研究空白与创新点3. BP神经网络原理3…

Python常用的第三方模块之二【openpyxl库】读写Excel文件

openpyxl库模块是用于处理Microsoft Excel文件的第三方库,可以对Excel文件中的数据进行写入和读取。 weather.pyimport reimport requests#定义函数 def get_html():urlhttps://www.weather.com.cn/weather1d/101210101.shtml #爬虫打开浏览器上的网页resprequests.…

成熟软件项目解决方案:360°全景影像显控软件系统

​若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/147425300 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、Open…

前端开发核心知识详解:Vue2、JavaScript 与 CSS

一、Vue2 核心知识点 1. Vue2 的双向绑定原理 Vue2 实现双向绑定主要依赖数据劫持与发布 - 订阅者模式。 利用Object.defineProperty方法对数据对象的属性进行劫持,为每个属性定义getter和setter。getter用于收集依赖,当视图中使用到该属性时&#xf…

JDK安装超详细步骤

🔥【JDK安装超详细步骤】 文章目录 🔥【JDK安装超详细步骤】1. 卸载系统自带的旧版JDK2. 安装JDK113. 验证安装是否成功4. 常见问题4.1 执行java -version提示命令未找到? 1. 卸载系统自带的旧版JDK 查询已安装的OpenJDK包。 rpm -qa | gre…

39.剖析无处不在的数据结构

数据结构是计算机中组织和存储数据的特定方式,它的目的是方便且高效地对数据进行访问和修改。数据结构表述了数据之间的关系,以及操作数据的一系列方法。数据又是程序的基本单元,因此无论是哪种语言、哪种领域,都离不开数据结构&a…