第五章-数字水印-2-原理及实现

news2024/9/21 0:30:40

数字水印原理

根据之前图像获取位平面的操作可知,最低位位平面对整体图像的影响最小,因此数字水印的原理为在图像的最低有效位上嵌入隐藏信息,即在图像的最低位替换为数字水印位平面,完成数字的嵌入操作,对已嵌入数字水印的图片提取最低位位平面,即可得到数字水印和解密后的图像,因操作在最低位位平面,所以可以忽略对图像的影响。

数字水印制造

数字水印的实现基于上述原理的具体实现,首先准备需要嵌入数字水印的lena图(512*512)以及获取数字水印的原始图(512*512)。

数字水印的原始图是在纯白(255)背景上随便写的字,通过代码把数字水印原始图变成数字水印图。

大体步骤如下:

  1. 数字原始图片显示为灰度图
  2. 灰度图中把关键信息独立出来,具体为把背景色置为0(这里用的纯白背景255,实际可能是一定范围的颜色区间)
  3. 灰度图只有水印关键信息,把此信息的颜色值变为1,灰度图变为最低位平面,得到数字水印

代码如下:

import cv2 as cv
import numpy as np

# --------------------------制造数字水印
# step1 读取原始图
key = cv.imread("key.png", 0)
#  step2 得到数字水印灰度图 可以看到文字及背景白色
cv.imshow("key255", key)
# step3  之前提取位平面图的掩模操作,把白色255背景变成黑色0
key[key == 255] = 0
cv.imshow("key0", key)
# step4 再把文字变成1,这样就得到了数字水印
key[key > 0] = 1
cv.imshow("key", key)
cv.waitKey()
cv.destroyAllWindows()

运行效果如下:

数字水印嵌入及提取

理解了数字水印的原理再来分析数字的嵌入及提取就会觉得特别简单了。

  1. 先把数字水印生成好,看上面即可。
  2. 把载体图像的最低位位平面给处理掉,使用一个254的矩阵与载体图像做与运算即可。
  3. 数字水印加入到载体图像的最低位位平面即可,此时完成数字水印的嵌入。
  4. 生成一个全部为1的矩阵与载体图像做与运算从而得到最低位位平面,此时得到的就是水印。
  5. 嵌入数字水印的图像做减法运算即可得到丢失了最低位位平面的原始图像
  6. 此时水印只有1和0,再转为二值图显示数字水印的图像,显示完成即可。

具体实现如下:

import cv2 as cv
import numpy as np

# --------------------------制造数字水印
# step1 读取原始图
key = cv.imread("key.png", 0)
#  step2 得到数字水印灰度图 可以看到文字及背景白色
cv.imshow("key255", key)
# step3  之前提取位平面图的掩模操作,把白色255背景变成黑色0
key[key == 255] = 0
cv.imshow("key0", key)
# step4 再把文字变成1,这样就得到了数字水印
key[key > 0] = 1
cv.imshow("key", key)
# -----------------------嵌入水印过程
# step1 生成值全为254的模板
lena = cv.imread("lena.jpg", 0)
cv.imshow("lena", lena)
r, c = lena.shape
mask_254 = np.ones((r, c), dtype=np.uint8) * 254
# step2 用254模板把lena的最低位
lena_high_bit = cv.bitwise_and(lena, mask_254)

# step3 去掉最低位的lena嵌入数字水印 这一步用或运算也行
# lena_water = cv.bitwise_xor(lena_high_bit, key)
lena_water = lena_high_bit + key

cv.imshow("lena_water", lena_water)

# -----------------------提取水印过程
# step4 生成各全为1的模板,用来把数字水印提取出来
mask_1 = np.ones((r, c), dtype=np.uint8)
# step5 嵌入水印的图像与1模板做与运算,把水印提取出来
key_after = cv.bitwise_and(lena_water, mask_1)
# step6 嵌入水印的图像减去水印得到的就是失去最低位的"原图" 这一步也可以用254的模板做与运算
# mask_254 = np.ones((r, c), dtype=np.uint8) * 254
# lena_after = cv.bitwise_and(lena_water, mask_254)
lena_after = lena_water - key_after
cv.imshow("lena_after", lena_after)

# step7 把数字水印转化为二值图,直接显示出来
key_after[key_after > 0] = 255
cv.imshow("key_after", key_after)

cv.waitKey()
cv.destroyAllWindows()

运行效果如下:

总结:知道数字水印的原理整体实现起来就轻松多了,大体就是在图片的最低位加入数字水印,提取水印也就是把提取出已嵌入水印的图像的最低位位平面。后面的可视化水印及艺术文字大体就是对图像和数字水印图像的区域运算,不再做单独讨论。

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

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

相关文章

Jenkins+Python自动化测试持续集成详细教程(全网独家)

目录 一、前言 二、环境准备 三、创建Jenkins Job 四、编写Python自动化测试脚本 五、测试报告生成与展示 六、持续集成流程优化 七、实战演练 八、常见问题及解决方案 九、结论 一、前言 Jenkins是目前最为流行的CI/CD工具之一,它可以支持多种语言和技术…

如何使用ffmpeg给视频减震去抖

之前自己发过一些记录仪拍下来的画面,你们可能已经看过了,例如: 最适合骑行的罐装饮料 然而,自己这个骑行记录仪,仅仅是很低端的一款,防抖功能很差,远远比不了GoPro那些高端的户外运动记录仪&am…

使用PCL滤波器实现点云裁剪

主要目的就是根据已知的ROI区域,对点云进行裁剪。要么留下点云ROI区域,要么去除。 ROI区域一般都是一个矩形,即(x,y,width,height)。 那么封装的函数形式一般如下: pcl:…

