zoukankan      html  css  js  c++  java
  • C++实现网格水印之调试笔记(五)—— 提取出错

    在实现提取水印的过程中,遇到了一些问题

    首先还是根据论文中的思路来梳理一下整个提取流程

    1. 读入两个模型,一个原始模型ori_mesh, 一个水印模型wm_mesh。
    2. 将两个模型对齐(即放在同一个坐标系下)
    3. 分别计算两个模型的频谱系数,记ori_mesh频谱系数为Rs, Rt, Ru, 记wm_mesh的频谱系数为wRs, wRt, wRu.
    4. 根据下式计算Qj

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

    6. 最后根据下式得出原始水印序列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

  • 相关阅读:
    RTB交接
    awk命令详解
    Linux下的压缩解压缩命令详解
    inux下文件权限设置中的数字表示权限,比如777,677等,这个根据什么得来的
    jmeter接口测试教程
    kafka常用的操作命令
    hadoop常用的操作命令
    linux常用命令
    hive的常用命令
    用shell脚本写一个for循环
  • 原文地址:https://www.cnblogs.com/scut-linmaojiang/p/4479081.html
Copyright © 2011-2022 走看看