C++实现网格水印之调试笔记(四)—— 完成嵌入
接下来的问题是,当模型是对称的时候,结果是符合预期的,但是当模型是不对称的时候,结果是错误的,如下:
输入: 顶点:233
输出:
这又是什么鬼。。。,我的马呢!!!
看来逻辑上还是有错误
注意这时候C++输出的调试信息如下:
错误提示为:Input to EIG must not contain NaN,然后是一堆烫烫烫。。。
还有一个提示是: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 8.367225e-021.
初步估计是matlab计算模型特征值时出错了。这里一直困惑我的地方是,为什么输入一个对称的模型时,计算的结果没有问题,当输入一个非对称的模型时,却会出现上述结果?
然后我查看了之前计算矩阵特征值的matlab代码,
其中eigs是matlab中自带的对矩阵做特征分解的方法。通过错误提示可以看出,在matlab的eigs函数中的第94行出现了错误,打开matlab可以继续查看进一步的调用中出现的错误,总结起来应该是输入的矩阵中有一些无效值。然后我检查了一下计算拉普拉斯矩阵的方法。我用的是形式是下式中的第一个,
也就是说,用到了面积信息。当出现面积为0的情况时,0就作为除数了。论文中本来的拉普拉斯矩阵的计算方法是 L= D – A,其中D为对角矩阵,其对角元素为顶点的度,A为邻接矩阵。思考再三,决定重新写拉普拉斯矩阵的计算方法以及特征值分解的算法。
各矩阵的获取方式如下:
以及matlab特征值分解的代码
修改了代码后的输出:(当然首先来看我的马了=。=)
两个模型的对比:
用线勾勒出的是嵌入水印后的模型
下面两张图是一些细节
然后再看看兔子。输入: 顶点1187
最后再用一开始的圆柱验证一下。顶点:1180,两个模型用肉眼看几乎是重合的
从上面的结果来看,第一部分嵌入水印的工作应该是完成了。接下来就是提取水印了。