Русский
Русский
English
Статистика
Реклама

Генеративное искусство

Перевод Чему я научился за (почти) 30 дней Codevemberа 30 скетчей на p5.js

15.06.2020 20:17:21 | Автор: admin
image

Что такое #codevember и зачем он нужен? В последние пару лет каждый ноябрь я натыкался в соцсетях на интересные произведения искусства, созданные ИИ, отмеченные этим хэштегом. Согласно информации с codevember.xyz:

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

В этом году я решил попробовать поучаствовать и в ноябре изучить Processing (p5.js) и побаловаться созданием графики, которая создана не для какой-то определённой задачи.



Подготовительной работой лучше заниматься в фоновом режиме



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

Я раньше читал Природу кода Дэниэла Шиффмана. Он начинал с броуновского движения и текучих форм, которые, как я думал, могли быть использованы в точке размещения пера для рисования.

image

image
Стандартное случайное блуждание, и затем использование координат для рисования линий и кругов

Темп важен



Соблюдение постоянного темпа позволило мне не забыть синтаксис и размышлять, совершенствуя скетчи в течение нескольких дней, а не начинать с нуля каждый раз. Хоть иногда это казалось жульничеством, порой результаты меня радовали.

image
image
image
image
Использование текучих форм как инструмента для рисования

Легко впишется в твой день, но не в каждый


Я был довольно-таки постоянным, но несколько дней я пропустил и наверстал на следующий день, сделав два скетча. Был и день, который я не наверстал. Имея семью и работу с полным рабочим днём, втиснуть новую привычку, которая может занять до 30 минут, не всегда возможно.
image
image
Цвет волны на картине Хокусая отбирается и перерисовывается в виде рисунка брызгами и проецируется в случайные 3D плитки, отсортированные по осветлённости

Ежедневные скетчи не лучший способ изучения нового языка


Учитывая мои ограничения по времени и способности вникнуть, большая часть обучения языку Processing прошла в спешке. Я много изучал примеры, чтобы разобраться в возможностях p5.js и часто брал и адаптировал чужой код, чтобы заставить всё работать. Всё это работало, но у меня не было особо времени выучить всё до автоматизма.

image
Перисто

Я отдаю предпочтение одной цветовой гамме


Что мне нравилось в работе с цветами в p5, так это цветовое пространство HSB (тон насыщенность яркость). Оно куда более интуитивно понятно, чем RGB (кто-то вообще задумывается о том, сколько красного, зелёного и синего в цвете?) или HEX. Несмотря на доступ к новым методам кодирования цветов, меня постоянно тянуло назад к моим обычным цветовым привычкам. Не то что бы это было плохо, просто вещь, которую я для себя осознал.

image
Обычно это тёмный фон, узкий диапазон приглушённых цветов, иногда использование режима наложения Dodge

(И теперь я понимаю, что годами упускал из виду цветовые режимы HSB/HSL в d3.js)

Комплексные системы золотая середина


Несколько дней спустя я нашёл онлайн курс, который называется Generative Art and Computational Creativity from Philippe Pasquier, который до сих пор прохожу. История ИИ искусства куда глубже и шире, чем я мог себе представить, и есть формализованная систематика, что хорошо. Эта диаграмма форм поведения ИИ систем как раз донесла до меня, что я искал и почему мне порой нужно столько времени, чтобы решить, что скетч готов.

image

Фиксированные системы (fixed) формируют единственный статический вывод; периодические системы (periodic) колеблются между двумя или более состояниями; хаотичные системы (chaotic) не формируют никакого предсказуемого образа (я думаю, не считая вещей, типа странных аттракторов), но комплексные системы (complex) дают нам структуру и стабильность периодических систем и координированную рандомность хаотичных систем.

image

Неправильное использование тоже стратегия



Порой я застревал на некоторых моментах, пытаясь создать что-то в 3D. И чисто возясь с кодом я создавал, в конце концов, что-то далёкое от того, что я пытался сделать, но достаточно интересное, чтобы назвать это скетчем. Вместо того чтобы передвигать 3D фигуру во времени, я рисовал поверх ещё одну слегка изменённую фигуру, и получалась многослойная фигура.
image
image
image
Ошибки сделаны

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

image
David Hockney, The Scrabble Game, 1983

Я прорываюсь к координированному разрушению красивой математики



Совершенные формы хороши, но оторваны от жизни. Интрига кроется в изъянах: что пошло не так с этим прекрасным планом действий?

Изображая и создавая системы, содержащие в себе одновременно структуру и правила вместе с шумом и рандомом, я работаю больше над раскрытием красоты в неожиданных проявлениях.

image

Забавно наблюдать за тем, как эти скетчи рисуют сами себя.

Посмотреть всю коллекцию можно на гитхабе.

Если вы хотите попробовать еще что-то или начать с более простых проектов:

Подробнее..

Перевод Использование микрофона для создания произведений искусства, реагирующих на звук, на Javascript

18.06.2020 16:09:14 | Автор: admin
Несколько приёмов для создания произведений процедурального (генеративного) искусства.

image

Настройка объекта для микрофона вещь достаточно лёгкая, хоть и сначала может показаться сложной. Не надо волноваться. Даже если вы это не очень понимаете, то и не нужно. Потому что когда всё настроено и работает, вам больше никогда не придётся проделывать это всё снова



Куча туториалов могут объяснить это более подробно, но я что-то не видел советов, как перейти с Hello world на следующий уровень. Об этом я и хочу вам рассказать.

Не откладывая в долгий ящик предупрежу, что это не работает в Safari. И никогда не работало. Есть баги, благодаря которым может сработать Но давайте реально, меня уже достал поиск обходных путей в этих не ахти каких браузерах. Как и вас, думаю.


И ещё заметьте: с прошлого года нужно https соединение, чтобы использовать микрофон. Если вы используете что-то вроде Live Server от Atom (а его использовать стоит, поверьте мне), микрофон настроится автоматически.

Итак, сначала очень скучное дело, настройка микрофона Только не пугайтесь

