Какой будет лучший выбор алгоритма гладкой раскраски для Мандельброта?

Я визуализирую набор Мандельброта и уже добился некоторой плавной окраски, но если присмотреться, картина становится очень зашумленной. Мне интересно, как лучше всего улучшить окраску, чтобы добиться большей эстетики. Поможет ли использование раскраски гистограммы удалить грубые пиксельные области? Вот визуализация фрактала с использованием 10 000 итераций.

Вот как я сейчас генерирую и назначаю цвета:

            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            int black = 0;
            int[] colors = new int[max]; //max is the maximum number of iterations
            for (int i = 0; i<max; i++) {
                colors[i] = Color.HSBtoRGB(i/256f, 1, i/(i+8f));
            }
            for(int i = 0; i < colors.length / 2; i++)
            {
                int temp = colors[i];
                colors[i] = colors[colors.length - i - 1];
                colors[colors.length - i - 1] = temp;
            }

           ...
           ...
           ...

                    if (iterations < max) image.setRGB(col, row, colors[iterations]);
                    else image.setRGB(col, row, black);
                }
            }

            //ImageIO.write(image, "png", new File("mandelbrot_seeria90"+Integer.toString(i)+".png"));
            ImageIO.write(image, "png", new File("resotest.png"));

person Lauri Miller    schedule 18.03.2016    source источник
comment
На это ответили здесь: stackoverflow.com/a/1243788/216248   -  person karatedog    schedule 18.03.2016
comment
Вопрос не звучит так, как будто он требует плавной интерполяции цветов, а скорее общего сглаживания изображения. Это может быть немного неудобно (вы не можете просто использовать какой-то гауссиан, чтобы размыть окончательное изображение). Но вы можете для каждого пикселя взять среднее значение для окружающих пикселей, где количество итераций не было превышено (т.е. среднее значение всех окружающих пикселей, которые не являются черными).   -  person Marco13    schedule 18.03.2016


Ответы (3)


Простым решением, которое может дать приемлемые результаты, является простое сглаживание с использованием суперсэмплинга 2x2, 3x3 или 4x4 и генерация каждого пикселя путем усреднения значений цвета (а не количества итераций) блока из 4, 9 или 16 пикселей.

Этот подход представляет собой всего лишь общий метод рендеринга изображения, он не использует какие-либо конкретные знания фракталов Мандельброта для решения проблемы, но вы можете оптимизировать его, вычислив количество итераций для соседних целых пикселей и выполняя только этап подвыборки, если счетчики не все так же. Это означает, что вы будете делать это только там, где это необходимо: на границе между двумя счетчиками итераций или в шумных местах с множеством разных счетчиков рядом друг с другом.

Вы можете проверить это, сгенерировав тестовое изображение, а затем уменьшив его масштабным коэффициентом в приложении для редактирования изображений (убедитесь, что у вас включена фильтрация). Если все в порядке, вы можете реализовать это, добавив пару дополнительных циклов for внутри существующего внутреннего цикла пикселей для каждого субпикселя, увеличивая c на 1/2, 1/3 или 1 / 4 шага пикселя. Сложите значения цвета и разделите на соответствующую сумму.

person samgak    schedule 28.03.2016

Думайте циклически, если конечное значение достигает начального значения в цикле, а у вас есть несколько циклов.

Проверьте это, создав горизонтальную гамму, например |||| ... ||| цветов.

Что-то типа:

fill:
for (int i = 0; i < max; ) {
    for (int h = 0; h < NH; ++h) {
        float hValue = ((float)h) / NH;
        for (int b = 0; b < NB; ++b) {
            doublebValue = ((double)b) / NB; // 0 .. 1
            bValue = Math.sin(2 * Math.PI  * bValue); // -1 .. 1
            bValue = (2 + bValue) / 3; // 0.33 .. 1
            colors[i] = Color.HSBtoRGB(hValue, 1, (float) bValue);
            ++i;
            if (i >= max) {
                break fill;
            }
        }
    }
}
person Joop Eggen    schedule 18.03.2016

Слишком много для комментария, но не для окончательного ответа, извините.

Вы можете легко сделать плавную градацию цвета там, где контуры широко разбросаны, но в окрестности M-Set ("бесконечные" итерации) изображение становится явно хаотичным, с соседними пикселями, имеющими очень разное количество итераций, поэтому оно кажется зашумленным. . Когда создается зум, это становится еще более очевидным, и шумная область кажется «танцующей».

Я обнаружил, что лучшим решением было использовать шкалу серого в этих областях, исходя из разницы в итерациях 8 соседних пикселей. Если предположить, что «бесконечная» область окрашена в черный цвет, такие серые пиксели будут самыми черными там, где есть наибольшие различия в соседях, или где некоторые соседи находятся в M-Set. На более мелкой стороне, когда есть несколько соседей одинаковой глубины, я бы получил от них некоторый цветовой тон. А на среднем уровне, где нет соседей с одинаковой глубиной, оттенок серого будет основан на их вариациях.

Я использовал C и ассемблер (для итерации).

person Weather Vane    schedule 18.03.2016