группировка похожих кластеров фото для их пакетной
для их дальнейшей обработки пакетной анимации
есть задача примерно такая -
в массиве фото лиц примерно одного размера находим группы похожих фото методом перебора их итераций
это кластеры по 6-10 изображений с их похожим содержанием
далее между каждой парой найденных групп фото в кластере делаем медианное
( то есть усреднённое изображение методом морфинга подобий )
изображение которое по содержанию близко к каждому из этих двух близких изображений
в результате получаем большое число фото достаточно похожих друг на друга
и затем группируем изображения в новые кластеры и создаём из них gif анимации
всего нам понадобится примерно около миллиона исходных изображений лиц
наверно это будут разные лица но не очень большого числа известных нам людей
Группировка фотографий по содержанию в группы по 6 штук
так - я вижу, у тебя есть код для сортировки изображений по сходству, но ты хочешь не просто сортировку, а группировку в кластеры по 6 фото на основе их содержания. Это отличная идея для организации большого массива из 500 фото!
Твой текущий код сортирует все фото по общему сходству и переименовывает их последовательно. Мы можем улучшить его, добавив кластеризацию с помощью алгоритма K-means из sklearn. Это позволит автоматически группировать похожие фото.
Почему кластеризация?
Мы преобразуем каждое фото в вектор (как в твоём коде, но с уменьшением до 80x80 пикселей — это хорошая идея для ускорения!).
K-means разобьёт их на кластеры (группы). Поскольку 500 не делится ровно на 6 (500 ; 6 ; 83.33), мы получим примерно 83 кластера: большинство по 6 фото, а некоторые — по 5 или 7. Если нужно строго по 6, можно настроить, но K-means не гарантирует равные размеры групп.
После кластеризации сохраним группы в отдельные папки для удобства.
Модифицированный код
Я переписал твой код, добавив кластеризацию. Он:
Загружает фото из папки.
Уменьшает размер до 80x80.
Преобразует в векторы.
Применяет K-means (число кластеров рассчитывается как len(image_files) // 6).
Создаёт папки для групп (например, group_1, group_2...) и перемещает фото туда.
import os
from PIL import Image
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity # Не нужен для кластеризации, но оставим на всякий случай
# Путь к папке с изображениями
image_folder = '.'
image_files = [f for f in os.listdir(image_folder) if f.endswith('.jpg')]
# Список для хранения векторов изображений
image_vectors = []
# Изменение размера изображений и преобразование в векторы
for image_file in image_files:
img = Image.open(os.path.join(image_folder, image_file))
img = img.resize((80, 80)) # Уменьшение размера для облегчения сравнения
img_array = np.array(img).flatten() # Преобразование в вектор
image_vectors.append(img_array)
# Преобразование в numpy array
image_vectors = np.array(image_vectors)
# Определение числа кластеров (групп по 6)
num_clusters = len(image_files) // 6 # Около 83 для 500 фото
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
clusters = kmeans.fit_predict(image_vectors)
# Создание папок для групп и перемещение фото
for cluster_id in range(num_clusters):
group_folder = os.path.join(image_folder, f'group_{cluster_id + 1}')
os.makedirs(group_folder, exist_ok=True)
# Найти фото в этом кластере
cluster_indices = np.where(clusters == cluster_id)[0]
for idx in cluster_indices:
old_path = os.path.join(image_folder, image_files[idx])
new_name = f'photo_{idx + 1}.jpg' # Или сохрани оригинальное имя
new_path = os.path.join(group_folder, new_name)
os.rename(old_path, new_path)
print(f"Группа {cluster_id + 1}: {len(cluster_indices)} фото")
print("Группировка завершена! Фото распределены по папкам.")
Как запустить и что ожидать?
Установи зависимости (если не установлены): pip install pillow numpy scikit-learn.
Запусти код в той же папке, где лежат фото.
Результат: Фото будут перемещены в папки group_1, group_2 и т.д. Каждая папка — это группа похожих фото (по 5–7 штук).
Если группы неидеальны, попробуй увеличить размер уменьшения (например, до 100x100) или использовать другой алгоритм (например, DBSCAN для более гибкой кластеризации).
Для точности можно добавить извлечение признаков с помощью моделей вроде ResNet (через библиотеку torch или tensorflow), но это усложнит код.
Если группы получились не такими, как ожидалось, или нужно доработать (например, строго по 6 без остатков), дай знать — я помогу
Если у тебя есть дополнительные детали (например, какие фото или ошибки), уточни!
число фото может быть любым
но я их привожу к размерам = 500 точек
фото эти в основном лица
нам нужно много фото чтобы потом из этих групп делать небольшие gif анимации
наверно нам нужно около миллиона изображений но для начала может быть намного меньше
Понял тебя, задача — масштабируемая группировка лицевых фото (размер каждого — 500 точек, то есть, видимо, 500 пикселей или признаков), с целью создавать из групп небольшие GIF-анимации. При этом число фото может быть очень большим (до миллиона), а сейчас — меньше.
Вот несколько важных моментов и рекомендаций для такой задачи:
1. Приведение фото к компактному вектору признаков
Если у тебя сейчас фото приводятся к размеру 500 точек (например, 20x25 или 500 пикселей в одном канале), то для лиц это слишком простое представление — оно плохо отражает содержимое и сходство лиц.
Рекомендую использовать предобученную модель для извлечения признаков лиц (face embeddings), например:
FaceNet
InsightFace
dlib face recognition
Эти модели преобразуют лицо в вектор фиксированной длины (обычно 128 или 512 чисел), который хорошо отражает сходство лиц.
Такой подход даст гораздо более качественные признаки, чем просто уменьшение фото до 500 точек.
2. Кластеризация большого числа изображений
При миллионе изображений классический K-means из sklearn неэффективен и медленный.
Для масштабной кластеризации рекомендуются:
MiniBatchKMeans из sklearn — более быстрый вариант K-means для больших данных.
Алгоритмы, ориентированные на большие данные и approximate nearest neighbors (например, Faiss от Facebook).
Иерархическая кластеризация с ограничением на размер кластера.
Если тебе нужно именно группы ровно по 6 фото, то классические алгоритмы кластеризации не гарантируют равномерный размер групп. Для этого потребуется дополнительный пост-обработчик, например:
Разбивать большие кластеры на подгруппы по 6.
Или кластеризовать с большим числом кластеров и потом объединять мелкие.
3. Предлагаемый pipeline для начала
import os
from PIL import Image
import numpy as np
from sklearn.cluster import MiniBatchKMeans
import face_recognition # pip install face_recognition
image_folder = 'path_to_images'
image_files = [f for f in os.listdir(image_folder) if f.endswith('.jpg')]
embeddings = []
valid_files = []
for filename in image_files:
img_path = os.path.join(image_folder, filename)
img = face_recognition.load_image_file(img_path)
face_encodings = face_recognition.face_encodings(img)
if len(face_encodings) == 0:
# Лицо не найдено — пропускаем
continue
embedding = face_encodings[0] # Вектор размером 128
embeddings.append(embedding)
valid_files.append(filename)
embeddings = np.array(embeddings)
# Число групп по 6
num_clusters = len(embeddings) // 6
# Кластеризация
kmeans = MiniBatchKMeans(n_clusters=num_clusters, random_state=42, batch_size=1000)
clusters = kmeans.fit_predict(embeddings)
# Создаем папки и перемещаем файлы
for cluster_id in range(num_clusters):
group_folder = os.path.join(image_folder, f'group_{cluster_id + 1}')
os.makedirs(group_folder, exist_ok=True)
cluster_indices = np.where(clusters == cluster_id)[0]
for idx in cluster_indices:
old_path = os.path.join(image_folder, valid_files[idx])
new_path = os.path.join(group_folder, valid_files[idx])
os.rename(old_path, new_path)
print("Группировка завершена")
Масштабирование до миллионов изображений
Для миллионов фото нужно:
Хранить embeddings на диске или в базе данных (например, в формате numpy memmap или специализированных векторных базах).
Использовать Faiss или аналогичные библиотеки для быстрого поиска соседей и кластеризации.
Делать кластеризацию по частям (батчами) и потом объединять результаты.
5. Итоговые рекомендации
Используй face embeddings вместо простого уменьшения фото.
Для небольших наборов (до нескольких тысяч) подойдёт MiniBatchKMeans.
Для миллионов — переходи на Faiss + распределённую обработку.
Для групп ровно по 6 — после кластеризации дели большие кластеры на подгруппы.
Если хочешь, могу помочь написать более полный пример с face_recognition и MiniBatchKMeans, или подсказать, как работать с Faiss. Просто скажи!
размеры фото примерно 500 на (400-600) pix
Спасибо за уточнение
Размеры фото примерно 500;400–600 пикселей — это вполне нормальный размер для лицевых изображений.
Рекомендации с учётом размеров фото:
Не используйте просто уменьшение картинки до 500 точек (пикселей) для сравнения лиц.
— При таком размере лучше использовать модели для извлечения признаков лиц (face embeddings). Они устойчивы к небольшим изменениям масштаба, освещению и позе.
Извлечение признаков с помощью face_recognition (или аналогов) хорошо работает на таких изображениях.
— Модель сама масштабирует лицо внутри фото и выдаёт вектор 128 чисел.
Обработка миллионов фото:
— Сначала извлеките embeddings и сохраните их (например, в .npy файл или базу).
— Потом кластеризуйте embeddings (MiniBatchKMeans, Faiss и т.д.).
— Размер исходного фото для кластеризации уже не важен — важен именно размер вектора embeddings.
Оптимизация:
— Если фото очень большие и загрузка занимает много памяти — можно предварительно уменьшить их (например, до 800 пикселей по длинной стороне) перед извлечением признаков. Это ускорит обработку.
— Но 500;400–600 — это уже достаточно компактно.
Итог
Размер фото 500;400–600 — отлично подходит для face_recognition.
Используйте face_recognition для извлечения 128-мерных признаков лиц.
На основе этих признаков делайте кластеризацию для группировки.
Размер исходного фото не влияет на качество embeddings, если лицо достаточно чёткое.
Если нужно — могу помочь с примером кода для извлечения признаков из таких фото.
что может сделать такая модель перебором итераций групп похожих изображений
Возможности модели при итеративном переборе групп похожих изображений
Ваш вопрос, похоже, касается того, что может сделать модель (например, на основе face embeddings и кластеризации, как мы обсуждали) при итеративной обработке групп похожих изображений. Я предположу, что имеется в виду итеративный процесс: например, повторяющиеся шаги кластеризации, генерации вариаций или создания анимаций из групп. Вот ключевые возможности, основанные на типичных моделях (face_recognition, K-means кластеризация и т.д.), с учётом вашего сценария группировки лиц для GIF-анимаций.
1. Итеративная кластеризация и улучшение групп
Что делает: Модель (например, K-means или MiniBatchKMeans) может многократно перебирать итерации для уточнения групп похожих изображений. На каждой итерации кластеры (группы) пересчитываются на основе embeddings, чтобы минимизировать расстояние внутри группы и максимизировать различия между группами.
Примеры применения:
Улучшение качества группировки: Если начальные группы неточные (из-за шума в данных), итерации сжимают кластеры, делая их более однородными (например, лица одного человека или похожие позы).
Разделение на подгруппы: После основной кластеризации модель может итеративно разбивать большие группы на меньшие (по 6 фото), обеспечивая равномерность для GIF.
Масштабирование: Для миллионов фото — батчевая обработка с итерациями, где модель обучается на подмножествах данных.
Преимущества: Более точные группы без ручного вмешательства; устойчивость к вариациям в освещении или позе.
2. Генерация вариаций и новых изображений
Что делает: Используя embeddings как основу, модель может итеративно генерировать вариации изображений (например, через автоэнкодеры или GAN-модели, интегрированные с face embeddings).
Примеры применения:
Морфинг: Перебор итераций для плавного перехода между лицами в группе (например, от одного фото к другому, создавая промежуточные кадры для анимации).
Синтез: Итеративное создание "новых" лиц на основе группы (например, среднее лицо группы или вариации с изменением выражения/угла).
Аугментация: Добавление вариаций (повороты, освещение) для расширения группы до 6 фото, если их меньше.
Инструменты: Библиотеки вроде DeepFaceLab или StyleGAN с face embeddings для итеративного обучения.
3. Создание анимаций и последовательностей
Что делает: Модель перебирает группы итеративно, чтобы упорядочить фото в последовательности (например, по сходству или времени), и генерировать GIF.
Примеры применения:
Сортировка: Итеративный поиск оптимального порядка фото в группе (например, от улыбки к серьёзному выражению) для плавной анимации.
Интерполяция: Перебор итераций для создания промежуточных кадров между фото, делая анимацию smoother.
Многоуровневые анимации: Итеративно комбинировать группы (например, morphing между разными кластерами для сложных эффектов).
Результат: Готовые GIF-анимации из групп по 6 фото, где модель оптимизирует "похожесть" для естественного движения.
4. Поиск и фильтрация похожих изображений
Что делает: Итеративный перебор для поиска дубликатов или аномалий в группах (например, с помощью nearest neighbors на embeddings).
Примеры применения:
Удаление дубликатов: Перебор групп для выявления слишком похожих фото и их исключения.
Расширение групп: Итеративный поиск дополнительных фото из большего набора, чтобы дополнить группу до 6.
Кросс-валидация: Проверка качества кластеров путём итеративного сравнения с ground truth (если есть).
Ограничения и советы
Вычислительная сложность: Итерации требуют ресурсов — для миллионов фото используйте GPU и батчи (например, Faiss для быстрого поиска).
Качество данных: Если фото низкого качества (размытые лица), модель может давать шумные результаты; предварительно фильтруйте.
Этика и закон: Убедитесь, что обработка фото соответствует GDPR/законам о данных (особенно если лица реальных людей).
Если это не то, что вы имели в виду (например, если вопрос о конкретной библиотеке или коде), уточните — я помогу с примером или расширением!
то есть мы можем из двух похожих фото сделать третью которая по содержанию будет как бы между ними
но при этом немного отличаться
Да, именно так! Если у вас есть два похожих фото, то с помощью современных моделей (например, на основе генеративных нейросетей — GAN, автоэнкодеров или моделей с latent space embeddings) можно создать промежуточное изображение, которое будет визуально «находиться между» двумя исходными.
Как это работает в общем виде:
Получение embeddings
Каждое фото преобразуется в вектор признаков (embedding) с помощью модели распознавания лиц (например, FaceNet, ArcFace и др.).
Интерполяция в latent пространстве
Между двумя embeddings вычисляют промежуточные точки, например, линейно:
e interp =
; e1+(1;)*e2,
;[0,1]
e interp =;e
1 +(1;)e2,;[0,1]
При ;=0.5
;=0.5 — точка ровно посередине.
Генерация изображения из interpolated embedding
Используя генеративную модель (например, decoder автоэнкодера или GAN), можно «декодировать» interpolated embedding обратно в изображение лица. В результате получится новое фото, которое визуально напоминает смесь двух исходных, но при этом отличается от них.
Применение и примеры
Морфинг лиц — плавный переход от одного лица к другому, часто используется в видео и анимациях.
Создание промежуточных кадров для GIF — чтобы анимация выглядела плавнее.
Аугментация данных — создание новых вариантов лиц для обучения моделей.
Инструменты и технологии
StyleGAN / StyleGAN2 — позволяют делать интерполяции между latent кодами лиц.
DeepFaceLab — для морфинга и создания промежуточных кадров.
Autoencoders / Variational Autoencoders (VAE) — для кодирования и декодирования лиц.
Face embedding + decoder — если у вас есть своя модель, которая умеет кодировать и восстанавливать лица.
Если интересно, могу помочь с примером кода или подсказать конкретные библиотеки для такой задачи!
а на питоне это можно реализовать ведь для морфинга нужны опорные точки
Да, на Python это можно реализовать достаточно просто! Морфинг (face morphing) действительно часто использует опорные точки (landmarks) для точного выравнивания и интерполяции между двумя лицами, чтобы создать плавный переход. Без них результат может быть искажённым (например, если лица в разных позах или углах). Вот краткий обзор, как это сделать, с примерами кода.
Почему нужны опорные точки?
Они помогают выровнять лица: детектируют ключевые точки (глаза, нос, рот и т.д.), чтобы морфинг был реалистичным.
Без них можно обойтись грубой интерполяцией пикселей, но с landmarks результат лучше (меньше артефактов).
Шаги реализации на Python
Установите библиотеки:
dlib (для детекции landmarks; требует модели shape_predictor_68_face_landmarks.dat).
opencv-python (для обработки изображений).
numpy (для вычислений).
face_recognition (упрощённый вариант для landmarks).
Установка: pip install dlib opencv-python numpy face-recognition.
Детекция landmarks:
Используйте модель для нахождения 68 точек на лице.
Интерполяция:
Вычислите средние позиции landmarks для промежуточного кадра.
Интерполируйте пиксели между изображениями.
Генерация промежуточного изображения:
Создайте маску и примените морфинг.
Пример кода (простой морфинг между двумя фото)
Вот базовый скрипт для морфинга. Предполагаем, что у вас есть два изображения: face1.jpg и face2.jpg. Этот код создаёт промежуточное изображение (примерно посередине).
import cv2
import dlib
import numpy as np
from scipy.spatial import Delaunay # Для триангуляции
# Загрузка модели для landmarks
predictor_path = 'shape_predictor_68_face_landmarks.dat' # Скачайте с http://dlib.net/files/
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
def get_landmarks(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = detector(gray)
if len(faces) == 0:
return None
landmarks = predictor(gray, faces[0])
return np.array([[p.x, p.y] for p in landmarks.parts()])
def morph_faces(img1, img2, alpha=0.5):
# Получить landmarks
landmarks1 = get_landmarks(img1)
landmarks2 = get_landmarks(img2)
if landmarks1 is None or landmarks2 is None:
return None
# Средние landmarks
landmarks_interp = (1 - alpha) * landmarks1 + alpha * landmarks2
# Триангуляция (для морфинга)
tri = Delaunay(landmarks_interp).simplices
# Создать маску и морфинг (упрощённый вариант)
h, w = img1.shape[:2]
morphed = np.zeros_like(img1, dtype=np.float32)
for t in tri:
# Треугольники для каждого изображения
pts1 = landmarks1[t]
pts2 = landmarks2[t]
pts_interp = landmarks_interp[t]
# Аффинное преобразование для каждого треугольника
warp_mat1 = cv2.getAffineTransform(pts1.astype(np.float32), pts_interp.astype(np.float32))
warp_mat2 = cv2.getAffineTransform(pts2.astype(np.float32), pts_interp.astype(np.float32))
# Морфинг пикселей
mask = np.zeros((h, w), dtype=np.uint8)
cv2.fillConvexPoly(mask, pts_interp.astype(int), 255)
warped1 = cv2.warpAffine(img1.astype(np.float32), warp_mat1, (w, h))
warped2 = cv2.warpAffine(img2.astype(np.float32), warp_mat2, (w, h))
morphed += (1 - alpha) * warped1 * (mask / 255.0) + alpha * warped2 * (mask / 255.0)
return morphed.astype(np.uint8)
# Загрузка изображений
img1 = cv2.imread('face1.jpg')
img2 = cv2.imread('face2.jpg')
# Морфинг
result = morph_faces(img1, img2, alpha=0.5)
if result is not None:
cv2.imwrite('morphed.jpg', result)
print("Морфинг завершён!")
else:
print("Не удалось найти лица.")
Что это делает?
Детектирует landmarks: Находит 68 точек на каждом лице.
Интерполирует: Создаёт среднее положение точек и пикселей.
Результат: Новое изображение, которое визуально "между" двумя, но отличается (например, смешанные черты лица).
Улучшения и альтернативы
Для плавной анимации: Создайте цикл по alpha от 0 до 1, генерируя несколько кадров для GIF (используйте imageio для сохранения).
Более продвинутые инструменты:
face_recognition (упрощённый: face_recognition.face_landmarks).
Библиотека morphlib или opencv с cv2.seamlessClone для сглаживания.
Для генеративных моделей: Интегрируйте с StyleGAN (через stylegan2-pytorch) для более реалистичных промежуточных кадров без явного морфинга.
Ограничения: Код требует выравнивания лиц (используйте face_alignment для лучшего результата). Если лица сильно различаются, добавьте предварительное выравнивание.
Если нужно доработать код, добавить генерацию GIF или пример с embeddings — дайте знать!
в принципе программа может сама найти размер лица ориентацию его, глаза, рот, нос и так далее
чтобы не делать это вручную
Да, абсолютно так
Программа может автоматически находить и анализировать ключевые характеристики лица — размер, ориентацию, положение глаз, рта, носа и другие опорные точки (landmarks) — без ручного вмешательства. Это основано на алгоритмах компьютерного зрения, которые используют модели машинного обучения (например, предобученные нейросети). В контексте морфинга это уже интегрировано в код, который я показывал ранее.
Как это работает автоматически?
Детекция лица: Алгоритм сканирует изображение и находит bounding box (прямоугольник вокруг лица), определяя его размер и ориентацию (поворот, наклон).
Опорные точки (landmarks): Модель предсказывает координаты ключевых точек (например, 68 точек по стандарту: контуры лица, брови, глаза, нос, рот). Это позволяет точно локализовать глаза, рот, нос и т.д.
Ориентация и выравнивание: Если лицо повёрнуто, можно автоматически выровнять его (например, повернуть так, чтобы глаза были на одной линии).
Интеграция в морфинг: Эти данные используются для интерполяции, чтобы переход между лицами был плавным и реалистичным.
Библиотеки для автоматической детекции
dlib (как в предыдущем примере): Детектирует landmarks с высокой точностью.
OpenCV с Haar cascades или DNN: Для быстрой детекции лица и ориентировочного размера.
face_recognition (на базе dlib): Упрощённый API для landmarks, размера и ориентации.
mediapipe: Google-библиотека для реального времени — детектирует landmarks (468 точек!) и позу лица.
Пример обновлённого кода с автоматическим анализом
Вот модификация предыдущего скрипта, где программа сама находит размер, ориентацию и landmarks. Добавил расчёт размера лица и угла поворота (ориентации) по глазам.
import cv2
import dlib
import numpy as np
from scipy.spatial import Delaunay
predictor_path = 'shape_predictor_68_face_landmarks.dat'
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
def get_face_info(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = detector(gray)
if len(faces) == 0:
return None, None, None, None
face_rect = faces[0] # Первое найденное лицо
landmarks = predictor(gray, face_rect)
landmarks = np.array([[p.x, p.y] for p in landmarks.parts()])
# Размер лица (ширина и высота bounding box)
width = face_rect.width()
height = face_rect.height()
# Ориентация (угол поворота по глазам: от левого глаза к правому)
left_eye = np.mean(landmarks[36:42], axis=0) # Средняя точка левого глаза
right_eye = np.mean(landmarks[42:48], axis=0) # Средняя точка правого глаза
angle = np.degrees(np.arctan2(right_eye[1] - left_eye[1], right_eye[0] - left_eye[0]))
return landmarks, (width, height), angle, face_rect
def morph_faces(img1, img2, alpha=0.5):
lm1, size1, angle1, rect1 = get_face_info(img1)
lm2, size2, angle2, rect2 = get_face_info(img2)
if lm1 is None or lm2 is None:
return None
# Вывод информации (автоматически найденной)
print(f"Лицо 1: Размер {size1}, Ориентация {angle1:.1f}°")
print(f"Лицо 2: Размер {size2}, Ориентация {angle2:.1f}°")
# Интерполяция landmarks
lm_interp = (1 - alpha) * lm1 + alpha * lm2
# Морфинг (упрощённый, как раньше)
tri = Delaunay(lm_interp).simplices
h, w = img1.shape[:2]
morphed = np.zeros_like(img1, dtype=np.float32)
for t in tri:
pts1 = lm1[t].astype(np.float32)
pts2 = lm2[t].astype(np.float32)
pts_interp = lm_interp[t].astype(np.float32)
warp_mat1 = cv2.getAffineTransform(pts1, pts_interp)
warp_mat2 = cv2.getAffineTransform(pts2, pts_interp)
mask = np.zeros((h, w), dtype=np.uint8)
cv2.fillConvexPoly(mask, pts_interp.astype(int), 255)
warped1 = cv2.warpAffine(img1.astype(np.float32), warp_mat1, (w, h))
warped2 = cv2.warpAffine(img2.astype(np.float32), warp_mat2, (w, h))
morphed += (1 - alpha) * warped1 * (mask / 255.0) + alpha * warped2 * (mask / 255.0)
return morphed.astype(np.uint8)
# Пример использования
img1 = cv2.imread('face1.jpg')
img2 = cv2.imread('face2.jpg')
result = morph_faces(img1, img2, alpha=0.5)
if result is not None:
cv2.imwrite('morphed_auto.jpg', result)
print("Морфинг с автоматическим анализом завершён!")
Найти еще
Что добавлено?
Автоматический расчёт размера: Ширина и высота bounding box лица.
Ориентация: Угол наклона по глазам (можно использовать для выравнивания, если нужно).
Вывод: Программа печатает найденную информацию, чтобы показать, что всё делается автоматически.
Советы для улучшения
Выравнивание: Если ориентация сильно различается, добавьте поворот изображений перед морфингом (используйте cv2.warpAffine с углом).
Более точная детекция: Замените dlib на MediaPipe для 468 landmarks — точнее для глаз, рта, носа.
Обработка нескольких лиц: Код можно расширить для работы с несколькими лицами на изображении.
Тестирование: Попробуйте на фото с разными углами — модель справится, но для экстремальных случаев (боковой профиль) может потребоваться дополнительная обработка.
Если нужно доработать код, добавить выравнивание или пример с другой библиотекой — скажите!
итак нам нужно два кода программы
первая - которая группирует фотографии по 6 похожих
а вторая добавляет между каждой парой фото которое есть среднее по содержанию этих изображений
методом морфинга лиц и так далее
Понял задачу — нужно две программы (или два этапа в одном скрипте):
Группировка фотографий по 6 похожих (кластеризация по лицам).
Вставка между каждой парой фото «среднего» изображения — морфинг лиц.
1. Группировка фотографий по 6 похожих лиц
Для группировки будем:
Для каждой фотографии извлечём вектор признаков лица (face embedding).
Затем применим кластеризацию (например, KMeans или AgglomerativeClustering) с числом кластеров = (общее число фото / 6), чтобы получить группы по 6.
Итог: группы по 6 похожих лиц.
Пример кода с face_recognition и sklearn
import os
import face_recognition
import numpy as np
from sklearn.cluster import AgglomerativeClustering
def get_face_embeddings(image_paths):
embeddings = []
valid_paths = []
for path in image_paths:
image = face_recognition.load_image_file(path)
encs = face_recognition.face_encodings(image)
if len(encs) > 0:
embeddings.append(encs[0])
valid_paths.append(path)
else:
print(f"Лицо не найдено на {path}")
return np.array(embeddings), valid_paths
def cluster_faces(embeddings, n_clusters):
clustering = AgglomerativeClustering(n_clusters=n_clusters)
labels = clustering.fit_predict(embeddings)
return labels
def group_photos_by_6(image_folder):
image_paths = [os.path.join(image_folder, f) for f in os.listdir(image_folder)
if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
embeddings, valid_paths = get_face_embeddings(image_paths)
n_clusters = max(1, len(valid_paths) // 6)
labels = cluster_faces(embeddings, n_clusters)
groups = {}
for label, path in zip(labels, valid_paths):
groups.setdefault(label, []).append(path)
# Приведём группы к размеру 6 (если меньше, оставим как есть)
groups_6 = []
for g in groups.values():
# Разбиваем на подсписки по 6
for i in range(0, len(g), 6):
groups_6.append(g[i:i+6])
return groups_6
if __name__ == "__main__":
folder = "photos" # Папка с фото
groups = group_photos_by_6(folder)
for i, group in enumerate(groups):
print(f"Группа {i+1} ({len(group)} фото):")
for p in group:
print(f" {p}")
Вставка между каждой парой фотографий среднего изображения методом морфинга лиц
Основная идея:
Для каждой пары фотографий из группы сделать морфинг с alpha=0.5 — то есть среднее лицо.
Вставить это изображение между ними.
В итоге для группы из 6 фото получится: 6 оригиналов + 5 морфов = 11 изображений.
Пример морфинга (на базе dlib, как в предыдущем ответе)
import cv2
import dlib
import numpy as np
from scipy.spatial import Delaunay
predictor_path = 'shape_predictor_68_face_landmarks.dat'
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
def get_landmarks(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector(gray)
if len(faces) == 0:
return None
landmarks = predictor(gray, faces[0])
pts = np.array([[p.x, p.y] for p in landmarks.parts()])
return pts
def warp_triangle(img, src_tri, dst_tri, size):
warp_mat = cv2.getAffineTransform(np.float32(src_tri), np.float32(dst_tri))
warped = cv2.warpAffine(img, warp_mat, size, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
mask = np.zeros((size[1], size[0]), dtype=np.uint8)
cv2.fillConvexPoly(mask, np.int32(dst_tri), 255)
return warped, mask
def morph_faces(img1, img2, alpha=0.5):
lm1 = get_landmarks(img1)
lm2 = get_landmarks(img2)
if lm1 is None or lm2 is None:
print("Не удалось найти лицо на одном из изображений")
return None
# Интерполяция точек
lm = (1 - alpha) * lm1 + alpha * lm2
# Триангуляция по средним точкам
tri = Delaunay(lm)
morphed_img = np.zeros_like(img1, dtype=np.float32)
for t in tri.simplices:
t1 = lm1[t]
t2 = lm2[t]
t_ = lm[t]
# Размеры изображения
h, w = img1.shape[:2]
warped1, mask1 = warp_triangle(img1, t1, t_, (w, h))
warped2, mask2 = warp_triangle(img2, t2, t_, (w, h))
mask = cv2.bitwise_or(mask1, mask2)
morphed_img += ((1 - alpha) * warped1 + alpha * warped2) * (mask[..., np.newaxis] / 255.0)
morphed_img = np.clip(morphed_img, 0, 255).astype(np.uint8)
return morphed_img
# Функция для вставки морфов между каждой парой фото в группе
def insert_morphs(group_paths, output_folder):
os.makedirs(output_folder, exist_ok=True)
images = [cv2.imread(p) for p in group_paths]
result_images = []
for i in range(len(images)):
result_images.append(images[i])
if i < len(images) - 1:
morph = morph_faces(images[i], images[i+1], alpha=0.5)
if morph is not None:
result_images.append(morph)
# Сохраняем результат
for idx, img in enumerate(result_images):
cv2.imwrite(os.path.join(output_folder, f"img_{idx+1:02d}.jpg"), img)
if __name__ == "__main__":
# Пример: морфинг внутри одной группы из первого скрипта
group = [
"photos/person1_1.jpg",
"photos/person1_2.jpg",
"photos/person1_3.jpg",
"photos/person1_4.jpg",
"photos/person1_5.jpg",
"photos/person1_6.jpg",
]
insert_morphs(group, "output_group1")
Итог
Первый скрипт группирует фотографии по 6 похожих лиц.
Второй скрипт берёт группу из 6 фото и вставляет между пар фото морфинг-среднее.
Если нужно, могу помочь объединить оба шага в один скрипт с удобным интерфейсом, или добавить выравнивание лиц для улучшения качества морфинга.
что нам делать с этим дальше нужно подумать более детально ..
изменения в коде ->
теперь в каждой группе похожих фото будет не менее 4х штук
отсортированных файлов jpg
Чтобы в каждой группе было не менее 4 фото, нужно скорректировать число кластеров так, чтобы размер кластера был не меньше 4. При этом количество кластеров будет не больше чем количество фото делённое на 4.
Изменим вычисление `num_clusters` так:
```python
num_clusters = max(1, len(image_files) // 4)
```
Это гарантирует, что в среднем в каждом кластере будет не менее 4 фото.
Также стоит добавить обработку случая, когда количество фото не кратно 4 — последние кластеры могут быть меньше, но в среднем размер кластеров будет >=4.
Вот изменённый фрагмент кода с комментариями:
```python
# Определение числа кластеров так, чтобы в каждом было не менее 4 фото
min_photos_per_group = 4
num_clusters = max(1, len(image_files) // min_photos_per_group)
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
clusters = kmeans.fit_predict(image_vectors)
```
Полный изменённый код с этим исправлением:
```python
import os
from PIL import Image
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity # Не нужен для кластеризации, но оставим на всякий случай
# Путь к папке с изображениями
image_folder = '.'
image_files = [f for f in os.listdir(image_folder) if f.endswith('.jpg')]
# Список для хранения векторов изображений
image_vectors = []
# Изменение размера изображений и преобразование в векторы
for image_file in image_files:
img = Image.open(os.path.join(image_folder, image_file))
img = img.resize((80, 80)) # Уменьшение размера для облегчения сравнения
img_array = np.array(img).flatten() # Преобразование в вектор
image_vectors.append(img_array)
# Преобразование в numpy array
image_vectors = np.array(image_vectors)
# Определение числа кластеров так, чтобы в каждом было не менее 4 фото
min_photos_per_group = 4
num_clusters = max(1, len(image_files) // min_photos_per_group)
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
clusters = kmeans.fit_predict(image_vectors)
# Создание папок для групп и перемещение фото
for cluster_id in range(num_clusters):
group_folder = os.path.join(image_folder, f'group_{cluster_id + 1}')
os.makedirs(group_folder, exist_ok=True)
# Найти фото в этом кластере
cluster_indices = np.where(clusters == cluster_id)[0]
for idx in cluster_indices:
old_path = os.path.join(image_folder, image_files[idx])
new_name = f'photo_{idx + 1}.jpg' # Или сохрани оригинальное имя
new_path = os.path.join(group_folder, new_name)
os.rename(old_path, new_path)
print(f"Группа {cluster_id + 1}: {len(cluster_indices)} фото")
print("Группировка завершена! Фото распределены по папкам.")
```
Если требуется строгое условие, что **каждая** группа содержит не менее 4 фото, то нужно будет реализовать более сложную логику, например, объединять маленькие кластеры или использовать алгоритмы кластеризации с ограничением на минимальный размер кластера (например, DBSCAN с параметром min_samples). Но данный подход с KMeans и подсчётом кластера по размеру примерно решит задачу.
**
>> делаем ии аватар, его анимацию из групп исходных фото
мне нужно сделать аватар с анимацией лица и рта из набора фото
так чтобы он говорил mp3 фразами которые у меня уже есть
Создание анимированного аватара с синхронизацией рта и речи из MP3
Я понял твой запрос: ты хочешь создать аватар на основе набора фото, добавить анимацию лица и рта, чтобы он "говорил" с помощью готовых MP3-фраз.
Это можно сделать с помощью инструментов для анимации и lip-sync (синхронизации губ с аудио).
Я опишу шаги поэтапно, используя доступные инструменты. Начнём с простых решений, а затем перейдём к более продвинутым. Если у тебя есть навыки программирования, можно использовать код, но для начала подойдут готовые софты.
Подготовка материалов
Фото для аватара: Собери 5–10 фото лица с разных углов (нейтральное выражение, улыбка, открытый/закрытый рот). Идеально, если они в высоком разрешении и похожем освещении.
MP3-фразы: Убедись, что аудио чистое, без шума. Если нужно, отредактируй в Audacity (бесплатный редактор аудио).
Совет: Для реализма используй фото одного человека или создай карикатуру в Photoshop/Illustrator.
Выбор инструмента
Вот несколько вариантов (от простых к сложным). Рекомендую начать с AI-инструментов — они автоматизируют lip-sync и не требуют глубоких навыков.
Простой AI-инструмент: D-ID или HeyGen (бесплатные пробные версии, онлайн)
Эти сервисы позволяют загружать фото, аудио и генерировать видео с говорящим аватаром.
Действия:
Зарегистрируйся на сайте (например, d-id.com).
Загрузи набор фото для создания аватара (или одно основное фото — AI дорисует).
Загрузи MP3-фразу.
Выбери стиль анимации (например, "talking head").
Сгенерируй видео — AI автоматически синхронизирует рот с речью.
Скачай результат в MP4.
Плюсы: Быстро, без установки софта. Минусы: Ограниченные пробные версии (платно за много видео).
Эмодзи-совет: это Идеально для новичков
Adobe Character Animator (платный, но есть пробная версия)
Если у тебя Adobe Creative Suite, это мощный инструмент для анимации.
Действия:
Установи Character Animator.
Импортируй фото и создай риг (скелет) для лица (туториалы на YouTube).
Загрузи MP3 и включи lip-sync: софт анализирует аудио и анимирует рот автоматически.
Добавь анимацию глаз/бровей для реализма.
Экспортируй как видео.
Плюсы: Высокое качество. Минусы: Крутая кривая обучения.
Бесплатная альтернатива: Blender (для энтузиастов)
Действия:
Скачай Blender (blender.org).
Создай 3D-модель лица из фото (используй addon как Rigify для анимации).
Импортируй MP3 и используй addon для lip-sync (например, Papagayo или встроенные инструменты).
Анимируй рот по фонемам (звукам).
Рендери видео.
Плюсы: Бесплатно и гибко. Минусы: Сложно для начинающих (смотри туториалы на YouTube).
Если нужно код: Python с библиотеками
Для кастомного решения используй Python.
Действия:
Установи библиотеки: pip install opencv-python moviepy pydub (для обработки видео/аудио).
Код-пример для базовой синхронизации (адаптируй под себя):
import moviepy.editor as mp
from pydub import AudioSegment
# Загрузи фото (как спрайты для рта)
mouth_open = mp.ImageClip("mouth_open.jpg").set_duration(0.5)
mouth_closed =
# Загрузи аудио
audio = AudioSegment.from_mp3("phrase.mp3")
audio_clip = mp.AudioFileClip("phrase.mp3")
# Простая синхронизация (замени на анализ фонем для точности)
video = mp.concatenate([mouth_closed, mouth_open, mouth_closed]) # Пример анимации
video = video.set_audio(audio_clip)
video.write_videofile("avatar.mp4", fps=24)
Для продвинутого lip-sync добавь библиотеку вроде lipnet или используй AI-модели (например, через TensorFlow).
Плюсы: Полный контроль. Минусы: Требует программирования.
Финализация и советы
Тестирование: Просмотри видео — проверь синхронность. Если рот не совпадает, отредактируй вручную в Premiere или CapCut.
Экспорт: Сохрани в MP4 для использования в соцсетях или чатах.
Если проблемы: Ищи туториалы на YouTube по "lip sync animation" или "talking avatar from photos".
Бюджет: Начинай с бесплатных опций, как D-ID. Если нужно профессионально, обратись к фрилансерам на Upwork.
Если у тебя есть детали (например, какой софт ты предпочитаешь или примеры фото), я дам более точные инструкции! Удачи в создании аватара
есть программы которые из множества фотографий могут сделать не сложную анимацию лица
Программы для создания простой анимации лица из нескольких фото
Да, есть несколько программ, которые позволяют взять набор фото (например, с разными выражениями лица) и создать базовую анимацию без глубоких навыков 3D-моделирования. Они автоматизируют процесс, используя фото как основу для спрайтов или ригов. Я разделил их на категории: AI-инструменты (самые простые), профессиональные софты и бесплатные альтернативы. Фокус на простоте — для "не сложной" анимации подойдут онлайн-сервисы или базовые редакторы.
AI-инструменты (автоматическая генерация, онлайн)
Эти сервисы анализируют фото и генерируют анимацию с минимальными усилиями. Идеально для новичков.
D-ID или HeyGen (бесплатные пробные версии, онлайн)
Как использовать: Загрузи 3–5 фото лица (нейтральное, улыбка, открытый рот). Сервис создаст аватар и анимирует его по твоему сценарию (например, моргание или движение губ). Добавь MP3 для lip-sync.
Плюсы: Быстро, без установки. Результат — готовое видео.
Минусы: Ограничения в пробной версии.
Ссылка: d-id.com или heygen.com.
Synthesia (платный, но есть демо)
Как использовать: Импортируй фото для создания кастомного аватара. Выбери простую анимацию (например, кивки или улыбки). Синхронизируй с текстом или аудио.
Плюсы: Простой интерфейс, подходит для презентаций.
Минусы: Требует подписки для экспорта.
Ссылка: synthesia.io.
Профессиональные программы (с ручным контролем)
Подходят, если хочешь больше кастомизации, но всё равно просто.
Adobe Character Animator (платный, пробная версия)
Как использовать: Импортируй фото как слои. Создай риг лица (автоматически или вручную). Анимируй выражения (морщинки, рот) с помощью ключевых кадров. Для простоты используй готовые шаблоны.
Плюсы: Высокое качество, интеграция с Photoshop.
Минусы: Требует Adobe CC.
Ссылка: adobe.com/products/character-animator.html.
Toonly или Powtoon (платные с бесплатными пробами)
Как использовать: Загрузи фото в библиотеку. Создай слайды с анимацией (например, переходы между выражениями). Добавь движения (глаза, рот). Экспортируй как GIF или видео.
Плюсы: Дружелюбный интерфейс, много шаблонов.
Минусы: Ориентировано на презентации, не чисто на лица.
Ссылка: toonly.com или powtoon.com.
Бесплатные альтернативы (для энтузиастов)
Если бюджет ограничен, попробуй эти.
Blender (бесплатный, скачиваемый)
Как использовать: Импортируй фото как текстуры для 3D-модели. Используй addon (например, Rigify) для простого рига лица. Анимируй ключевые кадры (открытый/закрытый рот). Для простоты следуй туториалам по "face animation from photos".
Плюсы: Полная свобода, рендер в видео.
Минусы: Крутая кривая обучения (смотри YouTube-туториалы).
Ссылка: blender.org.
GIMP + GAP (GIMP Animation Package) (бесплатный)
Как использовать: Открой фото как слои в GIMP. Используй GAP для создания анимации (например, моргание глаз или движение рта). Сохрани как GIF.
Плюсы: Просто для 2D-анимации
Минусы: Базовая анимация, без AI
Ссылка: gimp.org (GAP — addon)
Советы по выбору и использованию
Для простоты: Начни с D-ID или HeyGen — они генерируют анимацию из фото автоматически. Загрузи фото, выбери стиль и получи видео за минуты.
Требования: Фото должны быть похожими (один человек, хорошее освещение). Для анимации рта добавь фото с открытым/закрытым ртом.
Если нужно больше: Для real-time анимации попробуй FaceRig (бесплатно), но он требует камеры.
Тестирование: Создай короткую анимацию (5–10 секунд) и проверь на синхронность.
Если укажешь, какие фото у тебя есть (например, количество или стиль), или предпочитаешь конкретный софт, я дам более детальные шаги или примеры
Свидетельство о публикации №125090602500