1. 实验类别

设计型实验:MATLAB设计并实现基于DCT的图像数字水印算法。

2. 实验目的

了解基于DCT的图像数字水印技术,掌握基于DCT系数关系的图像水印算法原理,设计并实现一种基于DCT的数字水印算法。

3. 实验条件

(1) Windows 2000或Windows Xp以上操作系统;

(2) MATLAB 6.5以上版本软件;

(3)图像文件

4. 实验原理

 基于DCT的图像数字水印

在信号的频域(变换域)中隐藏信息要比在时域中嵌入信息具有更好的鲁棒性。一幅图像经过时域到频域的变换后,可将待隐藏信息嵌入图像的显著区域,这种算法更具抗攻击能力,而且保持了人类感官的不可察觉性。常用的变换域方法有离散余弦变换、离散小波变换和离散傅立叶变换等。

本实验介绍一种提取秘密信息的时候不需要原始图像的盲水印算法,算法的思想是利用载体中两个特定的DCT系数的相对大小来表示隐藏的信息。首先载体图像分为8*8分块,进行二维DCT变换,分别选择其中约定的两个位置,比如用(u1,v1)和(u2,v2)代表所选定的两个系数的坐标。如果Bi(u1,v1)< Bi(u2,v2),代表隐藏1。如果Bi(u1,v1)> Bi(u2,v2),代表隐藏0。

提取的时候接收者对包含水印的图像文件进行二维DCT变换,比较每一块中约定位置的DCT系数值,根据其相对大小,如果Bi(u1,v1)< Bi(u2,v2),则提取1;如果Bi(u1,v1)> Bi(u2,v2),则提取0。最终得到隐藏信息的比特串,从而恢复出秘密信息。

在上述算法过程中,如果有一对系数大小相差非常少,往往难以保证携带图像在保存和传输的过程中以及提取秘密信息的过程中不发生变化。因此在实际的设计过程中,一般都是引入一个Alpha变量对系数的差值进行控制,将两个系数的差值放大,可以保证提取秘密信息的正确性。

1.DCT数字水印嵌入.m脚本代码:

