基于鲁棒性的数字水印的嵌入与提取

2023-10-23 17:48

本文主要是介绍基于鲁棒性的数字水印的嵌入与提取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数字水印技术(Digital Watermarking)是通过一定的算法将一些标志性信息直接嵌入到多媒体内容当中,但不影响原来内容的价值和使用,并且不能被人的感知系统察觉或者注意到,只有通过专门的检测器或者阅读器才能提取。如图1所示:左上角是要嵌入的水印,右上角是宿主图像,左下角是嵌入水印之后的图像。


图1   (1)水印  (2)原始宿主图像 (3)嵌入水印之后的宿主图像

数字水印常见的分类:

(1)    根据数字水印是否可见分为:可见水印、不可见水印。

(2)    根据数字水印的作用可以分为:鲁棒性水印、脆弱性水印、半脆弱性水印。

(3)    根据水印实现的方法分为:时(空)域水印、频域数字水印。

数字水印系统的组成:嵌入和提取。

数字水印嵌入的一般过程如图2所示:


图2 数字水印嵌入的一般过程

数字水印提取的一般过程如图3所示:


图3 数字水印提取的一般方法

基于DCT的的鲁棒性水印嵌入过程如图4所示:


图4 基于DCT的的鲁棒性水印嵌入

 

 

 


水印的提取步骤




function [snr , watermarked_image_int] = water_mark1(coypright,cover_object,k,blocksize)
if nargin<4coypright=[ 'coypright.bmp'];  %水印cover_object = ['len_std__.jpg'];%原图片k = 20;%设置水印强度blocksize = 8;  %设置图像的分块大小为blocksize*blocksize;
end
midband = [0 0 0 1 1 1 1 0 ;0 0 1 1 1 1 0 0 ;0 1 1 1 1 0 0 0 ;1 1 1 1 0 0 0 0 ;1 1 1 0 0 0 0 0 ;1 1 0 0 0 0 0 0 ;1 0 0 0 0 0 0 0 ;0 0 0 0 0 0 0 0 ;];
message = imread(coypright);%为什么要将读入的图像转换为双精度呢
subplot(2,2,1);imshow(message);%显示水印
[Mm,Nm] = size(message);%计算水印的大小   Mm=24;Nm=64;
n = Mm*Nm;
message = reshape(message,1,n);
cover_object =  imread(cover_object)  ;%读入宿主图片并且将其转换成双精度
Mc = size(cover_object,1);  Nc = size(cover_object,2);
c = Mc/blocksize;   d = Nc/blocksize;   m=c*d;%计算图像划分的图像块
%计算宿主图像每一块的方差
xx =1;
for i=1:cfor j=1:dpjhd(xx) = sum( sum( cover_object(1+(i-1)*8:i*8 ,1+(j-1)*8:j*8 )))/64;fc(xx) = sum( sum( (cover_object(1+(i-1)*8:i*8 ,1+(j-1)*8:j*8 )- pjhd(xx)).^2))/64 ;xx = xx+1;end      
end
%取出方差最大的前n块   
[A,B] = sort(fc);    %B = A( (c*d-n+1) : (c*d) );%因为A中是从小到大排序了
p = B( (c*d-n+1) : (c*d) );%因为A中是从小到大排序了
%将水印信息嵌入到方差最大的前n块fc_o = ones(1,c*d);   %1是白色的fc_o(p) = message;
message_vetot = fc_o;
watermarked_image = cover_object;
rand('state',7);%设置随机数生成器状态,作为系统密钥
%根据当前的随机数生成器生成 0 1 的伪随机数
pn_sequence_zero = round(rand(1,sum(sum(midband))));
%嵌入水印
x = 1;y=1;
for kk=1:m%分块DCT变换a = cover_object(y:y+blocksize-1,x:x+blocksize-1);dct_block = dct2(a);ll=1;if message_vetot(kk) == 0   %这个块里应该嵌入水印for ii=1:blocksizefor jj=1:blocksizeif(midband(jj,ii) == 1)dct_block(jj,ii) = dct_block(jj,ii)+k*pn_sequence_zero(ll);ll = ll+1;endendendend%分块DCT反变换watermarked_image(y:y+blocksize-1,x:x+blocksize-1) = round(idct2(dct_block));b = idct2(dct_block);%换行if x+blocksize>=Ncx = 1;y = y+blocksize;elsex = x+blocksize;end
end
watermarked_image_int = uint8(watermarked_image);%生成并输出嵌入水印后的图像
imwrite(watermarked_image_int,'dct2_watermarked.bmp','bmp');
subplot(2,2,2);imshow(cover_object);%显示原来图像 
subplot(2,2,3);imshow(watermarked_image_int,[]);%显示嵌入后的图像
%显示峰值信噪比
xsz = 255*255*Mc*Nc/sum ( sum( (cover_object-watermarked_image).^2 ));
psnr = 10*log10(xsz);
snr = psnr(:,:,1); 
fprintf('信噪比是 %f',snr);
end

