LSBLeast Significant Bit),中文译名为最低有效位,是指一个二进制数字中的最低位。LSB算法的基本思想是用待嵌入的秘密信息取代载体图像数据的LSB,构成载密图像。又因为LSB对图像的外部特征影响很小,所以人难以用肉眼看出载密图像的变化。然而,人眼不仅对LSB位不可感知,对比LSB位更高的某些位同样不可感知,这就意味着这些更高的位同样可以用来嵌入秘密信息。同时,根据人类对绿色敏感,对蓝色不敏感的特点,我们还可以在绿色分量上嵌入更少的比特信息,在蓝色分量上嵌入更多的比特信息。嵌入比特信息的多少可以用(yr,yg,yb)来衡量。这三个值通常取(4,5,3)。

图像在matlab中表现为矩阵,矩阵的长即为图像的长,矩阵的宽即为图像的宽,图像中的每个像素点映射成矩阵中相应位置的元素,也就是数据。每个数据的大小为0~255,存于8bit的空间之内。rgb图像在matlab中表现为三层数据,对rgb图像的处理就是对着三层数据的处理传统lsb算法只在最低位嵌入数据,但是对于某些像素点,人类对某些高于lsb位的数据同样不能感知,这些位同样可以嵌入数据。其中,由于人类对rgb中的绿色敏感,而蓝色最不敏感,我们可以在蓝色分量中嵌入更多的数据。以上就是lsb拓展算法的原理。

