我正在编写一个图像水印系统,通过使用离散小波变换来转换图像的亮度通道,然后修改 DWT 输出的 LL 频带中的系数,从而在图像的低频带中隐藏水印。然后我做一个反向 DWT 并重建我的图像。
我遇到的问题是,当我修改 DWT 输出中的系数,然后是逆 DWT,然后再次修改 DWT 时,修改后的系数完全不同。
例如,2-scale DWT 的 LL 波段的输出系数之一是 -0.10704,我将这个系数修改为 16.89,然后对我的数据执行 IDWT。然后我获取了 IDWT 的输出并再次对其进行了 DWT,修改为 16.89 的系数变为 0.022。
我相当肯定 DWT 和 IDWT 代码是正确的,因为我已经针对其他库对其进行了测试,并且当滤波器系数和其他参数相同时,每个变换的输出都匹配。(由于舍入误差,在可以预期的范围内)
我遇到的主要问题是我可能不太了解 DWT,我认为 DWT 和 IDWT 应该是合理无损的(除了舍入误差等),但这里似乎并非如此.
我希望更熟悉变换的人可以指出一个可能的问题,是否有可能因为该位置的其他子带(LH、HL、HH)中的系数微不足道,我正在丢失数据?如果是这样,我如何确定这可能发生在哪些系数上?
我的嵌入函数如下,在 LL 频带中选择系数,如果所选位置的 LH、HH 或 HL 频带的绝对值大于相应子频带的平均值,则确定“强”为真。
//If this evaluates to true, then the texture is considered strong.
if ((Math.Abs(LH[i][w]) >= LHmean) || (Math.Abs(HL[i][w]) >= HLmean) || (Math.Abs(HH[i][w]) >= HHmean))
static double MarkCoeff(int index, double coeff,bool strong)
{
int q1 = 16;
int q2 = 8;
int quantizestep = 0;
byte watermarkbit = binaryWM[index];
if(strong)
quantizestep = q1;
else
quantizestep = q2;
coeff /= (double)quantizestep;
double coeffdiff = 0;
if(coeff > 0.0)
coeffdiff = coeff - (int)coeff;
else
coeffdiff = coeff + (int)coeff;
if (1 == ((int)coeff % 2))
{
//odd
if (watermarkbit == 0)
{
if (Math.Abs(coeffdiff) > 0.5)
coeff += 1.0;
else
coeff -= 1.0;
}
}
else
{
//even
if (watermarkbit == 1)
{
if (Math.Abs(coeffdiff) > 0.5)
coeff += 1.0;
else
coeff -= 1.0;
}
}
coeff *= (double)quantizestep;
return coeff;
}