function [sim ,message]=water_mark2(cover_object,watermarked_image,orig_watermark,blocksize)
if nargin<4cover_object = ['len_std__.jpg'];watermarked_image =['dct2_watermarked.bmp'];orig_watermark = ['coypright.bmp'];blocksize = 8;
endmidband = [0 0 0 1 1 1 1 0 ;0 0 1 1 1 1 0 0 ;0 1 1 1 1 0 0 0 ;1 1 1 1 0 0 0 0 ;1 1 1 0 0 0 0 0 ;1 1 0 0 0 0 0 0 ;1 0 0 0 0 0 0 0 ;0 0 0 0 0 0 0 0 ;];
cover_object = imread(cover_object)  ;%读入原宿主图像
watermarked_image = imread(watermarked_image);%读入待检测的图像
Mw = size(watermarked_image,1);Nw = size(watermarked_image,2);
c = Mw/blocksize;  d = Nw/blocksize;  m = c*d;
orig_watermark = double(imread(orig_watermark));%读入水印图像
Mo = size(orig_watermark,1);    No = size(orig_watermark,2);   n=Mo*No;
rand('state',7);%设置随机数生成器状态,作为系统密钥
%根据当前的随机数生成器生成 0 1 的伪随机数
pn_sequence_zeros = round(rand(1,sum(sum(midband))));
%提取水印x = 1;  y = 1;
for kk=1:mdct_block1 = dct2(watermarked_image(y:y+blocksize-1, x:x+blocksize-1));dct_block2 = dct2(cover_object(y:y+blocksize-1, x:x+blocksize-1));ll = 1;for ii=1:blocksizefor jj=1:blocksizeif (midband(jj,ii) == 1)sequence(ll) = dct_block1(jj,ii) - dct_block2(jj,ii);ll = ll+1;endendend%计算两个序列的相关性if sequence == 0  %没有嵌入信息,相关性就比较大correlation(kk) = 1;elsecorrelation(kk) = corr2(pn_sequence_zeros,sequence);end%换行if x+blocksize>=Nwx=1;  y=y+blocksize;elsex = x+blocksize;end
end%相关性大于0.5没有嵌入内容 ,小于0.5则表示曾经被嵌入
for kk=1:mif correlation(kk) == 1   %相关性比较大message_vector(kk) = 1;%没有嵌入信息elsemessage_vector(kk)=0;  %被嵌入了  1很多难道都被嵌入了吗????end
end
%计算原始图像的方差
xx =1;
for i=1:cfor j=1:dpjhd(xx) = sum( sum( cover_object(1+(i-1)*8:i*8 ,1+(j-1)*8:j*8 )))/64;fc(xx) = sum( sum( (cover_object(1+(i-1)*8:i*8 ,1+(j-1)*8:j*8 )- pjhd(xx)).^2))/64 ;xx = xx+1;end
end
%取出方差最大的前n块
A = sort(fc);  B=A((c*d-n+1):c*d);
%根据原始图像方差最大的前n块将水印提取出来
fc_o = ones(1,n); %1是白色的
H2=[];
for g=1:nfor h=1:c*dif( B(g) == fc(h))fc_o(g)= message_vector(h);break;endend
end
message_vector = fc_o;
%重组嵌入的图像
message = reshape(message_vector(1:Mo*No),Mo,No);
%计算提取的水印和原始水印的相似度
sim = corr2(orig_watermark,message);%把水印信息保存为‘message.bmp’
imwrite(message,'message.bmp','bmp');
figure;
subplot(2,1,1);
imshow(orig_watermark);
subplot(2,1,2);
imshow(message)
fprintf('提取的水印与原水印的相似度 %f',sim);
% end


这篇关于基于鲁棒性的数字水印的嵌入与提取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/269451

相关文章

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

ROS - C++实现RosBag包回放/提取

文章目录 1. 回放原理2. 回放/提取 多个话题3. 回放/提取数据包,并实时发布 1. 回放原理 #include <ros/ros.h>#include <rosbag/bag.h>#include <std_msgs/String.h>int main(int argc, char** argv){// 初始化ROS节点ros::init(argc, argv,

HalconDotNet中的图像特征与提取详解

文章目录 简介一、边缘特征提取二、角点特征提取三、区域特征提取四、纹理特征提取五、形状特征提取 简介   图像特征提取是图像处理中的一个重要步骤,用于从图像中提取有意义的特征,以便进行进一步的分析和处理。HalconDotNet提供了多种图像特征提取方法,每种方法都有其特定的应用场景和优缺点。 一、边缘特征提取   边缘特征提取是图像处理中最基本的特征提取方法之一,通过检

如何根据相同分隔符提取间隔数据?

最近遇到很多提问怎么提取字符的,而这些问题都有一个相同的特征,就是要提取的内容与内容之间,都有着相同的分隔符。当然,这种问题直接用“数据” →  “分列”功能就可以一步到位实现的,但有人喜欢折腾,而更多的人又非得指定函数公式的方法,或者更多的是要保持数据的同步性。   下面,我们就来讲讲用函数公式应该怎么实现这个提取,首先来个数据和要求,如下图,将 - 号间隔的内容依次提取到右边单元格内:

Java8特性:分组、提取字段、去重、过滤、差集、交集

总结下自己使用过的特性 将对象集合根据某个字段分组 //根据id分组Map<String, List<Bean>> newMap = successCf.stream().collect(Collectors.groupingBy(b -> b.getId().trim())); 获取对象集合里面的某个字段的集合 List<Bean> list = new ArrayList<>

OpenCV结构分析与形状描述符(10)检测并提取轮廓函数findContours()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 在二值图像中查找轮廓。 该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具,可用于形状分析和对象检测与识别。参见 OpenCV 示例目录中的 squares.cpp。 findContours 是 OpenCV 库中的一个重要函数

Base64编码 及 在HTML中用Base编码直接显示图片或嵌入其他文件类型

1.为什么要用到BASE64编码的图片信息      Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输。由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要转换一下。最常见的用途是作为电子邮件或WebService附件的传输编码.  2.base64编码定义    目前的internet

【python 走进pytotch】pytorch实现用Resnet提取特征

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂, 而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程 准备一张图片,pytorch可以方便地实现用预训练的网络提取特征。 下面我们用pytorch提取图片采用预训练网络resnet50,提取图片特征。 # -*- coding: utf-8 -*-import os

mhtml图片提取 百度图片下载

如果你需要找一些图片,可以先去百度一下,待相关网页加载完成后,点击保存,即可得到一个mhtml文件。这个文件里的图片会用base64进行存储,只需要找到他们并转化就可以。目前在美篇之类的网站上效果还一般,需要继续排查问题。 效果 代码 大概分为提取所有base64、转化为图片两步。 import base64from io import BytesIOfrom PIL import

python转换并提取pdf文件中的图片

#安装fitz包pip install pymupdf 脚本如下所示: import fitzimport reimport osimport timeimport sysarguments = sys.argvfor arg in arguments:print(arg)def file_name_list(base_dir):for i, j, k in os.walk(b