C++實現網格浮水印之調試筆記(五)—— 提取出錯

來源:互聯網
上載者:User

標籤:

在實現提取浮水印的過程中,遇到了一些問題

首先還是根據論文中的思路來梳理一下整個提取流程

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

ofstreamRsfile;

????????Rsfile.open("D:\\Rs.txt",ios_base::out );

????????if ( Rsfile)

????????{

????????????for ( inti = 0; i < m_vertexNum; i++)

????????????{

????????????Rsfile<<Rs[i]<<" ";

????????????}

????????}

????????Rsfile.close();

?

????//將原始網格的頻譜係數從檔案中讀取出來

????????double *pRs = newdouble[m_vertexNum];

????????double *pRt = newdouble[m_vertexNum];

????????double *pRu = newdouble[m_vertexNum];

?

????????//Rs

????????ifstreamRsfile;

????????Rsfile.open("D:\\Rs.txt",ios_base::in );

????????if (Rsfile)

????????{

????????????// read into memory

????????????Rsfile.seekg (0, Rsfile.end);

????????????intlength = Rsfile.tellg();

????????????Rsfile.seekg (0, Rsfile.beg);

?

????????????char *buffer = newchar[length];

????????????Rsfile.read(buffer, length);

????????????Rsfile.close();

?

????????????// parse into array

????????????std::istringstreamiss(buffer);

????????????inti = 0;

????????????while (iss >> pRs[i++]);

????????????delete [] buffer;

????????????// print or use it.

????????}

????????Rsfile.close();

在提取的過程中,主要的問題出在sign函數上,由於沒有查到sign函數所屬的標頭檔,因此我自己實現了一個sign函數,代碼如下:

doubleEigenDeformation::sign( doublex)

????{

????????cout <<"x = "<< x <<endl;

????????if( x > 0)

????????????return 1;

????????elseif(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++實現網格浮水印之調試筆記(五)—— 提取出錯

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.