C++实现网格水印之调试笔记(五)—— 提取出错
在实现提取水印的过程中,遇到了一些问题
首先还是根据论文中的思路来梳理一下整个提取流程
- 读入两个模型,一个原始模型ori_mesh, 一个水印模型wm_mesh。
- 将两个模型对齐(即放在同一个坐标系下)
- 分别计算两个模型的频谱系数,记ori_mesh频谱系数为Rs, Rt, Ru, 记wm_mesh的频谱系数为wRs, wRt, wRu.
- 根据下式计算Qj

- 再根据下式计算出嵌入水印的符号,这里相当于得到的是嵌入的水印b',只是记为了aj

- 最后根据下式得出原始水印序列b

根据上述步骤,我一开始的想法是在网格平台下读入两个模型,然后按照上述步骤进行计算会遇到一些麻烦,比如获取网格的时候,虽然可以用一个链表将打开的文件存放起来,但是在初始化网格的时候,由于参数都是单独的,如果全部都改写成数组或者是链表的话,那改动起来会相当麻烦。于是我决定在嵌入水印的时候,将R矩阵写入文件中,这样提取水印的时候就不必再读入原始网格,只需计算出读入的水印网格中的wR矩阵,然后从文件中读取出R矩阵,两者做差值,再按照原来的步骤进行判断即可。
写入和读取分别如下:
//将原始网格的频谱系数写入文件中Rs
ofstream Rsfile;
Rsfile.open("D:\\Rs.txt",ios_base::out );
if ( Rsfile)
{
for ( int i = 0; i < m_vertexNum; i++)
{
Rsfile<<Rs[i]<<" ";
}
}
Rsfile.close();
//将原始网格的频谱系数从文件中读取出来
double *pRs = new double[m_vertexNum];
double *pRt = new double[m_vertexNum];
double *pRu = new double[m_vertexNum];
//Rs
ifstream Rsfile;
Rsfile.open("D:\\Rs.txt",ios_base::in );
if (Rsfile)
{
// read into memory
Rsfile.seekg (0, Rsfile.end);
int length = Rsfile.tellg();
Rsfile.seekg (0, Rsfile.beg);
char *buffer = new char[length];
Rsfile.read(buffer, length);
Rsfile.close();
// parse into array
std::istringstream iss(buffer);
int i = 0;
while (iss >> pRs[i++]);
delete [] buffer;
// print or use it.
}
Rsfile.close();
在提取的过程中,主要的问题出在sign函数上,由于没有查到sign函数所属的头文件,因此我自己实现了一个sign函数,代码如下:
double EigenDeformation::sign( double x)
{
cout <<"x = "<< x <<endl;
if( x > 0)
return 1;
else if(fabs(x) < 0.000000000001)
return 0;
else
return -1;
}
由于精度的关系,sign函数判断的符号总是不正确,调试查看输入sign函数的值和其输出的只如下:

其中x是输入的值,P是判断后得到的值。
然后常识将输入扩大1kw倍也失败。
改用另外一个函数 double _copysign( double x, double y );
这个函数是C中math.h中的函数,函数功能: 以第二个参数y的符号(正或负)返回第一个参数x,于是在代码中调用形式如下:
wB[i] = _copysign(1, Q[i]) ;
结果如下:

返回符号成功,对比嵌入的水印序列

怎么两者差别这么大。。。
每次运行得到的P的结果都一样。

错误1:将Rt读入文件的时候,写成Rs了
错误2:顶点赋值方式错误

更正:



原始网格的R 水印网格的R
C++实现网格水印之调试笔记(五)—— 提取出错的更多相关文章
- C++实现网格水印之调试笔记(六)—— 提取完成
昨天在修改了可以调试出来的错误之后,提取出的水印和嵌入的仍然相去甚远.这个时候我觉得有必要整理一下嵌入和提取的整个过程. 嵌入过程: Step1,嵌入的时候对网格的拉普拉斯矩阵L进行特征值分解,得到特 ...
- C++实现网格水印之调试笔记(六)——补充
调用matlab生成的网格水印特征向量矩阵 从文件中读取的原始网格的特征向量矩阵 好吧,之前得出的结果不正确是因为代码写错了.因为实现论文中的提取方案时代码写错了,自己想了另外一个方法,结果方向两者在 ...
- 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++实现网格水印之调试笔记(一)
首先说一下我的一些简单的调试方法,除了常规的断点调试之外,我还会使用注释的方法来调试.当整个工程代码量相当多且调用层次关系较为复杂时,这种方法能够比较高效的定位到出错误的代码段或某个函数,然后在出现错 ...
- Crazyflie笔记五: CRTP 实时通信协议(一)(转)
源:Crazyflie笔记五: CRTP 实时通信协议(一) 这里详细介绍了 Crazyflie 的 CRTP实时通信协议的相关内容,由于内容很长,分几篇博文来讲述.这里是第一节内容.欢迎交流:301 ...
- Tomcat调试笔记
调试笔记 在使用Tomcat过程中经常碰到问题,导致tomcat启动失败.如下↓ 由于报错太过笼统,我根本无法找出错误.后来我切换到Console视图下,看到了如下错误信息. 根据报错信息,错误原因是 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
随机推荐
- PHP输入流php://input [转]
对于php://input介绍,PHP官方手册文档有一段话对它进行了很明确地概述. "php://input allows you to read raw POST data. It is ...
- s3cmd的安装与配置
安装包链接:http://files.cnblogs.com/files/litao0505/s3.rar 安装S3cmd1. tar -zxf s3cmd-1.0.0.tar.gz2. mv s3c ...
- Java学习笔记之:Java的数据类型
一.介绍 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. Java语言提供了八种基本类型 ...
- java:访问权限-protected实例
在不同包,子类继承后可以使用父类的protect权限的属性或方法 父类: package com.tinyphp; public class Father { protected String nam ...
- 利用qt打开一张图片并转成灰度矩阵
首先是mat类,这个类的主要作用是构造一个容器,并将对应像素的灰度值放在容器内 #ifndef MAT_H #define MAT_H #include <vector> #include ...
- KMP算法的C++实现
这个问题阮一峰老师讲的很清楚,链接 这里我只贴一下我的C++实现代码: #include <iostream> #include <cstring> #include < ...
- Right Column - 右侧栏目
function share(sType){ var sName = "Yorhom\'s Game Box"; var title='Yorhom\'s Game Box', _ ...
- linux PATH环境变量
$PATH:决定了shell将到哪些目录中寻找命令或程序,PATH的值是一系列目录,当您运行一个程序时,Linux在这些目录下进行搜寻编译链接 shell下输出path值: echo $PATH: w ...
- php整理(四): mysql
PHP学习(四)---PHP与数据库MySql 主要有以下的内容: 1.怎么连接数据库 2.怎么操作数据库 (1)怎么执行sql语言 (2)怎么处理返回的结果集 方法一:面向过程(已经过时,只是了解) ...
- [Codeforces676B]Pyramid of Glasses(递推,DP)
题目链接:http://codeforces.com/problemset/problem/676/B 递推,dp(i, j)表示第i层第j个杯子,从第一层开始向下倒,和数塔一样的题.每个杯子1个时间 ...