数字水印 | Arnold 变换的 Matlab 代码实现

🍍原文: 图像加密笔记之 Arnold 变换及 Matlab 代码实现

🍍写在前面: 在原文的基础上补全了代码。注意,Matlab 貌似是从 1 开始计数的,而非 0!



1 核心代码

A r n o l d \mathsf{Arnold} Arnold 变换的置乱代码如下:

img_new=zeros(h,w)  % h和w分别是原始图像的高度和宽度
for i=1:n  % n是置乱的轮数for y=1:hfor x=1:w           xx=mod((x-1)+b*(y-1),N)+1;  % a和b是可自行指定的参数yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;        img_new(yy,xx)=img(y,x);                endendimg=img_new;
end

A r n o l d \mathsf{Arnold} Arnold 变换的还原代码如下:

img=img_new;  % img_new是置乱后的图像
for i=1:nfor y=1:hfor x=1:w            xx=mod((a*b+1)*(x-1)-b*(y-1),N)+1;yy=mod(-a*(x-1)+(y-1),N)+1;img_new(yy,xx)=img(y,x);endendimg=img_new;
end

简而言之,置乱就是根据公式重新设置每个像素的位置,还原就是根据公式恢复每个像素原本的位置。



2 完整代码

补全后的代码如下,代码说明见后文:

close  all
X = imread('white_bear.jpg'); 
I = rgb2gray(X);
[h, w]=size(I);N = h; % 等于图片长度和宽度
a = 2; % 设置参数
b = 3; % 设置参数
n = 5; % n为置乱轮数% 置乱--------------------------------------------------
imagesArray = zeros(h, w, 3, n);
img = I;
img_new = zeros(h,w);
for i=1:nfor y=1:hfor x=1:w           xx=mod((x-1)+b*(y-1),N)+1;yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;        img_new(yy,xx)=img(y,x);endendimg = cat(3, img_new, img_new, img_new);imagesArray(:,:,:,i) = img;
endfigure('Name','置乱前后的图像')
subplot(2,3,1);imshow(I);title('原始图像','FontSize',12);for i=1:ntitleStr = ['置乱次数=', num2str(i)];subplot(2,3,1+i);imshow(uint8(imagesArray(:,:,:,i)));title(titleStr,'FontSize',12);
end% 还原--------------------------------------------------
imagesNewArray = zeros(h, w, 3, n);
imagesNewArray(:, :, :, 1) = imagesArray(:, :, :, n);
img = imagesArray(:, :, :, n);for i=2:n+1for y=1:hfor x=1:w            xx=mod((a*b+1)*(x-1)-b*(y-1),N)+1;yy=mod(-a*(x-1)+(y-1),N)+1;        img_new(yy,xx)=img(y,x);                   endendimg = cat(3, img_new, img_new, img_new);imagesNewArray(:,:,:,i) = img;
endfigure('Name','还原前后的图像')
for i=1:n+1titleStr = ['还原次数=', num2str(i-1)];subplot(2,3,i);imshow(uint8(imagesNewArray(:,:,:,i)));title(titleStr,'FontSize',12);
end


2.1 初始设置

close  all
X = imread('white_bear.jpg'); 
I = rgb2gray(X);
[h, w]=size(I);N = h; % 等于图片长度和宽度
a = 2; % 设置参数
b = 3; % 设置参数
n = 5; % n为置乱轮数
  • imread():读取原始图像。请根据自己的需求填写图像名;
  • rgb2gray():将原始图像转换为灰度图像;
  • size():获取原始图像的高度 h \mathsf{h} h 和宽度 w \mathsf{w} w
  • N = h:由于我的原始图像比例为 1 : 1 \mathsf{1:1} 1:1,因此填高度或宽度都行。


2.2 置乱操作

我在核心代码的基础上加入了一个数组和画图的代码。

img = I;
img_new = zeros(h, w);
imagesArray = zeros(h, w, 3, n);
  • i m g \mathsf{img} img 变量用于存放原始图像;
  • i m g _ n e w \mathsf{img\_new} img_new 的大小必须与 i m g \mathsf{img} img 的一致,否则无法赋值;
  • i m a g e s A r r a y \mathsf{imagesArray} imagesArray 数组的大小为 n \mathsf{n} n,所存放的变量大小为 h × w × 3 \mathsf{h\times w\times 3} h×w×3

i m a g e s A r r a y \mathsf{imagesArray} imagesArray 数组用于存储第 i i i 轮的置乱结果,即第 i i i 轮生成的 i m g _ n e w \mathsf{img\_new} img_new,它的大小是 h × w \mathsf{h\times w} h×w。后文会解释为什么还需要一个 3 \mathsf{3} 3

