C++实现网格水印之调试笔记(六)—— 提取完成
昨天在修改了可以调试出来的错误之后,提取出的水印和嵌入的仍然相去甚远。这个时候我觉得有必要整理一下嵌入和提取的整个过程。
嵌入过程:
Step1,嵌入的时候对网格的拉普拉斯矩阵L进行特征值分解,得到特征值和特征向量;
Step2,将特征向量单位化;
Step3,解方程:R . E = V(1),E,V已知求出R
其中R是频谱系数矩阵,E是单位化的特征向量矩阵,V是顶点坐标矩阵
Step4,修改R的R',其中R'= R + △ (2),R,△已知,求R'
Step5,根据矩阵方程(1)求出V', R'. E = V'(3),R', E已知,求V'
再来重温一下提取过程:
Step1,将原始水印M和网格水印M'对齐(放入同一坐标系下)
Step2,计算M的频谱系数R和M'的频谱系数R'
Step3,根据下式计算Qj即 △
Step4, 再根据下式计算出嵌入水印的符号,这里相当于得到的是嵌入的水印b',只是记为了aj
Step5,最后根据下式得出原始水印序列b
注意,在计算M'的频谱系数R'的时候,
用的是R'. E'= V'(4),E',V'已知,求R'
对比(3)和(4)式,
R'. E = V'(3)
R'. E' = V'(4)
可以看到两个等式中有两个量是相同的,即R'和V'而E和E'很可能是不相等的,所以用(4)式计算出的R'和(2)R'= R + △ (2)式中的R'是不同的,自然提取出来的 △ 也不正确。所以我觉得,是这篇论文本身有问题。。。
我觉得正确的提取方法应该是用式(3),输入水印网格,然后获取V'矩阵,用原始矩阵的E,两者结合求出R',与原始水印的R相减才能得到△
为了验证我的想法,我首先将原始网格中的E矩阵写入文件
//将单位化的特征向量写入文件中
ofstream NormEfile;
NormEfile.open("D:\\Ne.txt",ios_base::out );
if ( NormEfile)
{
for ( int i = 0; i < m_vertexNum; i++)
{
for (int j = 0; j < m_vertexNum; j++)
{
NormEfile<<E_matrix(i,j)<<" ";
}
}
}
NormEfile.close();
但是在读取的过程中遇到了问题。
Matlab计算出的R
获取出的R矩阵
也就是说 wRs应该是获取出的R矩阵的第一行
wRs = R_matrix.col(0);
输出wRs和R矩阵的第一行,结果却便了。。。
结果是循环的索引值写错了,修改后,结果如下:
但是Qi的值仍然错误
调试的时候发现,Ru读取的时候也出错了。。。
改正后问题仍然没有得到解决,观察上面的输出,估计问题是出在Ru上,输出Ru进行观察
原来是每次打开的文件都是Rs,忘记改成相应的文件了。。。。
修改之后,仍然错误。检查读出的pRu
文件中的Ru如下,显然读取错误了。
再检查pRs
读取的结果是正确的。明明是一样的读取方式,为啥会出错?
结果是下面一个判断写错了。。。
今天犯的很多错误都是这方面的,总结出来的教训是一定要仔细。
修改了上述错误后,终于提取出来了!
记录下将二维数组读出文件的方法(写入在前面有记录)
//从文件中将原始网格的E矩阵读取出来
double *pE = new double[m_vertexNum * m_vertexNum];
ifstream NERfile;
NERfile.open("D:\\Ne.txt",ios_base::in );
if (NERfile)
{
// read into memory
NERfile.seekg (0, NERfile.end);
int length = NERfile.tellg();
NERfile.seekg (0, NERfile.beg);
char *buffer = new char[length];
NERfile.read(buffer, length);
NERfile.close();
// parse into array
std::istringstream iss(buffer);
int i = 0;
while (iss >> pE[i++]);
delete [] buffer;
// print or use it.
}
NERfile.close();
int ecount = 0;
for ( int i = 0; i < m_vertexNum; i++ )
{
for ( int j = 0; j < m_vertexNum; j++ )
{
E_matrix(i,j) = pE[ecount++];
}
}
总算提取成功了。
值得注意的是,当模型的顶点个数为奇数时,产生的Wb和P的位数可能比顶点个数多一些,这是因为码片速率和原始的水印序列a的乘积很难刚好等于顶点个数。所以在读取Wb和P的时候应该改写一下while语句,如下:
while ( i<m_vertexNum )
{
iss >> RB[i++];
}
最后,new出来的数组最好用delete语句释放掉。
C++实现网格水印之调试笔记(六)—— 提取完成的更多相关文章
- C++实现网格水印之调试笔记(六)——补充
调用matlab生成的网格水印特征向量矩阵 从文件中读取的原始网格的特征向量矩阵 好吧,之前得出的结果不正确是因为代码写错了.因为实现论文中的提取方案时代码写错了,自己想了另外一个方法,结果方向两者在 ...
- C++实现网格水印之调试笔记(五)—— 提取出错
在实现提取水印的过程中,遇到了一些问题 首先还是根据论文中的思路来梳理一下整个提取流程 读入两个模型,一个原始模型ori_mesh, 一个水印模型wm_mesh. 将两个模型对齐(即放在同一个坐标系下 ...
- C++实现网格水印之调试笔记(二)
整理了一下要实现的论文Watermarking 3D Polygonal Meshes in the Mesh Spectral Domain,步骤如下: 嵌入水印 à 提取水印 à 优化(网格细分) ...
- C++实现网格水印之调试笔记(四)—— 完成嵌入
接下来的问题是,当模型是对称的时候,结果是符合预期的,但是当模型是不对称的时候,结果是错误的,如下: 输入: 顶点:233 输出: 这又是什么鬼...,我的马呢!!! 看来逻辑上还是有错误 注意这时候 ...
- C++实现网格水印之调试笔记(三)—— 初有结果
错误: error C2338: THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD 这种错误 ...
- C++实现网格水印之调试笔记(一)
首先说一下我的一些简单的调试方法,除了常规的断点调试之外,我还会使用注释的方法来调试.当整个工程代码量相当多且调用层次关系较为复杂时,这种方法能够比较高效的定位到出错误的代码段或某个函数,然后在出现错 ...
- JavaScript特效(调试笔记)
JavaScript特效 一.在网页上显示当前的时间日期,例如:“2016年3月26日 星期六”. js源代码: function getTime() { var today = new Date() ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- python3.4学习笔记(六) 常用快捷键使用技巧,持续更新
python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...
随机推荐
- 合并傻子//区间dp
P1062 合并傻子 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 从前有一堆傻子,钟某人要合并他们~但是,合并傻子是要掉RP的...... 描述 在一个园 ...
- 李洪强iOS开发之OC[014] -对象的存储细节
// // main.m // 13 - 对象的存储细节 // // Created by vic fan on 16/7/9. // Copyright © 2016年 李洪强. All r ...
- Project Euler 80:Square root digital expansion 平方根数字展开
Square root digital expansion It is well known that if the square root of a natural number is not an ...
- lintcode 中等题:find the missing number 寻找缺失的数
题目 寻找缺失的数 给出一个包含 0 .. N 中 N 个数的序列,找出0 .. N 中没有出现在序列中的那个数. 样例 N = 4 且序列为 [0, 1, 3] 时,缺失的数为2. 注意 可以改变序 ...
- 转贴: A Simple c# Wrapper for ffMpeg
原帖地址:http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/ A Simple c# Wrapper fo ...
- ISO9000与ISO9001的区别
很多人询问ISO9000和ISO9001的区别在哪里,其实这是一个概念上的误解. ISO9001是ISO9000族标准所包括的一组质量管理体系核心标准之一.ISO9000族标准是国际标准化组织(ISO ...
- ArcEngine中打开各种数据源(WorkSpace)的连接(转)
ArcEngine中打开各种数据源(WorkSpace)的连接 (SDE.personal/File.ShapeFile.CAD数据.影像图.影像数据集) ArcEngine 可以接受多种数据源.在开 ...
- iOS 相机和相册使用授权
1.判断用户是否有权限访问相册 授权一次后,不在提示是否授权 #import <AssetsLibrary/AssetsLibrary.h> ALAuthorizationStatus a ...
- (转)最新版的SSH框整合(Spring 3.1.1 + Struts 2.3.1.2 + Hibernate 4.1)
最近一直有朋友在问,最新版的Spring.Struts.Hibernate整合老是有问题,昨晚大概看了一下.从Hibernate 4 开始,本身已经很好的实现了数据库事务模块,而Spring也把Hib ...
- PHP工程师面临成长瓶颈
作为开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题,我该如何突破自身的瓶颈,以便更好的发展呢?PHP工程师面临成长瓶颈 ...