離散ウェーブレット変換を使用して画像の輝度チャネルを変換し、DWT 出力の LL 帯域の係数を変更することにより、画像の低周波数帯域の透かしを非表示にする画像透かしシステムを作成しています。次に、逆 DWT を実行してイメージを再構築します。
私が抱えている問題は、DWT 出力の係数を変更し、次に逆 DWT、次に DWT を変更すると、変更された係数が根本的に異なることです。
たとえば、2 スケール DWT の LL バンドの出力係数の 1 つは -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;
}