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,两个模型用肉眼看几乎是重合的

从上面的结果来看,第一部分嵌入水印的工作应该是完成了。接下来就是提取水印了。

原文地址:https://www.cnblogs.com/scut-linmaojiang/p/4454511.html