Я не знаком с JavaFX, в частности, но я пытался решить очень похожую проблему, используя Python и OpenCV :
https://github.com/tasercake/lowpolypy
Вот как я это сделал.
Общий поток:
- Изображение предварительной обработки (двустороннее / гауссово размытие для удаления шума и т. Д.)
- Получить ключевые точки из изображения (используя методы, подробно описанные ниже)
- Получить многоугольники из ключевых точек (используя триангуляцию Делоне или аналогичный алгоритм)
- Затенение полигонов (например, используя средний цвет всех пикселейвнутри многоугольника)
- Постобработка (регулировка контрастности, насыщенности и т. д.)
1.Предварительная обработка
Предварительная обработка изображения помогает удалить много ненужных высокочастотных деталей, прежде чем перейти к извлечению ключевой точки.
Этого можно добиться с помощью фильтра, такого как Двусторонний фильтр или Гауссов фильтр .
Возможно, вы также захотите уменьшить изображение здесь, чтобы ускорить обработку, но это не обязательно.
2.Извлечение ключевой точки
Это, вероятно, самая сложная часть, которая потребует наиболее тонкой настройки / экспериментов.
Некоторые методы, которые вы можете попробовать:
Любая библиотека манипуляций с изображениями / компьютерного зрения (например, OpenCV) должна иметь встроенную функцию.
Этот метод дает вам логическое изображение, гдепотенциальные ребра помечены как «True».Затем вы можете выбрать случайное подмножество этих точек и преобразовать их в координаты (X, Y) (или любой другой формат, который вам наиболее удобен).
Я нашел этот метод в сочетании с небольшим количеством рандомизациитребовать наименьшей подстройки.
Это еще один метод обнаружения характерных особенностей в изображении, но основанный на второй производной пикселей изображения(в отличие от фильтра Канни, который основан на первой производной).
Этот фильтр возвращает изображение, которое можно нормализовать и использовать в качестве маски веса для случайной выборки набора ключевых точек (возможно, естьболее эффективные способы использования фильтра, чем этот, но меня это не беспокоило).
Случайная замена
После того, как вы набрали набор ключевых точек из всех других методов, вы можете выбратьзаменить небольшое случайное подмножество всех ваших точек набором случайно сгенерированных ключевых точек.
Я обнаружил, что это помогает ввести сомЭстетически приятные неровности в конечном результате.
Перемешивание ключевых точек
В дополнение к прямой замене небольшого подмножества ключевых точек, я также «перемешал» (произвольно переведенный) каждую ключевую точку на очень маленькое количество,Это помогает ввести еще больше случайности и позволяет вам выполнить несколько прогонов вашей программы, чтобы получить один потенциально хороший вывод.
ПРИМЕЧАНИЕ : не забудьте добавить 4 углавашего изображения в качестве ключевых точек, или вы получите пустые / черные области вокруг вашего вывода.
3.Соедините ключевые точки с полигонами
Триангуляция Делоне - это алгоритм, который соединяет набор точек на плоскости таким образом, чтобы максимизировать наименьший угол в каждом сформированном треугольнике.(Очевидно, это не сработает, если вам не нужны исключительно треугольники).
4.Тени полигонов
Для каждого полигона вы хотите получить среднее значение всех пикселей изображения в пределах области, охватываемой полигоном.OpenCV имеет функцию (cv2.mean(image, mask)
), которая позволяет вам сделать это в несколько строк, передавая многоугольник в виде двоичной маски.
Некоторые результаты:
fox | fox_lowpoly
eminem | eminem_lowpoly