for i=1:nfor y=1:hfor x=1:w           xx=mod((x-1)+b*(y-1),N)+1;yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;        img_new(yy,xx)=img(y,x);endendimg = cat(3, img_new, img_new, img_new); % 将灰度图像的通道数变为3imagesArray(:, :, :, i) = img;
end

上述代码中,只有倒数第二行、第三行和核心代码的不一样。

  • cat(3,...):在第 3 \mathsf{3} 3 个维度上将 3 \mathsf{3} 3 i m g _ n e w \mathsf{img\_new} img_new 拼接起来;
  • imagesArray(:, :, :, i):将 i m g \mathsf{img} img 存入 i m a g e s A r r a y \mathsf{imagesArray} imagesArray 数组中;

说明:由于画图代码中的 i m s h o w \mathsf{imshow} imshow 函数要求输入值的大小为 M × N × 3 \mathsf{M\times N\times 3} M×N×3,因此我们需要把 i m g _ n e w \mathsf{img\_new} img_new 这一灰度图像的通道数变为 3 \mathsf{3} 3,即把 3 \mathsf{3} 3 i m g _ n e w \mathsf{img\_new} img_new 拼接起来。其中, i m g _ n e w \mathsf{img\_new} img_new 的大小是 M × N × 1 ( M = h , N = w ) \mathsf{M\times N\times 1\ (M=h,N=w)} M×N×1 (M=h,N=w)

figure('Name','置乱前后的图像')
subplot(2,3,1);imshow(I);title('原始图像','FontSize',12);for i=1:ntitleStr = ['置乱次数=', num2str(i)];subplot(2,3,1+i);imshow(uint8(imagesArray(:,:,:,i)));title(titleStr,'FontSize',12);
end
  • f o r \mathsf{for} for 循环前:绘制原始图像;
  • f o r \mathsf{for} for 循环内:绘制置乱 i i i 次后的图像。


2.3 还原操作

同样地,我在核心代码的基础上加入了一个数组和画图的代码。

img = imagesArray(:, :, :, n);
imagesNewArray = zeros(h, w, 3, n);
imagesNewArray(:, :, :, 1) = imagesArray(:, :, :, n);
  • i m g \mathsf{img} img 变量用于存放置乱 n n n 次后的结果;
  • i m a g e s N e w A r r a y \mathsf{imagesNewArray} imagesNewArray 数组用于存放还原 i i i 次后的结果;

i m a g e s N e w A r r a y \mathsf{imagesNewArray} imagesNewArray 数组中的元素与 i m a g e s A r r a y \mathsf{imagesArray} imagesArray 数组中的元素前后对应。后续代码逻辑与置乱操作同理,不再赘述。



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

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

相关文章

通过linux花里胡哨的控制台,学习linux基础命令

今天这个B我装定了! 前言命令集 开始1、cowsay (让牛说话,够无聊的,但牛说的话是你输入的,细思极恐!)Debian/Ubuntu 安装命令:RHEL/CentOS/Fedora 安装:运行解释 2、fort…

Windows离线安装snmp服务

打开1里面有教程 选择“管理” 启动,发现不行 再把2拷贝到: 在启动就可以了(查看服务:ctrlshiftEsc)

【ROS2】节点

文章目录 ROS2 节点示例:创建并运行成功一个节点1. 创建功能包2. 编写源文件、CMakeLists.txt、package.xml3. 编译功能包4. 设置环境变量5. 运行节点6. 查看节点 参考链接 ROS2 节点 机器人的每一项功能,都被称为是一个节点。 每个节点都是一个独立的…

ASP.NET一种多商家网络商店的设计与实现

摘 要 21世纪是网络的世纪,电子商务随之将成为主流商业模式,多商家网络商店系统就是一个C2C型的电子商务系统。本文详细论述了采用ASP.NET 2005 和 SQL Server 2000等技术实现的一个多商家网络商店的过程。论文首先阐述了本设计题目的选题意义、背景&a…

Swift 使用枚举协议CaseIterable遍历枚举所有值

在Swift中,可以使用.allCases属性来枚举一个符合CaseIterable协议的枚举的所有情况。使用不同的方法,如for-in循环,reduce,filter和map函数,你可以迭代一个枚举。 什么是CaseIterable协议? CaseIterable是…

香港虚拟主机哪里可以试用?用于企业建站的

香港虚拟主机适合个人、企业建站,包括外贸企业网站、个人博客网站、中小企业官网等,那么作为新手不知道哪家香港虚拟主机好用的时候,该如何找到可以试用的香港虚拟主机呢? 香港虚拟主机也称作香港空间、香港虚拟空间,…

【Unity】Unity项目转抖音小游戏(二)云数据库和云函数

