图像上的离散小波变换和LL带系数中的水印嵌入,再次执行IDWT-DWT时数据丢失?

发布于 2024-11-23 18:01:20 字数 1916 浏览 2 评论 0原文

我正在编写一个图像水印系统,通过使用离散小波变换变换图像的亮度通道,然后修改 DWT 输出的 LL 频带中的系数,来隐藏图像低频带中的水印。然后我进行逆 DWT 并重建我的图像。

我遇到的问题是,当我修改 DWT 输出中的系数,然后修改逆 DWT,然后再次修改 DWT 时,修改后的系数完全不同。

例如,2尺度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;
    }

I'm writing an image watermarking system to hide a watermark in an image's low frequency band by transforming the image's luminance channel with a Discrete Wavelet Transform, then modifying coefficients in the LL band of the DWT output. I then do an Inverse DWT and rebuild my image.

The problem I'm having is when I modify coefficients in the DWT output, then inverse-DWT, and then DWT again, the modified coefficients are radically different.

For example, one of the output coefficients in the LL band of the 2-scale DWT was -0.10704, I modified this coefficient to be 16.89, then performed the IDWT on my data. I then took the output of the IDWT and performed a DWT on it again, and my coefficient which was modified to be 16.89 became 0.022.

I'm fairly certain that the DWT and IDWT code is correct because I've tested it against other libraries and the output from each transform matches when the filter coefficients and other parameters are the same. (Within what can be expected due to rounding error)

The main problem I have is that I perhaps don't understand the DWT all that well, I thought DWT and IDWT were supposed to be reasonably lossless (Aside from rounding error and such), yet this doesn't seem to be the case here.

I'm hoping someone more familiar with the transform can point me at a possible issue, is it possible that because the coefficients in my other subbands (LH, HL, HH) for that position are insignificant I'm losing data? If so, how can I determine which coefficients this may happen to?

My embedding function is below, coefficients are chosen in the LL band, "strong" is determined to be true if the absolute value of the LH, HH, or HL band for the selected location is larger than the mean value of the corresponding subband.

//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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文