clc;
clear all;
pic_path = input('请输入要嵌入水印的图片绝对路径(要加单引号):');
watermark_txt = input('请输入水印所在文件绝对路径(要加单引号):');
msgfid=fopen(watermark_txt,'r');  %打开秘密文件,读入秘密信息
[key,count]=fread(msgfid,'ubit1');
alpha=0.01;
block = 8;
fclose(msgfid);
[len,col]=size(key);
io=imread(pic_path);                   %读取载体彩色图像
io=double(io)/255;
output=io;
i1=io(:,:,1);                           %取图像的第1层来隐藏,彩色图像空间RGB三层
T=dctmtx(block);                            %生成一个8*8 DCT变换矩阵
DCTrgb=blkproc(i1,[block block],'P1*x*P2',T,T');% x就是每一个分成的8*8大小的块,P1*x*P2相当于像素块的处理函数(记为fun),p1=T p2=T’,也就是fun=p1*x*p2=T*x*T'的功能是进行离散余弦变换,T,T'就是前面函数fun参数
[row,col]=size(DCTrgb);
row=floor(row/block);
col=floor(col/block);
contents = row * col;                    %contents表示图像矩阵能嵌入的最大比特数
if count > contents
    disp('Warning: 图像容量无法嵌入所有水印信息! 按enter退出matlab!');
    pause;
    quit;
else
    disp(['该图像能嵌入的水印信息最大值为:',num2str(contents),' bits']);
end
%纵向顺序信息嵌入
cow1 = 5;
cow2 = 4;
column1 = 2;
column2 = 3;
key_counter = 1;
temp = 0;
round_counter = 0;
total_marked_bits = 0;
if mod(count,row) == 0
    round = floor(count/row); % round记录需要图像矩阵多少列来嵌入水印(这里以一个8*8矩阵为一个bit嵌入单元)
else
    round = floor(count/row)+1; % round记录需要图像矩阵多少列来嵌入水印(这里以一个8*8矩阵为一个bit嵌入单元)
end

for ii=1:1:round
    for jj=1:1:row
        if DCTrgb(cow1,column1) == DCTrgb(cow2,column2)
            DCTrgb(cow1,column1) = DCTrgb(cow1,column1) - 0.0002;
        end

        if key(key_counter,1) == 1
            if DCTrgb(cow1,column1) > DCTrgb(cow2,column2)
                temp =  DCTrgb(cow1,column1);
                DCTrgb(cow1,column1) = DCTrgb(cow2,column2);
                DCTrgb(cow2,column2) = temp;
                DCTrgb(cow1,column1) = DCTrgb(cow1,column1) - alpha;% 扩大差距
            else
                DCTrgb(cow1,column1) = DCTrgb(cow1,column1) - alpha;% 扩大差距
            end
        elseif key(key_counter,1) == 0
             if DCTrgb(cow1,column1) < DCTrgb(cow2,column2)
                temp = DCTrgb(cow1,column1);
                DCTrgb(cow1,column1) = DCTrgb(cow2,column2);
                DCTrgb(cow2,column2) = temp;
                DCTrgb(cow2,column2) = DCTrgb(cow2,column2) - alpha;% 扩大差距
            else
                DCTrgb(cow2,column2) = DCTrgb(cow2,column2) - alpha;% 扩大差距
             end
         else
             disp('BitValueError: key bit value is invalid , neither 0 nor 1 !');
             disp('按 enter 退出matlab.');
             pause;
             quit;
         end
         cow1 = cow1 + block;
         cow2 = cow2 + block;
         key_counter = key_counter + 1;
         total_marked_bits = total_marked_bits + 1;
         if key_counter > count
             break;
         end
     end   %内层for
     round_counter =  round_counter + 1;
     disp(['当前嵌入轮数 :', num2str(round_counter)]);
     if key_counter > count
         disp(['水印嵌入正常结束!共嵌入:',num2str(total_marked_bits),' bits']);
         break;
     end
     cow1 = 5;
     cow2 = 4;
     column1 = column1 + block;
     column2 = column2 + block;
 end %外层for
%将信息写回并保存
wi=blkproc(DCTrgb,[block block],'P1*x*P2',T',T);%对DCTrgb进行逆变换
output(:,:,1)=wi;
imwrite(output,'E:\new\dct_watermarked.bmp');
figure;
subplot(1,2,1);
imshow(pic_path);
title('原始图像');
subplot(1,2,2);
imshow('E:\new\dct_watermarked.bmp');
title('嵌入水印图像');

运行截图:

2.DCT水印提取脚本代码:

clc;
clear all;
watermarked_picpath = input('请输入待提取的dct水印图片绝对路径(要加单引号):');
watermarked_bits = input('请输入嵌入的水印比特数:');
i=imread(watermarked_picpath);
i=double(i)/255;
i1=i(:,:,1);
block = 8;
T=dctmtx(block);
DCTcheck=blkproc(i1,[block block],'P1*x*P2',T,T');%对图像分块进行DCT变换
key = zeros(watermarked_bits,1);
[row,col]=size(DCTcheck);
row=floor(row/block);
col=floor(col/block);
cow1 = 5;
cow2 = 4;
column1 = 2;
column2 = 3;
key_counter = 1;
round_counter = 0;
total_get_bits = 0;
if mod(watermarked_bits,row) == 0
    round = floor(watermarked_bits/row); % round记录需要图像矩阵多少列来嵌入水印(这里以一个8*8矩阵为一个bit嵌入单元)
else
    round = floor(watermarked_bits/row)+1; % round记录需要图像矩阵多少列来嵌入水印(这里以一个8*8矩阵为一个bit嵌入单元)
end
for ii=1:1:round
    for jj=1:1:row
         if DCTcheck(cow1,column1) <= DCTcheck(cow2,column2)
             key(key_counter,1) = 1;
         else
             key(key_counter,1) = 0;
         end
         total_get_bits = total_get_bits + 1;
         key_counter = key_counter + 1;
         if key_counter > watermarked_bits
             break;
         end
         cow1 = cow1 + block;
         cow2 = cow2 + block;
     end %内层for
     round_counter =  round_counter + 1;
     disp(['当前提取轮数 :', num2str(round_counter)]);
     if key_counter > watermarked_bits
          disp(['水印提取正常结束!共提取水印:',num2str(total_get_bits),' bits']);
          break;
     end
     cow1 = 5;
     cow2 = 4;
     column1 = column1 + block;
     column2 = column2 + block;
end %外层for

fid=fopen('E:\new\dct_watermark_msg.txt','wt');
fwrite(fid,key,'bit1');
fclose(fid);

提取水印信息与原信息对比:

DCT水印实验遇到的问题及要点:

1.该实验对象是彩色RGB图像,任需要提取一层进行嵌入.

2.该实验中对每个矩阵块中的固定2个像素值比较时要考虑相等的情况,如若相等嵌入时先将其中任意一个减小少量,然后再比较大小考虑是否要互换像素值;最后提取时理论上是不会出现2个像素值一样的情况,但实验发现可能出现相等的情况,if DCTcheck(cow1,column1) <= DCTcheck(cow2,column2)代码中若去掉等号则提取的水印信息不正确.至今没明白为什么?

上述脚本在matlab6.5能正确运行,若有不足欢迎指正;若有疑问鄙人也乐于为道友解答,欢迎留言!

欢迎加入QQ群:735472015,群内有VC,MFC,win32API,批处理,python学习资料干货喔

基于DCT的图片数字水印实验的更多相关文章

  1. 基于LSB的图像数字水印实验

    1. 实验类别 设计型实验:MATLAB设计并实现基于LSB的图像数字水印算法. 2. 实验目的 了解信息隐藏中最常用的LSB算法的特点,掌握LSB算法原理,设计并实现一种基于图像的LSB隐藏算法. ...

  2. 优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码)。

    在您阅读本文前,先需要告诉你的是:即使是本文优化过的算法,DCT去噪的计算量依旧很大,请不要向这个算法提出实时运行的苛刻要求. 言归正传,在IPOL网站中有一篇基于DCT的图像去噪文章,具体的链接地址 ...

  3. SSE图像算法优化系列二十一:基于DCT变换图像去噪算法的进一步优化(100W像素30ms)。

    在优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码) 一文中,我们曾经优化过基于DCT变换的图像去噪算法,在那文所提供的Demo中,处理一副1000*1000左右的灰度噪音图像耗时 ...

  4. 基于DCT系数的实时监控中运动目标检测

    本文的主要内容来自2009 Advanced Video and Signal Based Surveillance会议的一篇论文“Real-Time Moving Object Detection ...

  5. 基于纹理的图片检索及demo(未启动)

    基于纹理的图片检索及demo(未启动)

  6. 基于h5的图片无刷新上传(uploadifive)

    基于h5的图片无刷新上传(uploadifive) uploadifive简介 了解uploadify之前,首先了解来一下什么是uploadify,uploadfy官网,uploadify和uploa ...

  7. 基于jQuery的图片相册滑出放大插件

    今天给大家带来一款基于jQuery的图片相册滑出放大插件.点击相册图片,展示该图片.该插件适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗..效 ...

  8. 一款基于jQuery的图片场景标注提示弹窗特效

    今天给大家分享一款基于jQuery的图片场景标注提示弹窗特效,这款实例适合在图片上标注某个物件,单击弹出详情说明,兼容360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之 ...

  9. 基于jquery hover图片遮罩层滑动

    分享一款基于jquery hover图片遮罩层滑动.这是一款仿腾讯课堂的鼠标悬停经过图片遮罩透明层滑动效果.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div clas ...

随机推荐

  1. gulpfile配置

    /** * 只包含合并压缩混淆,监听服务 */// 引入gulp模块var gulp = require('gulp'); // 引入其他模块var less = require('gulp-less ...

  2. 简单的自动升级提示AutoUpdater

    看过网上“圣殿骑士”和其他人的升级做法,感觉不太适合几十M的小型软件. 之前用的一直都是clickonce,但是3年下来感觉弊端太多,比如安装不能选择文件夹.打包不全.版本等问题,于是决定另辟捷径. ...

  3. 【转】C# GDAL 配置

    共生成9个dll,如下图: 1.在程序中添加*_csharp.dll四个文件的引用: 2.将剩余的五个文件复制到程序的Debug文件夹中:(如果不复制这五个文件就会出现类似“OSGeo.GDAL.Gd ...

  4. 高精度定时器实现 z

    1背景Permalink .NET Framework 提供了四种定时器,然而其精度都不高(一般情况下 15ms 左右),难以满足一些场景下的需求. 在进行媒体播放.绘制动画.性能分析以及和硬件交互时 ...

  5. 对于char *s1 和 char s2[] 的认识

    对于char *s1 和 char s2[] 认识有误区(认为无区别),导致有时出现“难以理解”的错误. char *s1 = "hello"; char s2[] = " ...

  6. 用npm-run自动化任务(转)

    自动构建JavaScript有不少好工具.不过其实很少有人知道,npm run命令就能很好地完成这一任务,配置起来也很简单. script npm会在项目的package.json文件中寻找scrip ...

  7. ListView实现下拉刷新(一)建立头布局

    一.效果演示 ListView实现下拉刷新,是很常见的功能.下面是一个模拟的效果,如下图:                                   效果说明:当往下拉ListView的时候 ...

  8. hdu 3068 最长回文_Manacher模板

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/neng18/article/details/24269469 pid=3068" rel= ...

  9. 牛客网多校训练第一场 I - Substring(后缀数组 + 重复处理)

    链接: https://www.nowcoder.com/acm/contest/139/I 题意: 给出一个n(1≤n≤5e4)个字符的字符串s(si ∈ {a,b,c}),求最多可以从n*(n+1 ...

  10. BZOJ2005:[NOI2010]能量采集(莫比乌斯反演,欧拉函数)

    Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得 ...