function Microphone (_fft) {  var FFT_SIZE = _fft || 1024;  this.spectrum = [];  this.volume = this.vol = 0;  this.peak_volume = 0;  var self = this;  var audioContext = new AudioContext();  var SAMPLE_RATE = audioContext.sampleRate;    // это просто проверка браузера на то,   // поддерживает ли он AudioContext и getUserMedia  window.AudioContext = window.AudioContext ||  window.webkitAudioContext;  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;  //теперь просто ждите запуска микрофона  window.addEventListener('load', init, false);  function init () {      try {        startMic(new AudioContext());      }      catch (e) {        console.error(e);        alert('Web Audio API is not supported in this browser');      }  }  function startMic (context) {    navigator.getUserMedia({ audio: true }, processSound, error);    function processSound (stream) {     //анализатор определяет частоту, колебательный сигнал и т. д.     var analyser = context.createAnalyser();     analyser.smoothingTimeConstant = 0.2;     analyser.fftSize = FFT_SIZE;     var node = context.createScriptProcessor(FFT_SIZE*2, 1, 1);     node.onaudioprocess = function () {       // число битов возвращает массив, а это половина FFT_SIZE       self.spectrum = new Uint8Array(analyser.frequencyBinCount);       // getByteFrequencyData выдаёт амплитуду для каждой ячейки       analyser.getByteFrequencyData(self.spectrum);       // getByteTimeDomainData определяет громкость за определённое время       // analyser.getByteTimeDomainData(self.spectrum);       self.vol = self.getRMS(self.spectrum);       // get peak  костыль, если громкость низкая       if (self.vol > self.peak_volume) self.peak_volume = self.vol;       self.volume = self.vol;     };     var input = context.createMediaStreamSource(stream);     input.connect(analyser);     analyser.connect(node);     node.connect(context.destination);  }  function error () {     console.log(arguments);  }}//////// SOUND UTILITIES ..... потом вставим сюда ещё чего-нибудь....return this;};var Mic = new Microphone();


Это даст нам массив амплитуд на наших частотах (использую 512 по умолчанию), представленные как Mic.spectrum. Окей, давайте начнём играть

Получение полной громкости.



image
Пошумим!

Я нечасто это использую, но это удобно и можно использовать в куче других утилит. Чтобы получить полную громкость или уровни, мы используем функцию getRMS(). RMS лучше указывает громкость входящего звука, он суммирует все громкости всех частот спектра. Итак, функция, которую мы добавим в Mic() выглядит так:

// A more accurate way to get overall volumethis.getRMS = function (spectrum) {var rms = 0;  for (var i = 0; i < vols.length; i++) {    rms += spectrum[i] * spectrum[i];  }  rms /= spectrum.length;  rms = Math.sqrt(rms);  return rms; }


И мы можем сделать простенькую анимацию, как ту, что выше, так:
var ctx = createCanvas("canvas1");ctx.background(235);function draw(){var s = Mic.getRMS();  ctx.fillStyle = rgb(s*2);  ctx.HfillEllipse(w/2, h/2, s*5, s*5);}


Получение спектра звука



image

Наш Mic() выдаёт Mic.spectrum, массив амплитуд или громкостей по всему спектру (или FFT_SIZE, у меня 512 по умолчанию). Мы можем использовать их как есть, вот так:

var ctx = createCanvas("canvas1");// сделайте сетку 200 по ширине// Как создавать сетки я показал тут [https://hackernoon.com/creative-coding-grids-2e6bcaa07596#.u4zyrccxr]var grid = new Grid(200, 1);function draw(){ctx.background(235);for (var i = 0; i < grid.length; i++) {    var s = Mic.spectrum[i];    ctx.fillStyle = hsl(map(i, 0, grid.length, 0, 360), 80, 50);    ctx.fillRect(grid.x[i], h - s, grid.spacing_x-1, s);  }}


Однако, я считаю, что было бы удобнее и эффективнее построить функцию отображения звука.

Отображение звука.



image

Если бы у нас было, к примеру, только 20 объектов, но наш спектр выдавал 512 частот (что является значением по умолчанию для объекта Mic()), было бы разумно распределить амплитуды, чтобы получить более чёткое отображение того, что происходит с нашим звуком. Поэтому давайте переотобразим наш спектр.

Чтоб начинающим было легче, я буду достаточно часто использовать простую map() функцию, которая хранится в моем главном файле creative_coding.js, и выглядит вот так:
function map(value, min1, max1, min2, max2) {var returnvalue = ((value-min1) / (max1 - min1) * (max2-min2)) + min2;return returnvalue;};


Основываясь на этом, мы можем сделать mapSound() функцию, чтобы равномерно распределять значения. Это, скорее всего, самый ценный инструмент анализа звука. Я использую его почти каждый день. Супер удобно и просто.

this.mapSound = function(_me, _total, _min, _max){if (self.spectrum.length > 0) {   // обозначьте значения по умолчанию, если другие не даны   var min = _min || 0;   var max = _max || 100;   //actual new freq   var new_freq = Math.floor(_me * self.spectrum.length /_total);   // обозначьте громкость до хороших значений   return map(self.spectrum[new_freq], 0, self.peak_volume, min, max);  } else {    return 0;  }      }


Мы затем можем легко создать спектр вот так:

image
Тест, тест, 1, 2, 3.

Визуализация спектра сделана из сетки, звук обозначается по длине сетки. Я также обозначил выданные значения (_min и _max) как 5 и высоту/4, чтобы лучше выглядело:

var ctx = createCanvas("canvas1");// make a grid 200 widevar grid = new Grid(200, 1);function draw(){ctx.clearRect(0,0,w,h);for (var i = 0; i < grid.length; i++) {    // Mic.mapSound(_me, _total, _min, _max)    var s = Mic.mapSound(i, grid.length, 5, h/4);    ctx.fillStyle = rgb(0);    ctx.fillRect(grid.x[i], grid.y[i] - s/2, grid.spacing_x-0.5, s);  }}


На самом деле, mapSound() сможет позаботиться о всех нуждах, связанных с анализом звука. Чаще всего, именно простота лучше всего работает для визуализация звука. Фишка творческого кодинга просто выстраивать простые биты друг на друге, чтобы получились сложно выглядящие творения. Так, например, мы можем использовать некоторые приёмы Math.cos и Math.sin, чтобы сделать красивый круглый спектр:

image
Мам, смотри, круглый спектр

Вот код-пример: просто создать кучи частиц и распределить длину каждой линии частицы к соответствующей громкости:

var ctx = createCanvas("canvas1");var num_items = 200;var radius = 100;ctx.lineWidth = 2;var particles = [];// работаем над углами for (var i = 0; i < num_items; i++) {  var angle = radians(distributeAngles(i, num_items));  particles[i] = {    x: w/2 + Math.cos(angle) * radius,    y: h/2 + Math.sin(angle) * radius,    angle: angle  }}function draw(){ ctx.background(0); for (var i = 0; i < num_items; i++) {  var p = particles[i];  var s = Mic.mapSound(i, num_items, 5, 100);  // map to greyscale  //ctx.strokeStyle = rgb(map(i, 0, num_items, 0, 255));      x2 = w/2 + Math.cos(p.angle) * (s + radius);  y2 = h/2 + Math.sin(p.angle) * (s + radius);  ctx.line(p.x, p.y, x2, y2); }}


И этот код может быть адаптирован в нечто типа этого это одно из моих первых визуально-звуковых творений на Javascript.

image

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

Как всегда, полный код можно найти у меня на github.

Счастливого кодинга!
Подробнее..

Перевод Визуализация изменения климата при помощи интерактивного генеративного искусства

28.10.2020 14:12:50 | Автор: admin

Чтобы мотивировать людей активнее бороться с изменением климата необходимо постоянно искать новые креативные способы. Их много: начиная от привлечения внимания к через крупные мероприятия, вродеDavos 2020, вплоть до визуализации последствий глобального потепления при помощи современных технологий обработки данныхи интерактивного генеративного искусства.

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

Не важно, насколько кейс заметный или наоборот, трудно понятный на первый взгляд, - цифровой подход оказывает сильное влияние, ведь сегодня люди всё большую часть своей жизни проводят онлайн. Технологии уже доказали свою способность изменить будущее человечества к лучшему, так почему бы не использовать цифровое пространство для привлечения внимания к проблеме климата?

Интерактивное генеративное искусство - едва заметное, но влиятельное

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

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

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

Благодаря генеративному подходу ландшафт достаточно необычен, ибо он всегда уникален для зрителя, но в тоже время расположение ключевых элементов всегда одинаково. Каждый раз, когда пользователь пользуется приложением, система создаёт уникальные графические элементы. Дерево, небо, облака и т. д. нарисованы с нуля, используются данные о погоде прямо сейчас, согласно местоположению пользователя.

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

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

Для реализации этого проекта использовался JavaScript, визуальные элементы нарисованы при помощи Canvas. Ландшафт состоит из четырёх главных компонентов: дерево, земля, небо и осадки. Этого достаточно, чтоб показать времена года и основные погодные условия.

Дерево

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

Нужно сгенерировать массив веток, или точнее - массив качеств веток. У каждой ветки должен быть свой угол наклона по отношению к ветке-родителю, своя длина и цвет, наклон листьев. Длина и угол наклона веток выбирается случайно согласно глубине дерева. Однако, нужно добавить или вычесть угол ветки-родителя. Так мы получаем две ветки, торчащие в разных направлениях.

Крона дерева не однородна, как, например, сфера, а состоит как бы из групп сфер. В результате цвета листьев разные, ибо некоторые из них темнее, а некоторые светлее. Поэтому крона поделена на две части, а каждая группа прокрашена слева направо плавной палитрой, переходящей от самых ярких к самым тёмным цветам. Функция divide(start,finish,intervalsAmount,n) делит числовой интервал между startиfinish на сумму интервалаintervalsAmount, и определяет интервал, включающий n.

const branchGroupDepth = 10; const leavesGroupSize = 2 ** (branchGroupDepth-1); let groupCounter = 0; function generate(angle, depth, arr) { let leafColor = colors[divide(0, leavesGroupSize, colors.length, groupCounter)]; arr.push({ angle, branchArmLength: random(minBranchLenght, maxBranchLenght), color: leafColor }); if (depth === branchGroupDepth) { groupCounter = 0; } if (depth === 0) { groupCounter++; } if (depth != 0) { if (depth &amp;gt; 1) { generate(angle - random(minAngle, maxAngle), depth - 1, arr); generate(angle + random(minAngle, maxAngle), depth - 1, arr); } else { generate(angle, depth - 1, arr); }}}

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

windSidewayForce - направление движения ветки по направлению ветра.

bendabilityOfCurrentBranch - коэффициент наклона ветки по ветру, зависящий от толщины ветки (или глубины дерева).

calcX(angle, r)/calcY(angle, r) функции, которые вычисляют координаты концов веток при помощи формулыrcos(angle)/rsin(angle).

let branchCounter = 0; const bendability = 2; const leafBendability = 17; function branch(x1, y1, arr, depth, windConfig) { if (depth != 0) { const xx = calcX(dir, depth * branchArmLength); const yy = calcY(dir, depth * branchArmLength); const windSidewayForce = windX * yy - windY * xx; const bendabiityOfCurrentBranch = (1 - (depth * 0.7) / (maxDepth * 0.7)) ** bendability; dir = angle + wind * bendabiityOfCurrentBranch * windSidewayForce; let x2 = x1 + calcX(dir, depth * branchArmLength); let y2 = y1 + calcY(dir, depth * branchArmLength); lines[depth].ush([x1, y1, x2, y2]); if (depth &gt; 1) { branch(x2, y2, arr, depth - 1, windConfig); branch(x2, y2, arr, depth - 1, windConfig); } else { branch(x2, y2, arr, depth - 1, windConfig); } } else { const leafAngle = angle + wind * windSidewayForce * leafBendability; leaves[color].push([x1, y1, leafAngle]); } }

Ветки дерева прокрашиваются простойlineTo()канвас функцией, и каждая ветка - линия. Листья красятся двумя кривыми Безье при помощи функции bezierCurveTo(). Кривые Безье состоят из трёх точек: начало (синяя), конец (синяя) и контроль (жёлтая). Последняя придаёт кривой форму.

Покраска листьев кривыми БезьеПокраска листьев кривыми Безье

Однако, у канвас функций есть определённая особенность: нельзя красить несколько фигур несколькими цветами или несколькими движениями одновременно. Поэтому все ветки сгруппированы по толщине, а все листья - по цвету. Чтобы ускорить рендеринг, их красят группами. Также холсты деревьев хранятся под ключом (индикатором ветра), чтобы увеличить скорость рендеринга. Это означает, что программе не нужно каждый раз вычислять с начала каждое дерево, используя один индикатор ветра.

Земля

Земля (или, скорее, трава) не менее важна, чем дерево, ибо трава может показывать ветер и времена года. Нужен массив столбцов, чтобы сгенерировать траву. Каждый столбец травы должен иметь свои координаты, обозначающие положение в поле, скорость реакции на ветер и угол наклона по отношению к земле. Более близкие столбцы травы должны иметь более насыщенный и контрастный цвет, а дальние должны казаться более сглаженными. Эта визуальная хитрость даёт ощущение травяного поля. Поле поделено на горизонтальные части, у каждой части свой цвет столбцов. После генерации массива поле нужно отсортировать от самых дальних до близких по y координате для эффекта наложения друг на друга.

function generate(number) { for (var i = 0; i &lt; number; i++) { var y = random(fieldTopStart, h + fieldBottomDeviation); var x = random(0, w); var colorGroup = divide(fieldTopStart, h + fieldBottomDeviation + 1, fieldAreas, y); var color = colors[colorGroup][random(0, colors[colorGroup].length)]; var angle = random(-maxAngleDeviation, maxAngleDeviation); var speed = random(minSpeed, maxSpeed); dots.push([x, y, color, angle, speed]); } dots.sort()}

Столбец травы, как и листья, красится двумя кривыми Безье. К тому же, трава реагирует на ветер наклоном. Координаты конца столбца и контрольные точки вычисляются согласно индикатору ветра.

Столбец травы красится двумя кривыми БезьеСтолбец травы красится двумя кривыми Безье

Небо и осадки

Облака и количество облаков - самые главные характеристики неба. Облака должны различаться по размеру относительно положения в небе. Поэтому небо поделено на горизонтальные части: в более высоких частях находятся большие облака, двигающиеся быстрее.

Облака содержат в себе круги двух типов. Первый тип - градиентные белые круги с градиентным центром в середине. Эти круги распределены равномерно по всей плоскости облака. Второй тип - градиентные серые круги со смещением вниз от центра. Они размещаются внизу плоскости облака и делают облако объёмным. Однако, облака перемещаются не только по небу, а ещё и внутри самих себя, меняя форму. Каждый круг динамичен и двигается по круговой траектории со своим центром.

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

Как выглядит генеративное искусство, основанное на погоде?

После некоторых манипуляций, включающих использование разных цветов для разных времён года и интеграцию с живыми данными, мы можем показать через живое окно весь год.

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

Ещё один полезный аспект - то, что через живое окно можно показать рост растений. Было бы интересно увидеть, сколько времени нужно определённым растениям для достижения зрелости. Есть ещё шкала Бофорта, которая показывает силу ветра. Она может показывать, как сильно ветер влияет на деревья, давая пользователю реалистичное восприятие силы ветра.

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

Популярные посты по генеративному искусству:

Подробнее..

Нейроссия как я научил нейросеть рисовать русскую хтонь

01.01.2021 18:11:05 | Автор: admin

Вступление

В России модно грустить. Популярная культура под разными соусами толкает нам депресняк: всякие майки "Россия для грустных", фестивали "боль", подборки "Russian doomer music" на ютубе и так далее. Рунет завален однотипными постпанком, панельками и серостью, которые тем не менее довольно много людей видят чем-то родным и уютным, ощущают частью своего культурного кода. Мне стало интересно, сможет ли ИИ если не победить то хотя бы возглавить эту моду и затронуть струны душ рашн думеров. Ведь что может быть более бессмысленно и тоскливо чем нейросеть, рисующая гипертрофированно-хтоническую Россию? Так появился проект нейроссия.

Собираем данные

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

Примеры скачанных фотографийПримеры скачанных фотографий

Чтобы выкачать фотки, лайки и комменты я воспользовался python-библиотечкой vk_api. Этот модуль позволяет работать с методами api вконтакта, а также обрабатывать капчу и двухфакторную аутентификацию. В качестве примера приведу скрипт скачивающий фоточки из последнего поста на стене сообщества:

Качаем картинки из последнего поста на стене группы
import osimport vk_apiimport urllib.requestdef captcha_handler(captcha):    print (f"url: {captcha.get_url()}\n")    key = input("Enter captcha code: ")    return captcha.try_again(key)def auth_handler():    code = input("Enter 2FA code: ")    return (code, True)def save_post_pictures(post, imgfolder, imres):    pictures = []        if not os.path.exists(imgfolder):        os.makedirs(imgfolder)        for attachment in post['attachments']:        if attachment['type'] == 'photo':            photo = attachment['photo']            for size in photo['sizes']:                if size['type'] == imres:                    url = size['url']                    filename = ('_'.join(url.split('/')[-2:])).split('?')[0]                    urllib.request.urlretrieve(url, os.path.join(imgfolder, filename))                    pictures.append(filename)                        return picturesphone = input("phone ")password = input("password ")domain = 'plattenbauten' # vk.com/plattenbautensess = vk_api.VkApi(phone, password, captcha_handler=captcha_handler, auth_handler=auth_handler)sess.auth()api = sess.get_api()posts = api.wall.get(domain=domain, count=1)['items']save_post_pictures(posts[0], domain, 'z') # https://vk.com/dev/photo_sizes - z максимальный размер

Так я накачал чуть больше чем 100к фоточек из нескольких пабликов. Дальше встал вопрос, как их отфильтровать. Для фильтрации я использовал детектор EfficientDet (чтобы выкинуть из датасета фотки с людьми, машинами, котиками и.т.д, оставив только пейзажи), а также совсем чуть-чуть NLP в лице NLTK чтобы обработать подписи к фотографиям - сделать стемминг слов и найти по тегам то что не нашёл детектор. В итоге осталось около 10к фотографий.

Обучаем стайлган

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

У этой реализации стайлгана есть одна особенность - на вход ему нужны данные в формате .tfrecord (как их получить из картинок описано в readme). А особенность заключается в том, что картинки записываются в tfrecord-ы без сжатия, что в условиях работы на Colab может быть критично. Так, например, датасет из 10 тысяч картинок разрешения 1024х1024, будучи сконвертированным в .tfrecord забьёт диск Колаба под завязку. Говорят, что есть модификация stylegan2 которая использует сжатие в .tfrecord-ах, но я её пока не проверял.

Отчего так в России берёзы шумят?Отчего так в России берёзы шумят?

Обучение на Google Colab в бесплатной версии идёт со скоростью примерно полчаса на эпоху для разрешения 1024х1024. Когда уже на первых эпохах на генерируемых сеткой картинках проступила родная цветовая гамма, вспомнился мем про "отчего так в России берёзы шумят".

Несколько эпох спустяНесколько эпох спустя

Генерируем видео

В какой-то момент проект из гиковских прикольчиков превратился в прикольчики творческие. Возникла идея привлечь к этому друзей-музыкантов и сделать генеративное видео с генеративной музыкой (впоследствие трансформировавшаяся в вариативный стрим на платформе mubert). Хотелось чтобы переходы в видео были хоть немного осмысленными и согласующимися с музыкой.

Латентный вектор это промежуточное сильно сжатое представление картинки, в котором скрыты все выученные нейросетью свойства. Наверное, можно было заморочиться и найти в латентном векторе (размерности 512) компоненты отвечающие за тот или иной параметр картинки (чтобы например плавно менять освещение, сохраняя структуру картинки), но я решил что проще сгенерировать видео по ключевым кадрам. Если плавно переходить от вектора соответствующего одной картинке (ключевому кадру) к вектору соответствующему другой, то картинки также будут плавно перетекать одна в другую. Для этого я поменял несколько строк в скрипте generate.py так, чтобы на вход он принимал папку с латентными векторами выбранных картинок, и список, в котором эти картинки должны появляться в видео.

В заключение

С появлением таких архитектур как stylegan, генеративное искусство набирает обороты - некоторые даже успешно продают генеративные картины за сотни денег, не написав ни строчки кода. Надеюсь, эта статья натолкнёт кого-то ещё на идеи применения нейросетей в искусстве, тем более что сервисы типа Colab существенно снижают порог вхождения и затраты для получения интересных результатов.

Ещё картиночкиЕщё картиночки

Ссылки

https://vk.com/neurussia - нейроссия в ВК

https://github.com/NVlabs/stylegan2-ada - нейросеть Stylegan2-ada

https://github.com/python273/vk_api - python-обёртка api вконтакте

Подробнее..

Перевод Как заставить генеративные изображения выглядеть естественно при помощи математических алгоритмов

16.06.2020 18:07:02 | Автор: admin
image

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

Этот пост не о языке и не о фреймворке. Мы будем говорить только о технике.

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



Ведущий принцип: моделируйте свои работы на основе реальности



Если возможно, подумайте, как бы вы изобразили своё творение на бумаге или как бы оно могло выглядеть в реальном мире. Моделирование реального физического процесса, скорее всего, приведёт к реалистично выглядящей работе.

Например, равномерно распределённые данные обычно не встречаются в природе. Большая часть данных представляет из себя что-то вроде колоколообразной кривой. Использование нормально распределённых случайных величин (те, что со средним значением и стандартным отклонением) чаще всего создаёт более естественный эффект, чем случайный выбор из промежутка или списка.

Линии


Предположим, что у нас есть тип данных, представляющий из себя отрезок. Чтобы нарисовать его, обычно мы делаем как-то так:

1. Выбрать начальную точку
2. Выбрать конечную точку
3. Провести черту между точками

В результате получается что-то такое:

image

По-моему, слишком идеально!

Случайный наклон



Предположим, что мы рисуем несколько горизонтальных линий, и мы хотим их сделать более естественными. Сперва можно немного подвинуть конечные точки линий. Мы можем сделать это, переместив их, используя нормальное распределение с небольшим стандартным отклонением в х и у направлениях.

image

Волнообразное колебание



Теперь у нас линии, которые немного смещены от изначально заданной позиции. И немного различаются по длине. Однако, они совершенно прямые. Это не похоже на линии, которые мы встречаем в реальном мире. Давайте сделаем их менее прямыми.

Например, это можно сделать так:

1. Выбрать N точек между конечными точками отрезка, чтоб создать новую линию.
2. Сместить каждую точку.
3. Смягчить линию и нарисовать её.

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

image

Влияние соседних точек



Хорошо, у нас начало что-то получаться. Изменение параметров стандартного отклонения позволяет нам контролировать колебания нашей линии. Однако, вы, наверное, заметили, что колебания независимы друг от друга. Линия может колебаться, то приближаясь к соседней верхней, то к нижней линиям. Чтобы уберечься от этого, я предлагаю такой вариант.

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

image

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

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

Текстурирование линий



Теперь наша линия выглдяит достаточно естественно. Но мы всё ещё рисуем идеально точной ручкой, когда мы вызываем функцию stroke(). В реальном мире, когда мы используем различные инструменты для рисования, у них есть различия в текстуре. Один из способов внести эти различия использовать технику песчаных сплайнов, популяризованную Андерсом Хоффом (a.k.a inconvergent). Идея проста:

1. Совсем чуть-чуть скорректируйте каждую точку линии, используя нормальное распределение.
2. Сгенерируйте ещё несколько точек, между каждой соседней парой точек, и нарисуйте их в виде крошечных точечек.
3. Повторите несколько раз.

Если ваши точки супер маленькие, то получится такая текстура:

image

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

image
Сон о пустыне (2018) Текстурированные линии основа многих моих работ.

Формы



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

Мы можем просто нарисовать квадрат.

image

Можем применить уже упомянутый принцип случайного наклона, понемногу изменив каждый угол.

image

Можно выбрать и сгладить точки между каждой соседней координатой, чтобы получить кривой квадрат.

image

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

image

Ничего из этого не ново. Мы здесь, по сути, говорим только о замкнутых отрезках, поскольку мы просто сглаживаем углы. А что насчёт заполнения пространства? Мы можем использовать функцию fill(), но это немного скучно.

image

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

image

* Примечание: можно это сделать, поделив квадрат на 2 треугольника и сгенерировав точку в каждом при помощи равномерного распределения.

Хотя выглядит это немного неаккуратно, поскольку равномерное распределение не настолько интуитивно понятно, как кажется. Для более естественного распределения точек, можем взять значения из одной из моих любимых последовательностей Последовательности Хальтона (2.3)[можно почитать про нее в классной статье].

Последовательность Хальтона (2.3) генерируют точки в промежутке (0, 1) (0, 1) в R2. Чтобы заполнить квадрат точками, сгенерированными в этой последовательности, мы можем:

1. Найти минимальный ограничивающий квадрат, содержащий в себе Прямоугольник.
2. Сгенерировать N точек в (2.3) последовательности Хальтона.
3. Градуировать каждую точку по ширине (или высоте) минимального ограничивающего квадрата.
4. Переместить точку по верхней левой координате квадрата.
5. Отфильтровать все точки, которые не лежат в Квадрате.

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

В общем, (2.3) последовательность Хальтона генерируется просто; прочитайте про псевдокод в википедии (eng). Вот заполнение штрихом на 10000 точек.

image

Поскольку (2.3) последовательность Хальтона генерируется не рандомно, она создаёт одинаково выглядящие текстуры. Пара способов обойти это:

1. Градуирование и (по желанию) лёгкое раскачивание ограничительного квадрата, чтобы сместить центр последовательности.
2. Отбрасывание N точек с начала последовательности.
3. Рандомное отбрасывание малой части точек из последовательности (но осторожно, это создает больше шума).

Конечно, эти подходы можно совмещать. Экспериментируйте!

Ещё один привычный способ генерации таких текстур использование избыточной выборки сглаживания. Это стохастический процесс, но он ещё и более требователен к ресурсам для вычисления и внедрения. Но он очень хорош. Я использовал этот способ в моей серии Провод, вот одна из работ.

image
Провод Т


Конечно же, это не единственный подход к текстурированию.

Цвет


Чувствовать, какие цвета сочетаются друг с другом очень, очень сложно. Легко выбрать цвета, которые по твоему мнению хорошо сочетаются, но потом понять, что они совершенно не сочетаются и заставляют твою работу выглядеть в 10 раз хуже, чем в чёрно-белом варианте.

И я бы сказал, для генеративных художников этосоздает особую сложность. Стандартный способ варьировать цвета в генеративном искусстве вручную настраивать жёстко закодированные переменные и генерировать раз за разом картинку, пока не понравится. Игра с цветом и правда лучший способ научиться чувствовать, как их правильно использовать. Как мы можем его улучшить?

Вот мой подход, который я переделал из идеи Джошуа Дэвиса [https://joshuadavis.com/]. Вся суть:

1. В отдельной программе (я, например, использую AutoDesk SketchBook) сконструировать горизонтальную градиентную линию и сохранить в png.
2. Открыть png как пиксели в программе для создания генеративного искусства, и интерполировать между началом и концом градиента, используя функции плавности (функции с диапазоном выхода [0,1])

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

Мы будем использовать вот этот градиент для закрашивания точек в предыдущем примере (только точек в 20 раз больше).

image

Используемая нами функция плавности линейна по значению y. 0 обозначен на значении y верхней части квадрата, а 1 в нижней. Стоит заметить, что результат функции плавности (между 0 и 1) слегка смещается вместе с нормально распределённым случайным значением. Это помогает сформировать менее однородную структуру.

image

Отлично. И это всего лишь абсурдно простая функция плавности (и градиент, который я сделал за 5 минут). Представьте себе возможности!

Используем шум с пользой



Раз уж мы говорим о функциях плавности, а что там с шумом? Шум Перлина не совсем соответствует подходит для этой функции, так как его значения варьируются от -1 до 1. Но с умным mapping`ом, ограничением посторонних значений, модульной арифметикой с плавающей запятой и/или другими хитростями, конечно, мы можем сузить диапазон до [0,1].

Вот одна из моих серий Modular, в которой я использовал 2D шум как функцию плавности в цвете.

image

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

Если взглянуть внимательно, то можно заметить, что штрихованная структура тоже часть шума.

image

Стоит отметить, что простой шум Перлина может начать казаться безжизненным со временем. Попробуйте поэкспериментировать с фрактальным броуновским движением или разработать свою собственную шумовую функцию, с которой можно будет поиграться. Эссе Flow fields Тайлера Хобба хорошая вещь для углубления в тему (шум Перлина формирует бесконечные векторные поля, текучие поля это полезное обобщение).

Ощутимость



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

Это идея затронута подробно в Природе кода, которую я вам просто порекомендую, не цитируя Дэниэла Шиффмана. Дэниэл разделяет сложные физические проблемы на без проблем усваиваемые ломтики, упрощая реализацию каждой идеи. Делая свои творения, я часто запускаю на некоторое время физическую симуляцию и делаю снимок в определённый момент, который и становится финальной картиной.

Например, в картине Слащавая сыворотка на мяч влияет гравитация, который скачет по каждому квадратику в сетке. Направление гравитации определено дополнительным полем шума, и шарик оставляет след.

image

В основе Пылевой чаши лежит симуляция рвущейся резинки.

image

Как по мне, эти картины живые. И неудивительно, правда. Они тесно связаны с нашим ведущим принципом:

Моделируйте свои работы на основе реальности

Когда мы фокусируемся на симуляции естественных процессов в коде, мы получаем более естественную работу.

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

P. S. Здесь не было никакого кода не просто так. Эти идеи достаточно общие и применимые во многих языках и средах разработки, я не хотел бы никого отталкивать, заставляя перейти на что-то другое.
Подробнее..

Перевод Визуализация генеративных алгоритмов гифа, деревья, повторяющиеся и дифференциальные линии (на Python)

22.06.2020 02:19:54 | Автор: admin
image

ВВЕДЕНИЕ


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

image

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

Иногда мне удается воссоздать явление, которое я собирался создать, а иногда нет. Чаще всего я получаю нечто интересное, даже если это не всегда то, что было задумано.



ПРИЗНАНИЕ


Буду честным перед вами, я иногдаберу идею для своей работы из работ других художников. Особенно Джареда Тарбелла и Nervous System. К примеру, алгоритм, который я назвал Орбиталь (изображение ниже) сделан с очень сильной опорой на Happy Place Тарбелла.

image

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

INCONVERGENT (НЕСОСРЕДОТОЧЕННЙ)


Я начал работать с генеративными алгоритмами, когда должен был готовиться к экзаменам в университете. Именно поэтому я купил домен inconvergent.net, насмехаясь над тем, как я уклоняюсь от учёбы. Первое, что я сделал скопировал несколько алгоритмов Тарбелла с помощью Javascript/Canvas. Через некоторое время ко мне начали приходить уже собственные идеи.

image

Первым моим работающим алгоритмом, помимо Orbitals, был Hyphae. Он получился, когда я пытался воссоздать поведение гифы, сделанное Nervous System. На тот момент я не понимал, насколько сложный этот алгоритм на самом деле, и я потратил очень много времени, тщетно пытаясь сделать что-то сносное. Я все же смог сделать его, а еще вы можете прочитать работу Зигграфа (ENG) по этой теме, если интересно. Увлекательное чтиво!

КОД


Я выкладываю почти весь свой код на Github. Все следующие разделы имеют ссылку на соответствующий репозиторий. К сожалению, не все из них хорошо документированы или обновлены.

HYPHAE (ГИФА) [GITHUB]


Я начал экспериментировать с системой, где я выращивал связанные друг с другом круги, которые не могли накладываться друг на друга. Работает это так: вы где-нибудь помещаете начальный (круг), и задаёте ему радиус и направление движения. Затем пытаетесь добавить новый узел по периметру первого узла в направлении движения. Важно иметь направление движения, чтобы было немного колебания, и каждый раз угол немного отклонялся. Также обязательно каждый раз при добавление нового делаете радиус новых узлов немного меньше предыдущего.

image

Чтобы получить ветви, можно выбрать узлы наугад и попытаться вырастить новый узел более-менее перпендикулярно направлению движения ветви. И либо узлы столкнутся, либо вы получите новую ветку. Для более интересных результатов можно сделать углы отклонений пропорциональными ширине (радиусу) ветки. Более толстые ветки, как правило, прямее, чем тонкие. И вы, очевидно, можете сделать ещё много других вещей. Например, вы получите радикально разные результаты, если настроите то, сколько гибких ветвей вырастет по мере их утончения.

image

И ещё одно небольшое примечание: когда ветка откололась от существующей ветви, нужно сделать для нее радиус значительно тоньше ветви-предшественника. Вы можете увидеть это на деревьях в реальной жизни. Суть в том, что масса должна быть примерно одинаковой до и после пересечения ветки. (Я где-то вычитал это, но я не могу найти где).

ДЕРЕВЬЯ [GITHUB]


Когда мы говорили о ветках, я понял, что можно упомянуть и маленький эксперимент с деревьями, ведь они похожи по сути.

image

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

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

image

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

ПОВТОРЯЮЩИЕСЯ ЛИНИИ [GITHUB]


В отличие от Гифы, на которую меня вдохновила биология, и от алгоритмов деревьев, следующий пример основан на картинах, нарисованных рукой Джона Френзена. По большому счёту, Френзен рисует линии, где каждая линия следует по контуру ранее нарисованной линии. Каждая последующая линия будет немножко изменяться, и вскоре появляются интересные узоры.

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

Это значит, что рисовать эти линии так же, как Френсен, можно путём рисования округлых фигур со множеством вершин. Отслеживание формы немного сложнее, но есть несколько способов, которые можно опробовать. Я хотел, чтобы поведение имитировало то, как в реальности рисуется фигура, мало-помалу, при этом продолжая предыдущие линии. Алгоритм, который я придумал работал не совсем так. То есть, он не избегал столкновений, но результаты все равно выглядели очень хорошо.

image

Чтобы проследить контур, можно выбрать некоторые из соседних рёбер в предыдущей линии, рассчитать среднее направление этих рёбер и добавить вершину к текущей линии вдоль этого направления. Затем добавить несколько случайных движений для имитации рисунка от руки. Некоторое время такой подход работает довольно хорошо, но есть некоторая инертность, которую можно увидеть в результатах, форма адаптируется слишком медленно.
Количество шума, которое вы добавляете к каждой вершине, имеет решающее значение. Этот шум является тем, что заставляет всю систему создавать интересные формы, ибо коррекция формы вынуждает в процессе пытаться повторить как общее движение, так и некоторые случайные искажения.
Далее идет несколько более сложная система, которая тоже включает в себя линии.

ДИФФЕРЕНЦИАЛЬНАЯ ЛИНИЯ [GITHUB]


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

Прежде чем я начал прикидывать способы, я видел только Floraform, созданный Nervous System, но вам стоит увидеть ещё Cellular Forms Энди Ломаса. Другой важный документ, который я обнаружил гораздо позже, находится здесь.

Сначала я попытался использовать метод, основанный на фрактальной кривой Коха. Но со случайным ростом, а не симметричным и регулярным, как во фрактале. Я так и не доделал и быстро сдался. Однако, через некоторое время (плюс-минус шесть месяцев), я понял, что мог бы ввести новые узлы, пока кривая Коха растёт, но нужно заставить эти узлы смещаться относительно друг друга. Таким образом, они могли бы корректировать их позиции динамически, как жемчуг на верёвочке. Так они смогут держать нужное расстояние от других узлов (жемчужин).

Алгоритм выглядит следующим образом. Сначала мы создаем набор узлов, соединённых в какую-нибудь форму (круги или линии подойдут). Затем мы случайным образом вводим новые узлы между парами существующих узлов. В каждой итерации узлы будут пытаться оптимизировать свои позиции. Они будут хотеть быть рядом, но не слишком близко к своим двум соседям. В то же время они будут хотеть быть как можно дальше от всех других узлов. Обратите внимание, что здесь нет возможности их столкновения.

image

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

image

Разницу не очень легко заметить на данных примерах, но она становится очень заметной на больших симуляциях. На рисунке ниже использован метод вставки на основе кривизны, а создание заняло около 40 часов.

image

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

image

image

А если генеративное искусство и визуализация данных, вас заинтересовали посмотрите другие посты degenerative_art, вот самые популярные на данный момент:

Подробнее..

Перевод Песочный алфавит при помощи генеративных алгоритмов

19.10.2020 00:12:27 | Автор: admin
image

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

Это развитие идей из публикаций:

Визуализация при помощи генеративных алгоритмов: гифа, деревья, повторяющиеся и дифференциальные линии (на Python)

Визуализация при помощи генеративных алгоритмов: дифференциальная сетка (2D и 3D) и трещины

Однако вам необязательно читать их все проекты, описанные здесь самодостаточны.

ПЕСОЧНЙ СПЛАЙН [GITHUB]


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

image

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

image

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

Вместо того, чтобы просто рисовать сплайн, я рисую ряд прозрачных точек вдоль линии в каждой итерации. Ещё я рисую одинаковое количество точек каждый раз, независимо от длины линии. Так как движение постепенное, высокая плотность образуется там, где линия движется медленно, а более низкая там, где линия движется быстро.

Такое поведение, и техника рисования, во многом похожи на несколько работ Тарбелла, в том числе Sand Dollar, Limb Sand Stroke, Sand traveller и Sandstroke. Отсюда и пошло название. Несколько человек указали мне, что эти образы также очень напоминают Аттрактор Лоренца, хотя метод используется немного другой.

image

Сочетание этого простого метода с различными конфигурациями сплайнов и цветов даёт огромное количество вариаций результатов, и я, вероятно, вернусь к экспериментам с ней в будущем.

ДИФФЕРЕНЦИАЛЬНАЯ РЕШЁТКА [GITHUB]


При работе над дифференциальной линией, дифференциальной сеткой и дифференциальной сеткой в 3d наиболее утомительной частью было управление структурой данных. Отчасти потому что я решил научиться использовать half-edge структуры данных в этом процессе. И ещё потому что это у меня так и не получилось. И, наконец, потому что я писал его в Cython, который был в новинку для меня.

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

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

Оказывается, что относительные окрестности хорошо подходят для этого. Несколько упрощённо можно сказать, что два узла являются относительными соседями, если достаточно большая область между двумя узлами не содержит других узлов.

image

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

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

Эта система не имеет какого-либо распределения истончиков пищи (точек, которые ускоряют рост), что является интересным аспектом для изучения. Например, такая простая система каким-то образом сможет в теории повторить Токийскую железнодорожную систему или показать какое-нибудь другое интересное поведение (но это не точно).

image

Эта система реализована с помощью pyCUDA, что означает, что все расчеты расстояний и расчёты соседства могут быть сделаны на GPU. Поэтому это, вероятно, один из самых быстрых алгоритмов, которые я когда-либо реализовывал. Можно сделать системы с сотнями тысяч узлов удивительно быстро, с учетом количество вычислений.

Ниже изображение с около 80 000 узлами, которое было нарисовано на моём механическом плоттере.

image

ПЕСЧАНЕ ТВОРЕНИЯ [GITHUB]

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

Я попробовал несколько разных подходов, но следующий метод привел к наиболее приятным результатам:

  • Создать несколько случайных контрольных точек из равномерного распределения, ограниченного сферой.
  • Расположить их в произвольном порядке.
  • Создать B-сплайн из контрольных точек в том же порядке.

image

Для того, чтобы добавить текстуру к формам, я делаю еще один сплайн путём клонирования первого набора контрольных точек, и немного перемещая все наугад. Потом я использую ранее упомянутую sandstroke технику, чтобы нарисовать прямые линии между одинаково расположенными точками на двух сплайнах. Таким образом, получается хорошая зернистость.

С небольшими изменениями параметров можно получить совершенно разные результаты, как например в примере ниже.

image

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

ПЕСЧАНЕ ЗНАКИ [GITHUB]


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

Чтобы получить представление о том, как это работает, вы можете посмотреть на изображение ниже, где выделены контрольные точки.

image

Есть ряд вещей, с которыми можно поэкспериментировать даже в этой простой конфигурации:

  • Количество контрольных точек на знак;
  • Расстояние между знаками;
  • Форма знаков;
  • Положение знаков относительно горизонтальной центральной линии;
  • Внутренний порядок контрольных точек в знаках;
  • Количество знаков в слове;
  • Как письмо делится на строки;
  • И так далее ...

Не говоря уже о том, что все эти вещи предполагают написанный слева направо, более или менее латинский, написанный от руки текст.

Ниже приведен пример одной из конфигураций, которую считаю лучшей до сих пор.

image

Есть ещё такое видео того, как мой плоттер выписывает текст.

Наконец, я хотел бы обратить ваше внимание на Lettres de ma mre, сделанную пионером генеративного искусства Верой Молнэр.
Больше работ автора можно увидеть на сайте Inconvergent

Предыдущие проекты этого же автора:


А если генеративное искусство и визуализация данных, вас заинтересовали посмотрите другие посты degenerative_art, вот самые популярные на данный момент:


Подробнее..

Перевод Сняли забавный фильм, сценарий для которого написал GPT-3

23.10.2020 20:07:00 | Автор: admin

В Солиситорах (Solicitors), новом короткометражном фильме, снятым парой студентов-старшекурсников Университета Чапмана, все начинается с женщины, сидящей на диване и читающей книгу. В дверь раздается стук. Она встает, открывает дверь и обнаруживает за ней потного, дерганного человека с растрепанными волосами. Я Свидетель Иеговы, - говорит он. Женщина не выглядит впечатленной и отвечает: Прошу прощения, я не говорю с солиситорами". Мужчина пытается удержать ее внимание - У меня есть отличная история.

В фильме есть два сюжетных твиста. Один - как и во многих короткометражных фильмах по О.Генри откровение последней минуты, которое полностью меняет наше представление о всех предыдущих событиях. Второй раскрывается буквально сразу. Не буду спойлерить (да ладно вам - фильм длится всего несколько минут), но второй как раз является важным - весь сценарий, начиная с 20 секунды фильма был написан искусственным интеллектом.

Самой большой проблемой для меня стало, когда я снимался в фильме, написанном в основном ИИ, найти мотивацию для моего персонажа и понять намерения в моем диалоге.

Хотя нет недостатка в прекрасных фильмах, написанных о передовом искусственном интеллекте, от Матрицы до Терминатора и от них до Ex Machina, очень немногие могут сейчас говорить, что их автором стал передовой искусственный интеллект. Являются ли Solicitors примером грядущих медиаразвлечений, основанных на технологиях?

Я нашел код AI [который мы использовали], пока сидел на обучении, пытаясь изобразить заинтересованность Zoom`ом , - сказал режиссер и оператор короткометражного фильма Джейкоб Ваус. Меня сразу зацепило. Мне понравилось вставлять короткие истории, которые я написал, и смотреть, куда AI в итоге приводит сюжет, или вводить безумное начало и смотреть, куда пойдет эта история. Поскольку мы изучаем кино, нам сразу же понравилась эта идея. Может ли он написать сценарий? Какой контент мы могли бы сделать, чтобы продвинуть такой фильм? Насколько творческими мы могли бы стать? "

Получив человеческих помощников, AI создал сценарий, включая его финальный сюжетный поворот. (Вы можете прочитать сценарий в Интернете здесь). Мы думали, что это было так забавно, но также в некотором роде блестяще то, как AI довел сценарий до таких крайностей, - сказал Эли Вайсс, продюсер Solicitors. С точки зрения сторителлинга, он дал все, что вы хотите от истории, даже если это получилось странновато.

Ваус сказал: Мы умирали от смеха, когда впервые прочитали это. То, как он использует детали с самого начала, будто они имеют смысл, но в то же время бессмысленны, для меня невероятно.

Позаботьтесь и об актерах. Самой большой проблемой для меня стало, когда я снимался в фильме, написанном в основном ИИ, найти мотивацию для моего персонажа и понять намерения в моем диалоге., - сказал актер Эштон Херрилд, который играет мужчину на пороге. Обычно работа актера заключается в том, чтобы представить обстоятельства и персонажа, которые говорят и делают такие вещи. Но в сценарии, написанном искусственным интеллектом, не было никакого скрытого смысла, который нужно было найти - только отдавать .

Машины, снимающие фильмы

Это не первый раз, когда AI. был использован для написания сценария. Несколько лет назад актер Зак Брафф исполнил машинный монолог в роли своего персонажа Джей Ди из Клиники. Больница во многом похожа на среднюю школу, - говорится в ней. - Самый удивительный человек умирает, а ты единственный, кто хочет украсть вещи у его отца.

Эти генеративные алгоритмы, обученные на больших объемах данных, могут использоваться для создания нового, но до странности знакомого контента путем поглощения огромного количества материала, будь то романы о Гарри Поттере, книги Песнь льда и пламени или сценарии любимых комедийных фильмов. В результате получается современная технически подкованная версия метода нарезок Уильяма Берроуза: сюрреалистическая техника создания чего-то нового из чего-то существующего путем физического разрезания и склеивания в случайном порядке. Конечные продукты в случае алгоритмически сгенерированных скриптов часто бывают забавными. Однако они обычно не делают это особенно хорошо - по крайней мере, в том смысле, в котором мы можем оценить голливудский сценарий как хороший.

Поскольку у фильма редко бывает один-единственный создатель сценария, идея интеграции инструментов искусственного интеллекта в цикл написания и разработки не так уж и революционна, как может показаться.

Однако GPT-3 это большой шаг вперед. Эта версия алгоритма генерации текста почти всерьез считалась слишком опасным для массового доступа (до момента релиза финальной версии ). GPT-3 представляет собой нейронную сеть обработки естественного языка, созданную OpenAI. Предварительно подготовленная языковая модель GPT, с добавлением нескольких предложений в качестве начала сценария о человеке, появляющемся на пороге, убедительно сгенерирует текст, который будет соответствовать исходному материалу - по крайней мере, по тону и стилю. Это произвело фурор после его выпуска. Британская газета Guardian, издание, которое в разное время заказывала работу у некоторых из величайших журналистов мира, опубликовала статью, написанную GPT-3. Они озаглавили ее: "Робот написал всю статью. Тебе еще не страшно, человек?"

В 1959 году британский ученый и писатель К. Сноу написал знаменитое эссе под названием Две культуры, в котором утверждал, что интеллектуальная жизнь всего западного общества разделилась на два лагеря: точные науки и инженерное дело с одной стороны и гуманитарные науки с другой. Эти два лагеря, как он утверждал, нельзя совмещать ни при каких условиях. Сегодня кажется, что стены между этими двумя культурами рушатся быстрее, чем многие думают.

Лучшие студии мира больше не классические студии в голливудском стиле. Это технологические компании, такие как Netflix, Apple, Hulu и Amazon, и, как любая стоящая технологическая компания, они часто используют высокотехнологичные решения для творческих задач. Netflix, например, не скрывает роли больших данных в определении того, какие проекты заказывать. Наряду с невероятно глубокими карманами, эта точность в отношении того, что они должны и что не должны делать, помогла им выбрать лучших со скоростью, которая заставила бы Усэйна Болта замедлиться, чтобы перевести дух.

Другие продвигают технологическое производство еще дальше. AI консалтинговые компании, такие как британская Epagogix, которую когда-то профилировал Малкольм Гладуэлл для The New Yorker, используют данные не только для того, чтобы сказать, стоит ли продолжать проект, но и для того, чтобы внести предложения о том, как эти проекты можно творчески изменить, чтобы сделать их более прибыльными. Тем временем медиа-футурист и создатель алгоритмических фильмов Алексис Кирк отвечает за создание фильмов, которые разветвляются на основе физиологических реакций тех, кто их смотрит.

Еще один инструмент для авторов

Легко посмотреть на такой фильм, как Солиситоры, и увидеть проблески будущего творчества, в котором сценаристы будут больше не нужны. Но это не совсем точно. Каким бы хорошим ни был GPT-3, маловероятно, что ведущие сценаристы, такие как София Коппола или Аарон Соркин, будут дрожать в своих высокооплачиваемых голливудских ботинках из экологически чистых материалов в ближайшее время. Такие инструменты, как GPT-3, в конечном итоге - это всего лишь инструменты. Они будут играть роль в будущем развлечений, но не заменять, а дополнять их.

"Поскольку у фильма редко бывает один-единственный создатель сценария, идея интеграции инструментов искусственного интеллекта в цикл написания и разработки не так уж и революционна, как может показаться". - Сказал Кирк.

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

AI который автоматически сгенерирует несколько страниц научно-фантастических идей или идей в стиле фильма ужасов, чтобы вдохновить писателя-человека, - это просто еще одна итерация этого, как и бот, который смотрит на ваше письмо и сообщает вам, принесли ли сценарии такого типа деньги в прокате в прошлом. (Программное обеспечение GPT-3, используемое Ваусом и Вайссом, называется Shortly Read. Его веб-сайт описывает его как средство помощи писателю. "Просто нажмите кнопку, и ИИ продолжит писать вашу историю, генерируя новые творческие идеи и сюжетные наработки". )

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

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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru