这周看了一篇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的更多相关文章

  1. 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月底了,突然开始有 ...

  2. C++实现网格水印之调试笔记(二)

    整理了一下要实现的论文Watermarking 3D Polygonal Meshes in the Mesh Spectral Domain,步骤如下: 嵌入水印 à 提取水印 à 优化(网格细分) ...

  3. C++调用Matlab引擎及Eigen配置

    这个周开始要着手实现网格水印的代码了,虽然还什么都不会,但也只能一步步摸索着往前走了. 我要实现的论文题目是<<Watermarking 3D Polygonal Meshes in th ...

  4. {ICIP2014}{收录论文列表}

    This article come from HEREARS-L1: Learning Tuesday 10:30–12:30; Oral Session; Room: Leonard de Vinc ...

  5. A Blind Watermarking for 3-D Dynamic Mesh Model Using Distribution of Temporal Wavelet Coefficients

    这周看了一篇动态网格序列水印的论文,由于目前在网格序列上做水印的工作特别少,加之我所看的这篇论文中的叙述相对简洁,理解起来颇为困难.好在请教了博士师兄,思路明朗了许多,也就把这思路整理在此了. 论文作 ...

  6. 从零3D基础入门XNA 4.0(2)——模型和BasicEffect

    [题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...

  7. 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 ...

  8. 【开发总结】—— BABYLON 3D开发常见问题及解决方法

    前言:组内同事们根据长时间的Babylon.js开发实践,一起将项目开发中遇到的问题及解决方法做了一个梳理. ios [最好] 关闭离线缓存—— 解决添加了反射的mesh 丢失的问题 不要使用 pos ...

  9. 3D图形处理库

    转自 3D图形处理库 高性能软件光栅化渲染器 OpenSWR OpenSWR —— 用于OpenGL的高性能,高度可扩展的软件光栅化渲染器 OpenSWR的目的是提供一个高性能,高度可扩展的OpenG ...

随机推荐

  1. lintcode 中等题:Simplify Path 简化路径

    题目 简化路径 给定一个文档(Unix-style)的完全路径,请进行路径简化. 样例 "/home/", => "/home" "/a/./b ...

  2. 61. Rotate List

    题目: Given a list, rotate the list to the right by k places, where k is non-negative. For example:Giv ...

  3. java类的加载以及初始化顺序

    类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...

  4. Ubuntu 安装mod_python配置Apache2

    在Ubuntu上搭建Python运行环境,mod_python是不可少的(据说mod_swgi也是可以的,没有亲测).使用命令安装mod_python. 安装: apt-get install lib ...

  5. 自定义View(2)canas绘制基本图形的示例

    效果 代码: void drawSample(Canvas canvas) { /* * 方法 说明 drawRect 绘制矩形 drawCircle 绘制圆形 drawOval 绘制椭圆 drawP ...

  6. Android Dialogs(6)Dialog类使用示例:用系统theme和用自定义的theme

    使用dialog时有很多 方法,其中一个就是直接 使用基类Dialog,可用来作一个没有按钮的非模态提示框,它可以直接从系统的主题构造也可从自定义的主题构造. 基本步骤: a,构造 b,调用dialo ...

  7. C# 写入XML文档三种方法详细介绍

      三个类将同样的xml内容写入文档,介绍了如何使用XmlDocument类对XML进行操作,以及如何使用LINQ to XML对XML进行操作. 它们分别使用了XmlDocument类和XDocum ...

  8. SQLserver游标原理和使用方法

    在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句.但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录.那么如何解决这种问题呢 ...

  9. 面试题_82_to_87_Date、Time 及 Calendar 的面试题

    82)在多线程环境下,SimpleDateFormat 是线程安全的吗?(答案)不是,非常不幸,DateFormat 的所有实现,包括 SimpleDateFormat 都不是线程安全的,因此你不应该 ...

  10. 1320. Graph Decomposition

    1320 简单并查集 #include <iostream> #include<cstdio> #include<cstring> #include<algo ...