Артефакты на изображении при вейвлет преобразовании Хаара

Столкнулся с проблемой при выполнении ДВП Хаара к изображению. При обратном преобразовании появляются артефакты в виде белых точек как на картинках (Слева исходное изображение, справа после преобразования). Алгоритм следующий: преобразую изображение из палитры 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 шт):

Автор решения: Sav1g

Проблема заключалась в переводе в byte, теперь все работает без всяких артефактов. Всем спасибо за уделенное время для решения моего вопроса.

→ Ссылка