业务需求,开始接触一下抖音小游戏相关的内容,开发过程中记录一下流程。 抖音云官方文档:https://developer.open-douyin.com/docs/resource/zh-CN/developer/tools/cloud/develop-guide/cloud-function-debug 1.开通抖音云环境 抖音云地址&a…

C++string 类的常用方法

string (构造函数) (1) default 构造长度为零字符的空字符串。 (2) copy 构造 str 的副本。 (3) substring 复制从字符位置 pos 开始并跨越 len 字符的 str 部分(如果任一 str 太短或 len 为 string::npos,则复制 str 的末尾…

代码随想录训练营Day30:动态规划2

1.62不同路径 dp[i][j]数组的定义:到达坐标(i,j)所需要的路径个数。递推公式:dp[i][j] dp[i-1][j]dp[i][j-1];//到达(i,j)的上一步只能是从上面到或者左边到初始化:对于…

Leaflet.canvaslabel在Ajax异步请求时bindPopup无效的解决办法

目录 前言 一、场景重现 1、遇到问题的代码 2、问题排查 二、通过实验验证猜想 1、排查LayerGroup和FeatureGroup 2、排查Leaflet.canvaslabel.js 三、柳暗花明又一村 1、点聚类的办法 2、歪打正着 总结 前言 在上一篇博客中介绍了基于SpringBoot的全国风景区WebGIS按…

Flutter 中的 Card 小部件:全面指南

Flutter 中的 Card 小部件:全面指南 在 Flutter 中,Card 是一个用于呈现内容的容器,它带有圆角边缘和阴影效果,常用于展示信息块,如用户头像、相册、笔记或任何需要突出显示的内容。Card 小部件提供了一种简单而直观的…

unity---常用API

1. Vector3:结构体由x、y、z这3个数值组成,表示一个向量 magnitude变量返回该向量的长度normalized变量返回 magnitude 为 1 时的该向量zero静态变量Vector3(0, 0, 0)one静态变量Vector3(1, 1, 1)forward静态变量Vector3(0, 0, 1)back静态变量Vector3(0…

Flutter 中的 Stack 小部件:全面指南

Flutter 中的 Stack 小部件:全面指南 在 Flutter 中,Stack 是一个用于叠加多个小部件的布局小部件。它允许你将多个小部件重叠放置,通过控制每个小部件的位置和大小,你可以创建出复杂的布局效果,如徽章图标、对话框、…

pandas DataFrame 常用遍历方法

在Pandas中,可以使用多种方法遍历DataFrame中的数据。以下是几种常见的方法: 基于索引遍历DataFrame的每一行。 基于行号遍历DataFrame的每一行, 该方式通过行号获取行数据信息,格式为Series,无法获取改行的index信息。 使用iterr…

1.8. 离散时间鞅-无界停时定理与随机游走

无界停时定理与随机游走 无界停时定理与随机游走1. 无界停时定理1.1. 一致可积1.2. 非一致可积2. 应用于随机游动-鞅方法2.1. 随机游走构造的鞅2.2. 对称简单随机游走无界停时定理与随机游走 1. 无界停时定理 本节给出一致可积下鞅的无界停时定理,说明一致可积下鞅的停止过程…

Agent AI智能体:未来社会的角色、发展与挑战

Agent AI智能体在未来社会中的角色、发展路径以及可能带来的挑战是一个非常值得关注的话题。让我们来深入探讨一下这些方面。 1. 角色与应用场景 Agent AI智能体是指具有自主决策能力和执行能力的人工智能系统,它们可以代表个人或组织执行各种任务和活动。在未来社…

大学课程中的算法java实现【学习算法】

大学课程中的算法java实现【学习算法】 前言前言推荐离散数学Warshall算法 P102可达性矩阵 P187欧拉图 Fleury算法 P201最小生成树 P234哈夫曼数 P240 数据结构与算法计算机操作系统最后 前言 这是陈旧已久的草稿2023-04-22 23:20:38 这是准备自己用java实现大学课程中所有遇…

免疫优化算法(Immune Optimization Algorithm)

注意:本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 ([www.aideeplearning.cn]) 算法背景 免疫算法是一种模拟生物免疫系统的智能优化算法。想象一下,当我们的身体遇到病毒或细菌侵袭时,免疫系统会启动…

mysql 事物

MySQL中的事务(Transaction)是一个确保数据完整性和一致性的重要概念。它将一组SQL操作捆绑在一起,当作一个单一的工作单元来执行。事务具备以下四个关键特性,即ACID特性: 原子性(Atomicity)&am…

DHCP原理

什么是DHCP DHCP (Dynamic Host Configuration Protocol,动态主机配置协议)是由Internet工作任务小组设计开发的,专门用于为TCP/IP网络中的计算机自动分配TCP/IP参数的协议,是一个应用层协议,使用UDP的67和68端口。 DHCP的前身是B…