Преобразование видео в мультфильм на Python и CV2

Рассказываем, как превратить видео с мультик при помощи Python и CV2, разбив видео на изображения и объединив обратно после преобразования.

1К открытий5К показов

Если вы последние несколько месяцев следили за разработками в области нейросетей, то наверняка сталкивались с такими проектами.

Однако, не все могут позволить себе тратить время на обработку каждого кадра видео, а также не всегда у компьютеров есть достаточно мощности для использования stable diffusion и подобных алгоритмов. В этом случае можно попробовать другой подход – создание мультфильма из видео. Привожу готовый код на github, который будет объяснен по ходу статьи.

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

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

Вначале необходимо импортировать необходимые библиотеки:

			import cv2
import numpy as np
		

Далее необходимо создать функции:

			def color_quantization(img, k):
# Transform the image
  data = np.float32(img).reshape((-1, 3))

# Determine criteria
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)

# Implementing K-Means
  ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
  center = np.uint8(center)
  result = center%save-sc0%
  result = result.reshape(img.shape)
  return result


def edge_mask(img, line_size, blur_value):
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  gray_blur = cv2.medianBlur(gray, blur_value)
  edges = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, line_size, blur_value)
  return edges
		

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

То же самое можно сказать про код сохранения и обработки:

			print("количество цветов на видео (рекомендуется 10-100)")
total_color = int(input())
line_size = 7
blur_value = 7
print("создание изображений...")
count = 1

vidcap = cv2.VideoCapture('vid.mp4')
success, image = vidcap.read()

while success:
  success, image = vidcap.read()

  edges = edge_mask(image, line_size, blur_value)
  image = color_quantization(image, total_color)
  blurred = cv2.bilateralFilter(image, d=7, sigmaColor=200,sigmaSpace=200)
  cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)

  cv2.imwrite(str(count) + '.jpg', cartoon)
  print("корректно сохранена " + str(count) + "-ая картинка")
  count += 1
		

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

Это — первая часть программы.

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

Как обычно, импорт библиотек:

			import cv2
import moviepy.editor as moviepy
from time import sleep
import os
		

Приём данных от пользователя:

			print("фотографий:")
count = int(input())
print("кадров в секунду:")
fps = int(input())
		

Далее — составление массива с фото и удаление этих фотографий, чтобы избежать ненужных файлов:

			counter = 1
img_array = []
for i in range(count):
    img = cv2.imread(str(counter) + ".jpg")
    height, width, layers = img.shape
    size = (width,height)
    img_array.append(img)
    if os.path.isfile(str(counter) + ".jpg"):
        os.remove(str(counter) + ".jpg")
    
    counter += 1

    if counter - 1 % 10 == 0:
      print("успешно превращены в видео " + str(counter) + " из " + str(count) + " фотографий")
		

Если вы хотите использовать полученные изображения, сотрите 8 и 9 строки.

Сборка видео из массива:

			out = cv2.VideoWriter('cartoon.avi',cv2.VideoWriter_fourcc(*'DIVX'), fps, size)
 
for i in range(len(img_array)):
    out.write(img_array[i])
out.release()

print("готово видео в формате .avi, но вы его нигде не воспроизведёте,")
		

Собственно, конвертация и сохранение:

			print("сейчас произойдёт конвертация в .mp4")
print("конвертация...")
print()
clip = moviepy.VideoFileClip("cartoon.avi")
clip.write_videofile("result.mp4")
print()

print("программа завершена! спасибо, что воспользовались cartooner 1.2!")
print("терминал автоматически закроется через 60 секунд")
sleep(60)
		

Вот и всё!

Примеры

Теперь проведём небольшое исследование модели, и получим видео:

Соответственно 10, 90 и 150 цветов. Заметно, что чем больше цветов, тем лучше качество, но и время генерации увеличивается пропорционально

Использование файлов .exe

Теперь рассмотрим использование файлов .exe из Яндекс диска. Скачиваем файлы, помещаем в отдельную папку. В эту же папку помещаем видео для превращения, переименовываем в vid.mp4, запускаем cartooner.exe, следуем инструкции. После окончания выполнения программы запускаем videoizer.exe и снова следуем инструкции. После выполнения программы вы получите: видео в формате avi, видео в формате mp4, возможно, несколько фотографий. Видео result.mp4 и есть результат работы программы. Помните, что при повторной генерации видео результата заместится новым.

Удачных компиляций!

Следите за новыми постами
Следите за новыми постами по любимым темам
1К открытий5К показов