Генерация умеренно интересных изображений

Краткий обзор: можно ли предложить алгоритм математического выхода по плоскости пикселей, которые генерируют умеренно интересное изображение, предпочтительно то, которое в целом напоминает что-то?

История к настоящему времени:

Когда-то давно я решил, чтобы уменьшить отходы цикла на моем (по общему признанию также) многочисленные компьютеры и намереваться генерировать изображения умеренно интересным способом; использование PRNG и некоторой умной математики для создания изображений, которые, в целом, напомнили бы что-то.

Или по крайней мере, который был планом. Как оказалось, умная математика требует быть умным математиком; это я не.

Довольно долго я прибыл в метод, который предпочел прямые линии (поскольку это обычно компоненты, из которых наш мир сделан), возможно, слишком сильно. Результат мягко интересен; сходство, возможно, городские сетки как таковые:

Городские сетки, возможно? http://totlandweb.info/imggen.out.png

Теперь для надлежащего вопроса: Учитывая исходный код этой небольшой программы; можно ли улучшить его и предложить ли метод, который дает несколько более интересные результаты? (например, не городские сетки, но возможно стоит, животные, география, что имеет Вас),

Это также предназначено как своего рода проблема; я предполагаю и как таковой, я записал некоторые абсолютно произвольные и одинаково дополнительные правила:

  1. В комментариях в коде говорится все это действительно. Предложения и "решения" должны отредактировать сам алгоритм, не окружающую платформу, за исключением для зафиксировать ошибки, который препятствует тому, чтобы образец компилировал.

  2. Код должен скомпилировать чисто со стандартным компилятором C проблемы. (Если обеспеченный пример не делает, ой! Скажите мне, и я зафиксирую.:)

  3. Метод должен, хотя снова, это является дополнительным, не, должны выявить справку из Вашей дружественной математической библиотеки окружения и в целом использовать (P) RNG как его канал ввода первичных данных.

  4. Решениями должен, вероятно, быть поставляемый компонент путем простого дергания независимо от того, что между строками надреза (те, которые говорят, что Вы не должны редактировать выше и ниже, соответственно), с оператором к эффекту того, что необходимо добавить к преамбуле в частности.

  5. Править: Иногда легко забыть, что люди в Интернете не могут прочитать мои мысли; но там Вы идете. Программа должна потребовать минимума человеческого вмешательства в поколение изображений, за исключением оценить результаты и выбрала лучшие.

Код требует, чтобы компилятор C и libpng создали; я не совсем уверен, что компилятор MinGW обеспечивает предметы первой необходимости, но я был бы удивлен, не сделал ли он. Для Debian Вы захотите libpng-dev пакет, и для Mac OS X Вы захотите инструменты XCode..

Исходный код может быть загружен здесь.

Предупреждение: Крупное поступление бахвальства кода!

// compile with gcc -o imggen -lpng imggen.c
// optionally with -DITERATIONS=x, where x is an appropriate integer
// If you're on a Mac or using MinGW, you may have to fiddle with the linker flags to find the library and includes.

#include 
#include 
#include 

#ifdef ITERATIONS
#define REPEAT
#endif // ITERATIONS

// YOU MAY CHANGE THE FOLLOWING DEFINES
#define WIDTH 320
#define HEIGHT 240

// YOU MAY REPLACE THE FOLLOWING DEFINES AS APPROPRIATE
#define INK 16384

