图像在每个像素都有相应的颜色值,我们将像素上的颜色值进行放大,并相互重合叠加覆盖,隐藏图像原有的信息从而达到加密的效果。实际上,放大像素值,颜色值自然放大。放大的倍数越大,加密后的图像越不容易分辨出原有的信息。
%% 基于像素点RGB值放大加密
% 读取加密图像
a = imread('e:\image-code\liuyifei.jpg');
% size(a)函数:获取矩阵大小,返回矩阵行列数
% rand()函数:随机生成和a大小相同的矩阵并且乘以100,可理解为加密倍数
r = rand(size(a))*100;
% 将a转为双精度,因为rand()函数生成的r矩阵精度较高,a矩阵与r矩阵相乘,需要提高a矩阵的的精度
rgbd = im2double(a);
%% 矩阵点乘运算,实现rgb值的放大加密
rgbs = rgbd.*r;
%% 保存加密后的图像
% b = imwrite(rgbs,'E:\image-code\jiami001.jpg');
%% 矩阵点除运算,实现rgb值的缩小解密
rgbe = rgbs./r;
%% 显示图像
subplot(1,3,1);imshow(a);title('原图');
subplot(1,3,2);imshow(rgbs);title('加密后');
subplot(1,3,3);imshow(rgbe);title('解密后');
如果提示错误使用imwirte,参考这个博客
行列像素点置乱就是将图像的原始矩阵中的各行顺序打乱,再将各列顺序打乱。具体实现方法是用randsample(函数随机生成一个元素个数等于行数,每个元素不大于行数,且每个元素都不相同的整数序列,按照这个序列数字的排列方式将原图矩阵的各行重新排列。同理重新排列矩阵各列,而随机生成的整数数列即可作为密钥。比如有一个4行6列的矩阵,初始行顺序是(1, 2, 3, 4),生成的行随机数列为(2, 4, 3, 1),则重新排列时将矩阵的第1行置于第四行,依次类推,得到行加密后的图像,在行加密的基础上再用同样的方法进行列加密。一个图像的像素大小就是它的矩阵大小,由于-般图像的矩阵行数列数都比较多,因此可以用这样的加密方法来隐藏图像信息。
%% 基于行列像素点置乱加密
%% 读取图像
a = imread('E:\image-code\liuyifei.jpg');
% 显示原图
subplot(2,3,1);imshow(a);title('原图');
%% 获取原图信息
% 获取原图行列数
[M,N] = size(a);
% 随机生成M个不相同的不大于M的数
Rm = randsample(M,M)';
Mchange = [1:1:M;Rm];
% 随机生成N个不相同的不大于N的数
Rn = randsample(N,N)';
Nchange = [1:1:N;Rn];
%% 加密
% 打乱行顺序
a(Mchange(1,:),:) = a(Mchange(2,:),:); % 按照随机生成的Rm序列中的顺序对原图矩阵的行进行重新排列
subplot(2,3,2);imshow(a);title('行加密');
% 打乱列顺序
a(:,Nchange(1,:)) = a(:,Nchange(2,:)); % 按照随机生成的Rn序列中的顺序对原图矩阵的列进行重新排列
subplot(2,3,3);imshow(a);title('列加密');
%% 解密
% 恢复行顺序
a(Mchange(2,:),:) = a(Mchange(1,:),:); % 逆向还原
subplot(2,3,5);imshow(a);title('行解密');
% 恢复列顺序
a(:,Nchange(2,:)) = a(:,Nchange(1,:)); % 逆向还原
subplot(2,3,6);imshow(a);title('列解密');
灰度图片被看成是许多个由值在0~255之间的像素点组成的图像,255表示白色,0表示黑色,黑白之间存在256个灰度级。灰度置乱加密是对图像的灰度值进行一定的运算操作来打乱重置,以此隐藏原图的信息。该算法适用于灰度图像,在实际应用中可将彩色图像转化为灰度图像使用。
clear all;
clc;
%% 基于灰度置乱加密
%% 获取原始图像
L = imread('E:\image-code\jiemi002.bmp')
% 请使用灰度图像,如果是彩色图像,会丢失彩色信息!!!
subplot(1,3,1);imshow(L);title('原图');
[x,y] = size(L);
% 生成与原图大小相同的随机矩阵
gadd = fix(255*rand(x,y));
%% 灰度值置乱加密
for m=1:x
for n=1:y
L1(m,n)=0.1*L(m,n)+0.9*gadd(m,n);
end
end
subplot(1,3,2);imshow(L1);title('加密图片');
%% 逆向解密
%% 灰度值置乱加密
for m=1:x
for n=1:y
L2(m,n)=(L1(m,n)-0.9*gadd(m,n))/0.1;
end
end
subplot(1,3,3);imshow(L2);title('解密图片');
混沌序列加密的原理是将根据密钥按照特定的方式进行重新排列后的混沌序列叠加覆盖在原图序列信息上,这样重新排列后的信息进行传输的时候,在公共信道上的信号会以一种随机噪声的特点传输,这样的信号在网络中大量存在,攻击者不能确定这是属于加密信息还是无用信息,降低了加密后的图像被攻击的可能性。接收者接到加密后的信息后,按照提前预定好的方式重新排列混沌序列,并将其从加密序列中去除掉,在经过一定程度上的运算,恢复图像原始的图像序列信息,从而显示出原始的图像信息。其原理示意图如下:
clear all;
clc;
%% 处理图像信息
% 读取原图
l = imread('E:\image-code\liuyifei.jpg')
% 转换为灰度图像
x = rgb2gray(l);
% 显示原始图片
subplot(1,3,1);imshow(x);title('原始图片');
% 获取图像大小
[a,b,c] = size(l);
% 定义变量N并赋值
N = a*b;
%% 加密
%% 创建秘钥
% 用户输入加密密码
m(1) = input('请输入秘钥(0~1之间):');
% 提示信息
disp('加密中...');
% 进行N-1次循环产生序列密码
for i=1:N-1
m(i+1) = 4*m(i)-4*m(i)^2;
end
m = mod(1000*m,256);
% 转换为无符号整型
m = uint8(m);
n = 1;
for i=1:a
for j=1:b
% 将图像每一像素值与序列每一位进行异或运算
e(i,j)=bitxor(m(n),x(i,j));
n = n+1;
end
end
%% 显示加密后的图片
subplot(1,3,2);imshow(e);title('加密后图片');
%% 写入加密后的图片
imwrite(e,'E:\image-code\jiami002.bmp');
%% 解密
[a,b,c] = size(e);
N = a*b;
m(1) = input('请输入秘钥(0~1之间):');
disp('解密中...');
% 进行N-1次循环产生序列密码
for i=1:N-1
m(i+1) = 4*m(i)-4*m(i)^2;
end
m = mod(1000*m,256);
% 转换为无符号整型
m = uint8(m);
n = 1;
for i=1:a
for j=1:b
% 将图像每一像素值与序列每一位进行异或运算
o(i,j)=bitxor(m(n),x(i,j));
n = n+1;
end
end
%% 显示解密后的图片
subplot(1,3,3);imshow(o);title('解密后图片');
%% 写入解密后的图片
imwrite(o,'E:\image-code\jiemi002.bmp');