Я пишу систему водяных знаков на изображении, чтобы скрыть водяной знак в низкочастотном диапазоне изображения, преобразовав канал яркости изображения с помощью дискретного вейвлет-преобразования, а затем изменив коэффициенты в диапазоне LL на выходе DWT.Затем я делаю обратный DWT и перестраиваю свое изображение.
Проблема, с которой я сталкиваюсь, заключается в том, что, когда я изменяю коэффициенты в выходных данных DWT, затем инверсные DWT, а затем снова DWT, измененные коэффициенты радикально отличаются.
Например, один из выходных коэффициентов в полосе LL 2-масштабного DWT был -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;
}