《死锁》与《CAS ABA》问题

文章目录 什么是死锁常见死锁情况❗️死锁的必要条件❗️如何避免死锁呢?CASCAS中ABA问题解决ABA问题 什么是死锁 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象 。 常见死锁情况❗️ 1.一个线程一把…

Java-static那些事儿

static作为java中基础常用的关键字,通常用于修饰内部类,方法和变量和代码段,且具有以下特性: static修饰内部类时,该类属于静态内部类,其只能访问外部的静态变量和方法static修饰方法时,该方法…

ROS学习第三十七节——机器人运动控制以及里程计信息显示

https://download.csdn.net/download/qq_45685327/87719766 https://download.csdn.net/download/qq_45685327/87719873 gazebo 中已经可以正常显示机器人模型了,那么如何像在 rviz 中一样控制机器人运动呢?在此,需要涉及到ros中的组件: ros…

【mapbox+turf.js】WebGIS空间分析系列(1)

最近在想,自己一直使用webgis做的都是可视化的内容,缺少空间分析的功能。 所以吧,最近理一下使用mapbox turf来做一些基础的空间分析功能。 大概的思路是,获取目标图层(多个图层),然后选择空…

servlet(2)—javaEE

1.获取请求数据 1.1开发前端发请求 ajax封装代码 // 参数 args 是一个 JS 对象, 里面包含了以下属性 // method: 请求方法 // url: 请求路径 // body: 请求的正文数据 // contentType: 请求正文的格式 // callback: 处理响应的回调函数, 有两个参数, 响应正文和响应的状态码…

qt中使用 ui 文件进行界面设计

目录 1、创建 Qt 应用 ​2、项目创建成功 3、直接点击打开 mainwindow.ui 文件 4、随便从左边侧边栏拖拽一个空间到 界面设计区域 5、在右侧边栏右键点击 pushButton 控件,点击转到槽 6、根据实际需要选择对应的信号,我这里方便演示选择 clicked&a…

linux 信号量semget/semop/semctl

专栏内容:linux下并发编程个人主页:我的主页座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 目录 前言 概述 原理机制 接口说明 代码演示 结尾 前言 本专栏主要分享linux下并发编…

基于 多态 的职工管理系统(Staff Management System)

目录 一、管理系统需求 作用:管理公司内所有员工的信息 分类:要显示每位员工的编号、姓名、岗位与职责 具体实现的功能: 二、创建管理 类 三、各个接口函数 1、菜单展示功能 2、 选择功能 3、创建员工功能 ①普通员工employee ②经理…

【Web3.0大势所趋】我看到了互联网未来的模样

前言 Web3.0 是一个越来越受到关注的话题,它被认为将会带来天翻地覆的变化。本文我们一起来谈谈 Web3.0 的概念、特点和优势,并探讨它为什么如此重要和具有革命性的。 文章目录 前言Web3.0是什么Web3.0的技术Web3.0的优势总结 Web3.0是什么 Web3.0: 是下…

尚硅谷Kafka

Kafka 1.Kafka概述1.1 定义1.2 消息队列1.2.1 传统消息队列的应用场景1.2.2 消息队列的两种模式 1.3 kafka基础架构 2.快速入门2.1 kafka环境安装2.2 kafka命令行操作参数2.2.1 主题命令行操作 2.2.2 生产者命令行操作2.2.3 消费者命令行操作 3.Kafka 生产者3.1 生产者消息发送…

Vue3+Vite神器:按需引入自定义组件unplugin-vue-components

前言 我们做项目时,会封装大量的公共组件,如果我们每一个都去在maints里面引入,非常麻烦不说,代码也不优雅。所以更好的方法就是自动注册全局组件,在组件中直接使用就好。 一种方法是自己在components文件夹下新建in…

QML控件--MenuBar

文章目录 一、控件基本信息二、控件使用三、属性成员四、成员函数 一、控件基本信息 Import Statement:import QtQuick.Controls 1.4 Since:Qt 5.1 二、控件使用 MenuBar:是菜单栏,通常,菜单静态声明为菜单栏的子项&…

redis入门必会知识

Redis基础知识目录 5、sortedSet 文章目录 系列文章目录前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 一、redis是什么? Redis(Remote Dictionary Server ),即远程字典服务 ! 是一个开源的使用ANSI C语言编写…

【C++】——- 模板初阶介绍

前言: 在之前的学习中,我们已经把 C前期所需要用到的知识都给大家介绍了一遍。接下来,我们要学习的就是关于在C 中模板的基本知识,今天我带给大家的内容便是关于 模板初阶的介绍。 目录 (一) 泛型编程 &…

【Python_Opencv图像处理框架】图像形态学操作

写在前面 本篇文章是opencv学习的第三篇文章,主要讲解了图像的形态学有关操作,作为初学者,我尽己所能,但仍会存在疏漏的地方,希望各位看官不吝指正❤️ 写在中间 读完这篇文章后,相信您便能信手拈来下面图…

给照片换底色(python+opencv)

给照片换底色(pythonopencv) 本篇目录: 🦄 一、分析照片基本信息 🦄 二、方法一(遍历图像,将像素值点替换修改为指定颜色) 🦄 三、修改图片颜色方法二(先转…

MySQL数据库索引

目录 0.知识回顾 1.数据库约束 一.索引 1.什么是索引 2.为什么要使用索引(作用) 3.索引的使用场景 4.如何使用索引 1.查看索引 2.创建索引 3.修改索引 4.删除索引 5.索引的分类 1.使用场景不同 2.按列区分 3.按数据组织方式 二.索引的数据结构 1.HASH 2.二叉搜…