void writePNG (png_bytepp imageBuffer, png_uint_32 width, png_uint_32 height, int iteration) {
  char *fname;
  asprintf(&fname, "out.%d.png", iteration);

  FILE *fp = fopen(fname, "wb");
  if (!fp) return;
  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  png_infop  info_ptr = png_create_info_struct(png_ptr);
  png_init_io(png_ptr, fp);
  png_set_filter(png_ptr, PNG_FILTER_TYPE_DEFAULT, PNG_FILTER_NONE);
  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
  png_set_IHDR(png_ptr, info_ptr, width, height, 8,
               PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  png_set_rows(png_ptr, info_ptr, imageBuffer);
  png_set_invert_mono(png_ptr); /// YOU MAY COMMENT OUT THIS LINE
  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
  png_destroy_write_struct(&png_ptr, &info_ptr);
  fclose(fp);
  free(fname);
}

int main (int argc, const char * argv[]) {
  png_uint_32 height = HEIGHT, width = WIDTH;


  int iteration = 1;
#ifdef REPEAT
  for (iteration = 1; iteration <= ITERATIONS; iteration++) {
#endif // REPEAT  

    png_bytepp imageBuffer = malloc(sizeof(png_bytep) * height);
    for (png_uint_32 i = 0; i < height; i++) {
      imageBuffer[i] = malloc(sizeof(png_byte) * width);
      for (png_uint_32 j = 0; j < width; j++) {
        imageBuffer[i][j] = 0;
      }
    }    

    /// CUT ACROSS THE DASHED LINES
    /// -------------------------------------------
    /// NO EDITING ABOVE THIS LINE; EXCEPT AS NOTED

    int ink = INK;
    int x = rand() % width, y = rand() % height;

    int xdir = (rand() % 2)?1:-1;
    int ydir = (rand() % 2)?1:-1;

    while (ink) {
      imageBuffer[y][x] = 255;
      --ink;
      xdir += (rand() % 2)?(1):(-1);
      ydir += (rand() % 2)?(1):(-1);
      if (ydir > 0) {
        ++y;
      } else if (ydir < 0) {
        --y;
      }
      if (xdir > 0) {
        ++x;
      } else if (xdir < 0) {
        --x;
      }
      if (x == -1 || y == -1 || x == width || y == height || x == y && x == 0) {
        x = rand() % width; y = rand() % height;
        xdir = (rand() % 2)?1:-1;
        ydir = (rand() % 2)?1:-1;
      }
    }

    /// NO EDITING BELOW THIS LINE
    /// -------------------------------------------

    writePNG(imageBuffer, width, height, iteration);

    for (png_uint_32 i = 0; i < height; i++) {
      free(imageBuffer[i]);
    }    
    free(imageBuffer);
#ifdef REPEAT
  }
#endif // REPEAT
  return 0;
}

Примечание: В то время как этот вопрос строго говоря не кажется "соответствующим" как таковой; я все еще полагаю, что это может дать начало некоторому способу "правильного" ответа. Возможно.

Счастливый поиск.

Отредактируйте (снова): исходный код для упрощенных путей bezier, используемых в моем ответе (чтение вниз), может быть найден здесь и здесь.

22
задан Williham Totland 25 April 2010 в 03:49
поделиться

6 ответов

Фракталы? Они больше не просто для анализа фондовых рынков (Шутка Мандельброта, извините).

Некоторые фрактальные изображения, как правило, напоминают реальные географические регионы. В частности, фракталы IFS могут быть использованы для довольно реалистичных растений и деревьев, а также местности.

фрактал.c — простое монохроматическое множество Мандельброта с зумом по умолчанию.


Добавлено:

Контекстно-свободные грамматики могут использоваться для выражения уравнений, которые могут рисовать изображения, эстетически приятные для человека. Джаред Тарбелл имеет связанную галерею замечательных изображений, сгенерированных программами. Алгоритм Чернил

2-е добавление Аза

Другая основная форма алгебраического или вычислительного искусства происходит от Клеточного автомата (CA), такого как (Джон) Игра жизни Конвея, прославленная 1970 Scientific American, написанной Мартином Гарднером. CA была вновь представлена публике с самостоятельной публикацией Стивена Вольфрама A New Kind of Science (NKS) в 2002 году. Это, как правило, замкнутые динамические системы, которые «живут» или «умирают», основанные на простом наборе правил.

С фракталами связаны хаотические системы или нелинейные динамические системы, если вы хотите звучать умно. Они могут быть смоделированы на физических системах, таких как прогнозирование погоды, и могут обеспечить не очень случайный, но трудно предсказуемый числовой выход, который можно визуализировать как странный аттракторSA).

10
ответ дан 29 November 2019 в 05:47
поделиться

