Watermarking 3D Polygonal Meshes in the Mesh Spectral Domain
这周看了一篇Ryutarou Ohbuchi网格水印的论文,论文中提出在网格的频率域中加入水印。对于网格而言,没有如图像中的DCT等转换到频率域的变换,因此用什么量来模拟传统频率域中的系数,是很关键的。本文提出的水印算法在给定的3D多边形网格的变换域中嵌入水印,该变换域在本文中指网格频谱分析。同时,3D多边形网格的形状是由它的点连接关系和顶点坐标定义的。
文中通过更改网格频谱系数来实现水印的嵌入。先将原始网格变换到频率域中,然后修改频率域系数,嵌入水印信息,最后将模型从频率域反变换到空域即可得到嵌入水印的模型。
首先,介绍网格的频率域
计算网格频谱涉及到拉普拉斯矩阵特征值分解。从特征值分解中会产生一个特征值序列和对应的特征向量序列。小的特征值对应空间频率中的低频,大的特征值对应空间频率中的高频。小的特征值对应的特征向量和低频系数代表了全局形状特征,而大的特征值对应的特征向量和高频系数代表局部或细节形状特征。将模型中的空域中的点投影到归一化的特征向量将生成该顶点的网格频率系数。文中使用联合拉普拉斯矩阵,即基尔霍夫矩阵K来替代原始的拉普拉斯矩阵。
基尔霍夫矩阵K定义如下:(实际上这个矩阵就是只用到顶点连接关系的拉普拉斯矩阵)
K = D – A
D:对角矩阵,它的元素Dii = di,表示节点i的度数,
A:多边形网格的邻接矩阵,其元素aij定义如下:
(1)
一个有n个顶点的多边形网格M将会产生一个n x n大小的K矩阵,其特征值分解将产生n个特征值λi 和 n 个n维特征向量 wi,(1 ≤ i ≤ n )。将原始网格中的第i个顶点的每个分量 Vi = (xi, yi, zi)(1 ≤ i ≤ n )单独地投影到第i个归一化的特征向量ei上,即ei = wi / ||wi||。(也就是说ei是wi的单位向量)。
通过以上步骤产生了n个网格频率系数 ri = ( rs,i ,rt,i ,ru,i ) ,(1 ≤ i ≤ n )。下标s,t和u表示的是在网格频率域中的正交坐标轴,对应空间坐标轴x,y和z。为了从频率域中逆变换到空间域,需要将ei与ri相乘并求和,具体转换公式如下:
(2)
水印生成
上文中已经提到过,文中通过更改网格频谱系数来实现水印的嵌入。每个频率系数有三个频率轴s,t和u,通过对频率系数的三个分量进行调制以完成对水印的嵌入。
本文嵌入的数据是一个m维的比特向量a = (a1,a2,…,am) ,
。每一个比特aj乘以码片速率c得到水印信号向量b = (b1,b2,…,bmc) ,
,且b的总长度为mc
bi = aj , j.c ≤ i < (j+1).c ( 3 )
(注:我对这个转换的理解是,将原本要嵌入的序列的每一位都重复嵌入c(码片速率)次,比如,m = 5,c = 3,原始序列为a =(11001),经过上式转换将变为 b =(111,111,000,000,111),文中也解释说将同一个比特重复嵌入c次可以增加水印抵抗随机调价噪声攻击)
将b转换为b',
,转换规则为
(4)
水印嵌入
接下来就可以考虑嵌入水印的操作了。首先以频率域中的s轴为例进行水印嵌入。假定rsi是嵌入水印前的网格的第i个频谱系数的s轴分量,pi∈{1,-1}是由密钥Kw生成的一个伪随机序列,α (α> 0)是调制幅度。则第i个嵌入水印后的频谱系数
计算公式如下:
(5)
在水印提取过程中,需要使用水印嵌入过程中用到的密钥,也就是作为伪随机数的种子值要相同。因此,密钥的分发可以通过如公钥加密等分方式来完成。
在频谱的t轴和u轴都执行如上的操作后将生成一系列嵌入水印的频谱系数
,使用上文中的公式(2)将频谱系数做逆变换即可得到空域中的顶点坐标
,如此便可得到一个嵌入水印的多边形网格。
水印提取
作为一个私有水印,本文中提出的水印算法是非盲水印算法,也就是说,在水印提取阶段需要原始的未嵌入水印的网格,记为cover-mesh、和嵌入水印的(或者被降级的)网格,记为stego-mesh。水印提取时,首先对cover-mesh M和stego-mesh Mˆ,进行对齐。(嵌入水印后的三维模型在使用的时候经常要通过一定的相似变换处理,如网格模型的旋转、平移、缩放等操作。这些操作带来了模型顶点信息的改变,而三维模型数字水印算法中水印信息就是嵌入在顶点的属性信息中,在此情况下是不能提取出嵌入的水印信息的。为此,在提取水印信息之前需要把待检测模型变换到原始网格模型的坐标下。这一步骤称为网格对齐操作-----来自硕士论文《三维模型数字水印技术研究》)
为了对齐两个网格,文中使用网格前5个(最低频)频谱系数来粗略地重构出网格的形状。然后使用重建的形状得到一个3 x 3 的协方差矩阵,由该矩阵计算出一系列的特征向量。通过比较由两个形状计算出的特征向量将两个网格对齐。
对齐后的网格各自进行特征值分解,以得到各自的频谱系数。其中,M分解得到rsi,M^分解得到rsi^,计算。
计算三个频率轴上的系数总和qj
(6)
上式中使用的pi与嵌入时保持一致。同时,假定M^中的顶点坐标受到的扰动可以忽略,那么
(7)
其中,qj的取值为{αc , -αc }.由于α和C始终为正,简单测试qj的符号即可恢复原始的信息比特序列aj
aj = sign(qj)
上式中的sign为取符号函数。通过本文中的公式(4)可以转换得到原始的信息比特序列bi。
优化:网格分割
特征值分解对于只有几百个顶点的网格来说效果较好,但是当网格规模变大时,如顶点个数为10^4 ~ 10^7时,先前的方法就会出现两个问题:一是计算特征值分解的时间远大于水印嵌入时间,二是分解数值的稳定性变得越来越有问题.
因此,当要对顶点数目为10^4 ~ 10^7的网格进行操作时,需要将原始网格分割成小的子网格(如500个顶点),从而水印的嵌入和提取都在每个子网格中独立地进行。
网格分割有一个额外的好处。 将水印信息重复地嵌入到子网格中,可以抵抗网格切除等攻击,只要被切除的网格中保留了至少一个之前划分的子网格,水印信息就可以从中提取出。
本文实现了一个简单的网格分割。首先,手动地选取"特征点",使得特征点近似在预期的子网格的中心位置,并使特征点近似均匀分布在整个网格上。每个子网格沿着特征点根据网格顶点之间的连接关系逐步进行区域的扩大。当原始网格完全被分割时,子网格停止增长。
网格频谱分析在各个子网格中进行,忽略子网格边界上顶点的连接。在网格的嵌入和提取阶段要求子网格划分情况相同,因此在原始网格中用到的特征点需要保存。
其他补充
由于在水印提取阶段用到了最低频的5个频率系数进行网格的对齐,因此在嵌入水印的时候,并不是将水印嵌入到所有的频率系数中的,最多只能嵌入到 n – 5 个高频系数中。
Watermarking 3D Polygonal Meshes in the Mesh Spectral Domain的更多相关文章
- An Oblivious Watermarking for 3-D Polygonal Meshes Using Distribution of Vertex Norms
An Oblivious Watermarking for 3-D Polygonal Meshes Using Distribution of Vertex Norms 转眼就11月底了,突然开始有 ...
- C++实现网格水印之调试笔记(二)
整理了一下要实现的论文Watermarking 3D Polygonal Meshes in the Mesh Spectral Domain,步骤如下: 嵌入水印 à 提取水印 à 优化(网格细分) ...
- C++调用Matlab引擎及Eigen配置
这个周开始要着手实现网格水印的代码了,虽然还什么都不会,但也只能一步步摸索着往前走了. 我要实现的论文题目是<<Watermarking 3D Polygonal Meshes in th ...
- {ICIP2014}{收录论文列表}
This article come from HEREARS-L1: Learning Tuesday 10:30–12:30; Oral Session; Room: Leonard de Vinc ...
- A Blind Watermarking for 3-D Dynamic Mesh Model Using Distribution of Temporal Wavelet Coefficients
这周看了一篇动态网格序列水印的论文,由于目前在网格序列上做水印的工作特别少,加之我所看的这篇论文中的叙述相对简洁,理解起来颇为困难.好在请教了博士师兄,思路明朗了许多,也就把这思路整理在此了. 论文作 ...
- 从零3D基础入门XNA 4.0(2)——模型和BasicEffect
[题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...
- Pushing state-of-the-art in 3D content understanding
Pushing state-of-the-art in 3D content understanding 2019-10-31 06:34:08 This blog is copied from: h ...
- 【开发总结】—— BABYLON 3D开发常见问题及解决方法
前言:组内同事们根据长时间的Babylon.js开发实践,一起将项目开发中遇到的问题及解决方法做了一个梳理. ios [最好] 关闭离线缓存—— 解决添加了反射的mesh 丢失的问题 不要使用 pos ...
- 3D图形处理库
转自 3D图形处理库 高性能软件光栅化渲染器 OpenSWR OpenSWR —— 用于OpenGL的高性能,高度可扩展的软件光栅化渲染器 OpenSWR的目的是提供一个高性能,高度可扩展的OpenG ...
随机推荐
- 套题T2
数学(math.cpp) DXY的数学很差... 对于所有1<=i<=N求(2^i – i^2)能被7整除的个数.(N<=1000000) 样例输入: 3 样例输出: 1 你在代码中 ...
- 【mongoDB基础篇②】PHP-mongo扩展的编译以及使用
安装PHP-mongo扩展 安装php-mongo扩展和安装其他php扩展的步骤一样: #1.首先上http://pecl.php.net上面搜索mongo,得到下载地址 wget http://pe ...
- CSDN代码片排版
CSDN上发博文,尤其是有代码的,要用好“插入代码”功能(见下图).这是必须的,未来的IT程序员,需要用这种方式,展示出自己的代码.这是尊重读者,树立品牌的需要. 相关方法,参考见视频<发布第一 ...
- Hibernate逍遥游记-第15章处理并发问题-002悲观锁
1. 2. hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.connection.driver_class=com.mys ...
- AE CreateFeatureClass 创建shp. 删除shp. 向shp中添加要素
/// <summary> /// 创建多边形shp /// </summary> /// <param name="pPolygon">< ...
- 250. Count Univalue Subtrees
题目: Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes ...
- Android Handler之Message传递参数
最近发现Message,发送消息可以传递参数,这个思路很好,所以写了一个例子,点击屏幕,给Activity发送一个消息,传递两个参数,并把这个activity销毁掉! 程序打开界面: 点击屏幕,销毁a ...
- Maven中心仓库
当你使用Maven构建一个项目,Maven会检查你的pom.xml文件,找出需要下载的依赖包.首先它会到本地仓库查找所需的文件,如果没找到,就到默认的中心仓库(这是新的http://search.ma ...
- Collection_Other
package com.bjsxt.others.que; import java.util.ArrayDeque; import java.util.Queue; /** * 使用队列模拟银行存款业 ...
- Android下HelloWorld项目的R.java文件介绍
R.java文件介绍 HelloWorld工程中的R.java文件 package com.android.hellworld; public final class R { public s ...