%function firstNzreo
%第一个不是零的位置
function po=firstNzreo(y8,y7,y6,y5,y4,y3,y2,y1)
if            y8~=0  po=8;
elseif       y7~=0  po=7;
elseif       y6~=0  po=6;
elseif       y5~=0  po=5;
elseif       y4~=0  po=4;
elseif       y3~=0  po=3;
elseif       y2~=0  po=2;
else         po=1;end
%function dec2bin_z
%十进制转二进制
function [y8,y7,y6,y5,y4,y3,y2,y1]=dec2bin_z(dec)
y1=mod(dec,2); dec=(dec-y1)/2;
y2=mod(dec,2); dec=(dec-y2)/2;
y3=mod(dec,2); dec=(dec-y3)/2;
y4=mod(dec,2); dec=(dec-y4)/2;
y5=mod(dec,2); dec=(dec-y5)/2;
y6=mod(dec,2); dec=(dec-y6)/2;
y7=mod(dec,2); dec=(dec-y7)/2;
y8=mod(dec,2);
end
%function bin2dec_z
%二进制转十进制
function dec=bin2dec_z(y8,y7,y6,y5,y4,y3,y2,y1)dec=y1+2*y2+4*y3+8*y4+16*y5+32*y6+64*y7+128*y8;
end
function varargout = GUI(varargin)
clc;
% GUI MATLAB code for GUI.fig
%      GUI, by itself, creates a new GUI or raises the existing
%      singleton*.
%
%      H = GUI returns the handle to a new GUI or the handle to
%      the existing singleton*.
%
%      GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GUI.M with the given input arguments.
%
%      GUI('Property','Value',...) creates a new GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before GUI_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to GUI_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES% Edit the above text to modify the response to help GUI% Last Modified by GUIDE v2.5 15-Jun-2018 01:13:08% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...'gui_Singleton',  gui_Singleton, ...'gui_OpeningFcn', @GUI_OpeningFcn, ...'gui_OutputFcn',  @GUI_OutputFcn, ...'gui_LayoutFcn',  [] , ...'gui_Callback',   []);
if nargin && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});
endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
elsegui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT% --- Executes just before GUI is made visible.
function GUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to GUI (see VARARGIN)% Choose default command line output for GUI
handles.output = hObject;% Update handles structure
guidata(hObject, handles);% UIWAIT makes GUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);% --- Outputs from this function are returned to the command line.
function varargout = GUI_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)% Get default command line output from handles structure% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)%%关闭坐标轴显示axis off;
[filename_img pathname_img]=uigetfile({'*.bmp';'*.jpg';'*.*'},'选择载体图片');
str=[pathname_img filename_img];%拼接pathname和filename,形成完整路径名
img=imread(str);
set(handles.pushbutton1,'userdata',img);
axes(handles.axes1);%打开axes1的句柄,进行句柄操作
imshow(img);% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
axis off;
[filename_hide,pathname_hide] = uigetfile({'*.jpg';'*.bmp';'*.*'},'选择水印图片');
str1=[pathname_hide filename_hide];
imhide=imread(str1);
set(handles.pushbutton2,'userdata',imhide);
axes(handles.axes3);
imshow(imhide);% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
axis off;
img=get(findobj('tag','pushbutton1'),'userdata');%finfobj返回游戏值
imhide=get(findobj('tag','pushbutton2'),'userdata');
[m,n,h]=size(img);
[mhide,nhide]=size(imhide);
imgR=img(:,:,1);
imgG=img(:,:,2);
imgB=img(:,:,3);
imgRline=imgR(:);
imgGline=imgG(:);
imgBline=imgB(:);
imhideline=imhide(:);
yr=4;
yg=5;
yb=3;
y=zeros(1,8);imhidelinebin=zeros(mhide*nhide*8,1);
for ii=1:mhide*nhide[imhidelinebin(ii*8),imhidelinebin(ii*8-1),imhidelinebin(ii*8-2),imhidelinebin(ii*8-3),...imhidelinebin(ii*8-4),imhidelinebin(ii*8-5),imhidelinebin(ii*8-6),imhidelinebin(ii*8-7)]...=dec2bin_z(imhideline(ii));
end%开始嵌入
flag=0;
embedSum=0;
imgRlineNew=imgRline;%B
imgBlineNew=imgBline;
for ii=1:m*nif(flag==1)break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=dec2bin_z(imgBline(ii));
fn=firstNzreo(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));
embedNum=fn-yb;if embedNum>0for jj=1:embedNumembedSum=embedSum+1;if embedSum>mhide*nhide*8flag=1;break;endy(jj)=imhidelinebin(embedSum);endimgBlineNew(ii)=bin2dec_z(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));end
end%R
for ii=1:m*nif(flag==1)break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=dec2bin_z(imgRline(ii));
fn=firstNzreo(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));
embedNum=fn-yr;if embedNum>0for jj=1:embedNumembedSum=embedSum+1;if embedSum>mhide*nhide*8flag=1;break;endy(jj)=imhidelinebin(embedSum);endimgRlineNew(ii)=bin2dec_z(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));end
end
%G
imgGlineNew=imgGline;
for ii=1:m*nif(flag==1)break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=dec2bin_z(imgGline(ii));
fn=firstNzreo(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));
embedNum=fn-yg;if embedNum>0for jj=1:embedNumembedSum=embedSum+1;if embedSum>mhide*nhide*8flag=1;break;endy(jj)=imhidelinebin(embedSum);endimgGlineNew(ii)=bin2dec_z(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));end
end%嵌入完成,开始整合
imgNew=zeros(m,n,h);
imgR2=reshape(imgRlineNew,[m,n]);
imgG2=reshape(imgGlineNew,[m,n]);
imgB2=reshape(imgBlineNew,[m,n]);
imgNew(:,:,1)=imgR2;
imgNew(:,:,2)=imgG2;
imgNew(:,:,3)=imgB2;
axes(handles.axes4);
imshow(uint8(imgNew));
set(handles.pushbutton3,'userdata',imgNew);% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
[filename filepath]=uigetfile({'*.bmp';'*.*'},'打开载密图片');
str=[filepath filename];
Img=imread(str);
[m,n,Z]=size(Img);
%只有知道图片原来的形状,才能提取出完整的水印,
%秘钥就是水印图像的高和宽,比如高346,宽350,秘钥就是346350。
%str1=get(findobj('tag','handles.edit1'),'userdata');
str1=get(findobj('tag','edit1'),'userdata');
key=str1mhide=str2double([str1(1),str1(2),str1(3)]);%高
nhide=str2double([str1(4),str1(5),str1(6)]);%宽
Graylinebin=zeros(8*mhide*nhide,1);
%准备工作
yr=4;
yg=5;
yb=3;
ImgR=Img(:,:,1);
ImgG=Img(:,:,2);
ImgB=Img(:,:,3);
ImgRline=ImgR(:);
ImgGline=ImgG(:);
ImgBline=ImgB(:);% 信息提取
%只有知道图片原来的形状,才能提取出完整的水印。Imhidelinebin=zeros(8*mhide*nhide,1);
%准备工作flag=0;
extractSum=0;
embedNum=0;
y=zeros(8,1);%R
for ii=1:m*nif flag==1break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=dec2bin_z(ImgRline(ii));fn=firstNzreo(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNum=fn-yr;if embedNum>0for jj=1:embedNum;extractSum=extractSum+1; if extractSum>8*mhide*nhideflag=1;break;endImhidelinebin(extractSum)=y(jj);endend
end%G
for ii=1:m*nif flag==1break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=dec2bin_z(ImgGline(ii));fn=firstNzreo(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNum=fn-yg;if embedNum>0for jj=1:embedNum;extractSum=extractSum+1; if extractSum>8*mhide*nhideflag=1;break;endImhidelinebin(extractSum)=y(jj);endend
end%B
for ii=1:m*nif flag==1break;end[y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1)]=dec2bin_z(ImgBline(ii));fn=firstNzreo(y(8),y(7),y(6),y(5),y(4),y(3),y(2),y(1));embedNum=fn-yb;if embedNum>0for jj=1:embedNum;extractSum=extractSum+1; if extractSum>8*mhide*Hideflag=1;break;endImhidelinebin(extractSum)=y(jj);endend
end%在工作区看到embedSum跟extractSum相等,说明提取没有出错
%提取完毕,开始整合
Imhideline=zeros(mhide*nhide,1);
for ii=1:mhide*nhideImhideline(ii)=bin2dec_z(Imhidelinebin(ii*8),Imhidelinebin(ii*8-1),Imhidelinebin(ii*8-2),Imhidelinebin(ii*8-3),...Imhidelinebin(ii*8-4),Imhidelinebin(ii*8-5),Imhidelinebin(ii*8-6),Imhidelinebin(ii*8-7));
end
Imhide=reshape(Imhideline,[mhide,nhide]);
axis off;
axes(handles.axes5);
imshow(uint8(Imhide));% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)% --- Executes on mouse press over axes background.
function axes1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)imgNew=get(findobj('tag','pushbutton3'),'userdata');
[filename,filepath]=uiputfile({'*.bmp'},'保存文件');
str=[filepath,filename];
imwrite(uint8(imgNew),str);% --- Executes on button press in pushbutton7.
function pushbutton7_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)% --- Executes during object creation, after setting all properties.
function axes4_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate axes4% --- Executes on mouse press over axes background.
function axes3_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)function edit1_Callback(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double
set(handles.edit1,'userdata',get(handles.edit1,'String'));
key=get(handles.edit1,'userdata')% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor','white');
end% --- Executes on button press in pushbutton8.
function pushbutton8_Callback(hObject, eventdata, handles)
im1=get(findobj('tag','pushbutton1'),'userdata');
im2=get(findobj('tag','pushbutton3'),'userdata');
dif=abs(double(im1)-double(im2));
axes(handles.axes7);
imshow(dif);
% hObject    handle to pushbutton8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)function edit2_Callback(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of edit2 as text
%        str2double(get(hObject,'String')) returns contents of edit2 as a double% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor','white');
end

代码下载请到:https://download.csdn.net/download/momogir_air/10480027

参考资料:

谢建全, 阳春华. 大容量的信息隐藏算法[J]. 计算机工程, 2008, 34(8):167-169

辰空同学的CDSN博客





LSB算法的扩展延伸相关推荐

  1. 基于自动图像分割算法和扩展数据集深度学习的经济作物病害识别

    基于自动图像分割算法和扩展数据集深度学习的经济作物病害识别 1.作物病害识别出现的问题 实际应用中作物图像的复杂背景信息和训练数据不足会导致深度学习的错误识别. 2.研究内容 提出了一种基于自动图像分 ...

  2. 欧几里德算法及其扩展算法

     一.欧几里德算法 1.欧几里德算法概述: 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数.其计算原理依赖于下面的定理: gcd函数就是用来求(a,b)的最大公约数的. gcd函数的基 ...

  3. 实战28:数字图像可视化水印系统的设计与实现(LSB算法、DCT算法、随机间隔算法、区域校验位算法、图像降级算法、图像降级算法改进等6种数字水印算法的实现)

    基于数字图像的可视化水印系统按照水印算法的不同主要分为空间域水印和变换域水印两大类.空间域水印以 LSB 算法--最低有效位算法为代表,变换域水印以 DCT 算法--离散余弦变换算法为代表[10]. ...

  4. 欧几里德算法与扩展的欧几里德算法及乘法逆元

    欧几里德算法与扩展的欧几里德算法及乘法逆元 欧几里德算法 扩展的欧几里德算法 乘法逆元 以下提到的数都是整数. 欧几里德算法 欧几里德算法用于求解最大公倍数,也就是辗转相除法.其结论非常简洁,对任意整 ...

  5. 寻找一种易于理解的一致性算法(扩展版)

    最新内容最先更新在主站深入浅出区块链社区 原文链接:寻找一种易于理解的一致性算法(扩展版) 摘要 Raft 是一种为了管理复制日志的一致性算法.它提供了和 Paxos 算法相同的功能和性能,但是它的算 ...

  6. 欧几里德算法及其扩展

    欧几里德算法其实就是辗转相除法,求最大公因数. 具体做法是:用较大数除以较小数,再用所得的余数(第一余数)去除除数,再用所得的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止.最后的除数就 ...

  7. K-Means聚类算法以及扩展算法K-Modes、K-Prototype

    k-means聚类算法是一种简单易行,时间复杂度低的聚类算法,特别是针对大规模的数据集.但其只能处理数值属性限制了他的应用范围,它的具体算法步骤如下: 1.确立最终聚类处理得到簇的个数,如果有先验知识 ...

  8. 浅谈Manacher算法与扩展KMP之间的联系

    首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解,网上解法颇多,时间复杂度也不尽相同,这里列述几种常见的解法. 解法一   ...

  9. RAFT 寻找一种易于理解的一致性算法(扩展版)

    摘要 Raft 是一种为了管理复制日志的一致性算法.它提供了和 Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 不同,使得 Raft 算法更加容易理解并且更容易构建实际的系统.为了提 ...

  10. 欧几里德算法与扩展欧几里德算法

    欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd( ...

最新文章

  1. sharepoint中一些gridview的使用方法
  2. Eclipse自动代码补全
  3. CodeForces - 1537E2 Erase and Extend (Hard Version)(扩展KMP-比较两个前缀无限循环后的字典序大小)
  4. Win7系统中Cookie位置
  5. 推荐一个非常好的行为验证码开源项目!
  6. c语言在dos下执行bat文件,应用dos批处理文件经常用到的DOS常用命令
  7. “智企云中享“,首届SAP中国云大会召开
  8. python3 开发面试题(面向对象)6.6
  9. IPv4 和 IPv6 有什么区别
  10. 2019-05-18 操作系统概论
  11. 全国计算机统考在线模拟网站,全国计算机统考模拟试题
  12. 智慧城市大数据创新联盟落户高新区
  13. load west0479 matlab,matlab矩阵详解 - Matlab 资料库 视频 教程 讲义 代码 - 数学建模社区-数学中国...
  14. 计算机控制电子点火系控制电路分析,点火示波器的工作原理 用示波器诊断点火系故障方法...
  15. 浏览器的标签栏上网站的小图标的设置方式
  16. phpStudy安装教程
  17. 中国软件企业排名(不是绝对的)
  18. mysql sum契合_文化契合者为王。 这是在下一次开发人员面试中如何定位的方法。...
  19. CAD能打开PDF格式吗?这样做可以快速实现
  20. 华为 GaussDB 数据库十问

热门文章

  1. ubuntu18.04 虚拟机重启后变成只读模式,怎么恢复?
  2. 女程序员:秃头的富婆不好当
  3. Android计算器横屏,如何将华为手机的计算器横屏转换成竖屏
  4. 计算机网络pop3是什么意思,smtp服务器是什么 pop3服务器是什么?
  5. 怎样一次删除许多WPS word中的文本框(及其内容)?简单方法
  6. MSB3644 找不到 .NETFramework,Version=v4.7 的引用程序集。要解决此问题,请为此框架版本安装......
  7. 东南亚电商lazadashopee平台怎么开店,需要什么条件?
  8. u盘安全弹出有什么用?数据丢失还能恢复吗
  9. Fisher discrimination criterion (费舍尔判别准则)
  10. Matlab快速导入数据文件