Хммм. Я вспоминаю, как давно сделал генератор страны в логотипе. Основная стратегия заключалась в том, чтобы засеять его художником для каждого цвета и иметь правило: «Цветные художники перемещаются случайным образом, но не могут перемещаться по окрашенной области, если она не окрашена в их собственный цвет». В результате получилось несколько непрерывно закрашенных участков. Художники беспорядочно перемещались в 4 направлениях, а размер сетки составлял примерно 50x50.

Сделав это, я взял свое изображение 50x50, расширил его (с ближайшим соседом) до чего-то намного большего и использовал некоторые стандартные графические фильтры (размытие и т.п.), чтобы оно выглядело прилично. Если вам нужно монохромное изображение, просто сделайте все границы черными, а все остальное - белыми.

Эта стратегия вообще не поддерживает прямые линии.

2
ответ дан 29 November 2019 в 05:47
поделиться

Это может быть скорее следствием вашей проблемы чем ее решение, но я видел интересные результаты, глядя на вашу идею под другим углом:

Возьмите сетку (постройте ее из квадратов, шестиугольников или чего-то еще) и сгенерируйте случайное поле точек на Это. Теперь рассмотрим все возможные способы соединения этого фиксированного набора точек с помощью линий, следующих за сеткой. Возьмите фрагменты изображений с похожей темой (например, листья) и преобразуйте их в стиль «штриховая графика», чтобы уменьшить их до контура. Для каждого набора из нескольких точек просмотрите свою библиотеку элементов контура и попытайтесь найти ту, которая может соединить точки (или, по крайней мере, приблизиться, это может потребовать вращения, зеркального отражения и т. Д.). Вы обнаружите, что существует множество возможных результатов, но если все будет сделано правильно, вы можете получить многие из них, которые выглядят как листья (даже если это «новые» типы листьев, которых никогда раньше не видели)!

1
ответ дан 29 November 2019 в 05:47
поделиться

Вместо прямой случайности вы можете добавить к поведению какое-то тривиальное состояние.Например, вместо выбора того, что делают x и y , на основе P , где P по существу равно rand% 2 вы можете выбрать их на основе условного уравнения. В качестве простого примера:

http://img121.imageshack.us/img121/9018/twostate.png

с двумя состояниями, если вы разрешаете состоянию 1 представлять «поддерживать текущий путь» и 0 для «изменения направления», тогда, регулируя порог Q , вы управляете частотой, с которой вы меняете направление. Добавление состояний добавляет сложности, но вы, вероятно, получите умеренно интересные результаты с тщательно подобранными значениями для P и Q .

1
ответ дан 29 November 2019 в 05:47
поделиться

Вопрос, который вы задаете, является эстетическим . То, что один человек считает «хорошим», «красивым» или «умеренно интересным», настолько сильно различается от человека к человеку, что я не думаю, что можно найти лучший ответ на этот вопрос.

Я знаю многих людей, которые сочли бы фотографию, которую вы разместили в своем вопросе, отвратительной и лишенной заслуг, пронизанной идеями социально-политической смирительной рубашки, которой является градостроительство. Однако Я думаю, что это выглядит интересно.

2
ответ дан 29 November 2019 в 05:47
поделиться

В духе полного разрушения моих собственных (по общему признанию произвольных правил, я пошел вперед и сам создал ответ!

В коде используется очень простой код кривой Безье Я собрался вчера вечером, и, хотя ответ не столь убедительно интересен, он все же немного забавен.Код Безье можно найти здесь и здесь .

In В дополнение к редактированию поля snip, я также добавил, конечно,

#include "bezier.h"

Это не очень хорошо работает без этой строки.;)

/// NO EDITING ABOVE THIS LINE; EXCEPT AS NOTED

Bezier *path = newBezier(newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height));

float t;
Point *point = NULL;

for (t = 0.0; t <= 1.0; t += 0.00000006) {
  point = bezierPoint(path, t, point);

  int32_t x = point->x, y = point->y;

  if (x >= 0 && x < width && y >= 0 && y < height)
    imageBuffer[y][x] = 255;
}

destroyPoint(point);

/// NO EDITING BELOW THIS LINE
0
ответ дан 29 November 2019 в 05:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: