標籤:
在實現提取浮水印的過程中,遇到了一些問題
首先還是根據論文中的思路來梳理一下整個提取流程
- 讀入兩個模型,一個原始模型ori_mesh, 一個浮水印模型wm_mesh。
- 將兩個模型對齊(即放在同一個座標系下)
- 分別計算兩個模型的頻譜係數,記ori_mesh頻譜係數為Rs, Rt, Ru, 記wm_mesh的頻譜係數為wRs, wRt, wRu.
- 根據下式計算Qj
- 再根據下式計算出嵌入浮水印的符號,這裡相當於得到的是嵌入的浮水印b‘,只是記為了aj
- 最後根據下式得出原始浮水印序列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++實現網格浮水印之調試筆記(五)—— 提取出錯