Артефакты на изображении при вейвлет преобразовании Хаара
Столкнулся с проблемой при выполнении ДВП Хаара к изображению. При обратном преобразовании появляются артефакты в виде белых точек как на картинках (Слева исходное изображение, справа после преобразования).
Алгоритм следующий: преобразую изображение из палитры RGB в палитру YCbCr, далее к Y коэффициенту применяю преобразование Хаара, и обратно соответственно. В результате на некоторых изображениях появляются артефакты. Кусок кода с самим преобразованием (ImageCustom - изображение в палитре YCbCr). Проблема не в смене палитры, а именно в алгоритме ДВП. Заметил, что точки образовываются именно на черных пикселях, но не понимаю в чем может быть загвоздка. Обособленно сам алгоритм ДВП работает правильно.
// Вейвлет преобразование
public static ImageCustom waveletTranform(ImageCustom im, int n, int m)
{
double[,] old = new double[im.Weight, im.Height];
// Копируем входной массив
double[,] mass = new double[n, m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
old[i, j] = im.pixels[i, j].Y;
mass[i, j] = old[i, j];
}
// I итерация, только полусуммы
for (int j = 0, j_count = 0; j < m; j += 2, j_count++)
for (int i = 0; i < n; i++)
old[i, j_count] = mass[i, j] + mass[i, j + 1];
// II итерация, только полуразности
for (int j = m - 1, j_count = m - 1; j > 0; j -= 2, j_count--)
for (int i = 0; i < n; i++)
old[i, j_count] = mass[i, j - 1] - mass[i, j];
// Копирование массива
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
mass[i, j] = old[i, j];
// III итерация, только полусуммы
for (int i = 0, i_count = 0; i < n; i += 2, i_count++)
for (int j = 0; j < m; j++)
old[i_count, j] = mass[i, j] + mass[i + 1, j];
// IV итерация, только полуразности
for (int i = n - 1, i_count = n - 1; i > 0; i -= 2, i_count--)
for (int j = 0; j < m; j++)
old[i_count, j] = mass[i - 1, j] - mass[i, j];
// Учитываем деление на 2
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
old[i, j] /= 4;
//Заполнение изображения
ImageCustom imnew = new ImageCustom(im);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
imnew.pixels[i, j].Y = (byte)old[i, j];
return imnew;
}
// Обратное вейвлет преобразование
public static ImageCustom waveletBack(ImageCustom im, int n, int m)
{
double[,] old = new double[im.Weight, im.Height];
// Копируем входной массив
double[,] mass = new double[n, m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
old[i, j] = im.pixels[i, j].Y;
mass[i, j] = old[i, j];
}
// I итерация (по столбцам)
for (int j = 0; j < m; j++)
for (int i = 0, i_count = 0; i < n; i += 2, i_count++)
{
old[i, j] = mass[i_count, j] + mass[n / 2 + i_count, j];
old[i + 1, j] = mass[i_count, j] - mass[n / 2 + i_count, j];
}
// Копирование массива
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
mass[i, j] = old[i, j];
// II итерация (по строкам)
for (int i = 0; i < n; i++)
for (int j = 0, j_count = 0; j < m; j += 2, j_count++)
{
old[i, j] = mass[i, j_count] + mass[i, m / 2 + j_count];
old[i, j + 1] = mass[i, j_count] - mass[i, m / 2 + j_count];
}
ImageCustom imnew = new ImageCustom(im);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
imnew.pixels[i, j].Y = (byte)old[i, j];
return imnew;
}
Ответы (1 шт):
Проблема заключалась в переводе в byte, теперь все работает без всяких артефактов. Всем спасибо за уделенное время для решения моего вопроса.