效果图
猫映射(Cat映射),也称为Arnold映射,由俄国数学家弗拉基米尔·阿诺德(Vladimir Igorevich Arnold)提出,在Arnold授课的时候经常使用猫的图像作为例子,故称为“猫映射”。这是一种在有限区域内进行反复折叠、拉伸变换的混沌映射方法,一般应用于多媒体混沌加密中。
Arnold也算一种比较主要的置乱算法,算法由以下变换公式产生:
其中xn,yn表示变换前灰度图中像素的位置,xn+1,yn+1表示变换之后的像素位置,a,b为参数,n表示当前变换的次数,N为图像的长或宽(由于该算法只适用于长宽相等的图像,所以我们不讨论M不等于N的情况),mod为模运算。
有了正变换公式,我们还需要反变换公式。
公式如下:
两个变换矩阵正好是求逆的关系。
数字图像可以看为一个二维矩阵,经过Arnold变换之后图像的像素位置会重新排列,这样图像会显得杂乱无章,从而实现了对图像的置乱加密效果。
代码1:输入图片只能是灰度图,且长宽一样
clear all;
close all;
clc;
img=imread('3.jpg');%读取图片,相对路径,图像必须是正方形,否则不具备Arnold变换的条件,可进行拓延处理
imshow(img,[])
[h,w]=size(img);
%置乱与复原的共同参数,就相当于密码,有了这几个参数,图片就可以复原
n=10;%迭代次数
a=3;b=5;
N=h;%N代表图像宽高,宽高要一样
%置乱操作
imgn=zeros(h,w);
for i=1:n
for y=1:h
for x=1:w
xx=mod((x-1)+b*(y-1),N)+1; %mod(a,b)就是a除以b的余数
yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;
imgn(yy,xx)=img(y,x);
end
end
img=imgn;
end
figure;
imshow(imgn,[])%治乱后的图片
%复原
img=imgn;
for i=1:n
for y=1:h
for x=1:w
xx=mod((a*b+1)*(x-1)-b*(y-1),N)+1;
yy=mod(-a*(x-1)+(y-1),N)+1 ;
imgn(yy,xx)=img(y,x);
end
end
img=imgn;
end
figure
imshow(imgn,[])%复原的图片
代码2:基于代码1稍微修改了一下,但是本质一样的
和代码1区别:
1、加入保存置乱图片和读取置乱图片的功能。
2、支持彩色图片,但是复原后只能是灰度图。
3、支持长宽不一致图片读入,但是复原后会造成部分失真。
clear all;
close all;
clc;
img=imread('1.jpg');%读取图片,相对路径,图像必须是正方形,否则不具备Arnold变换的条件,可进行拓延处理
mysize=size(img);%当只有一个输出参数时,返回一个行向量,该行向量的第一个元素时矩阵的行数,第二个元素是矩阵的列数。
if numel(mysize)>2%如果是彩色图像
img=rgb2gray(img); %将彩色图像转换为灰度图像
fprintf("图像为彩色图");
end
imshow(img,[])
[h,w]=size(img);
if h>w
img = imresize(img, [w w]);
fprintf("图像长宽不一样,图像可能失真");
end
if h<w
img = imresize(img, [h h]);
fprintf("图像长宽不一样,图像可能失真");
end
[h,w]=size(img);
%置乱与复原的共同参数,就相当于密码,有了这几个参数,图片就可以复原
n=10;%迭代次数
a=3;b=5;
N=h;%N代表图像宽高,宽高要一样
%置乱操作
imgn=zeros(h,w);
for i=1:n
for y=1:h
for x=1:w
xx=mod((x-1)+b*(y-1),N)+1; %mod(a,b)就是a除以b的余数
yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;
imgn(yy,xx)=img(y,x);
end
end
img=imgn;
end
imgn = uint8(imgn);
figure
imshow(img,[])%治乱后的图片
imwrite(imgn,'zhiluan.jpg');
%复原
img2=imread('zhiluan.jpg');%读取图片
for i=1:n
for y=1:h
for x=1:w
xx=mod((a*b+1)*(x-1)-b*(y-1),N)+1;
yy=mod(-a*(x-1)+(y-1),N)+1 ;
imgn(yy,xx)=img2(y,x);
end
end
img2=imgn;
end
imgn = uint8(imgn);
figure
imshow(imgn,[])%复原的图片
imwrite(imgn,'fuyuan.jpg');