Четверг, 04 апреля 2019 20:42

Раскраска старых черно-белых фотографий и видео с помощью OpenCV и Искусственного Интеллекта.

Оцените материал
(2 голосов)

Этот проект основан на исследовательской работе, разработанной в Калифорнийском университете в Беркли Ричардом Чжаном, Филиппом Изолой и Алексеем А. Эфросом. Оригинал - Colorful Image Colorization.

Общее

Идея этого урока будет заключаться в разработке полностью автоматического подхода, который будет генерировать реалистичные цвета в черно-белых (B & W) фотографиях и видео. В оригинальной статье, авторы приняли глубинную неопределенность проблемы, представив ее в качестве задачи классификации с использованием классовой балансировки во время обучения для увеличения разнообразия цветов в результате. Подход искусственного интеллекта (ИИ) реализован в виде прямого прохода в СНС ("Свёрточная Нейронная Сеть") / CNN (" Convolutional Neural Network") во время тестирования и обучен работе с более чем миллионом цветных изображений.

Вот фотокарточка 1906 года, на которой показано одно из первых испытаний самолета Сантоса Дюмона "14-бис" в Париже:

Черно-белая версия фотографии

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

Цветная фотография после обработки ИИ

Такая же техника может быть применена к старым видеозаписям. Здесь видеозапись черно-белой съемки города Рио-де-Жанейро, Бразилия, 1932 года:

И этаже версия, но уже в цвете:

 

Шаг 1: Lab Цветового Пространства

Обычно мы привыкли кодировать цветные фотографии с помощью модели RGB. Цветовая модель RGB является разновидностью цветовой модели, в которой красный, зеленый и синий свет суммируются различными способами для получения широкого спектра цветов. Название модели происходит от инициалов трех основных добавочных цветов: красного, зеленого, и синего. (red, green, blue)

RGB illumination

Но моделью, которая будет использоваться в этом проекте, является "Lab.

Цветовое пространство CIELAB (также известное как CIE L*a*b* или иногда сокращенно просто "Lab" цветового пространства) - это цветовое пространство, определенное Международной комиссией по освещению (CIE) в 1976 году. Он выражает цвет как три числовых значения: L* для яркости и a* и b* для зелено-красных и сине-желтых компонентов цвета.

Цветовое пространство L * a * b * * было создано по теории противоположных цветов, где два цвета не могут быть одновременно зелеными и красными, или желтыми и синими. CIELAB был разработан таким образом, чтобы быть концептуально единообразным по отношению к цветовому зрению человека, означая, что одинаковое количество числовых изменений в этих значениях соответствует примерно такому же количеству визуально воспринимаемых изменений.

В отличие от цветовой модели RGB, цвет Lab предназначен для соответсвия человеческому зрению. Она стремится к единообразию восприятия, а ее L-компонент тесно связан с восприятием человека. Компонент L является именно тем, что используется в качестве входных данных для модели ИИ, то есть для оценки оставшихся компонентов "a" и "b".

 

Шаг 2: Процесс ИИ (Глубокое Обучение)

Как было отмечено во введении, подход искусственного интеллекта (ИИ) реализован в виде прямого прохода в СНС ("Свёрточная Нейронная Сеть") во время тестирования и обучен работе с более чем миллионом цветных изображений. Другими словами, миллионы цветных фотографий были разложены с помощью Lab-модели и использованы в качестве входных параметров ("L") и классификационных меток ("a" и "b"). Для простоты разделимся на две части: "L" и "a+b", как показано на блок-схеме:

cnn training

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

cnn model

Короче говоря, используя широкий и разнообразный набор объектов и сценических данных, состоящий из 1,3-миллионных фотографий из ImageNet и применяя алгоритм глубокого изучения (Feed-Forward СНС), были созданы и доступны окончательные модели:

 

Модели

 

Шаг 3: Рабочая среда

FLHHZDIJTENDEHH.LARGE

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

  • Photo_Video_Colorization

В созданной директорией, давайте создадим вложенные папки:

  • Model
  • input_images
  • input_videos
  • colorized_images
  • colorized_frames
  • colorized_videos

Перейдите в хранилище, и скачайте 3 файла,  после чего переместите их в созданную подпапку "/model". Эти файлы:

  • colorization_release_v2.caffemodel
  • colorization_release_v2_norebal.caffemodel
  • colorization_release_v1.caffemodel

Предполагаю, что на вашем компьютере установлены Python (версия 3.6) и OpenCV (4.0). Мы опишем поэтапно весь процесс раскрашивания с помощью Jupyter Notebooks. Я рекомендую вам следовать пошагово по инструкции, но если хотите, Вы можете скачать файлы и тестовые фотографии из моего GitHub, Зеркало.

Я также рекомендую вам ознакомиться с замечательным учебником доктора Эдриан Роузброк "Черно-белые цвета изображения с OpenCV и Глубокое Обучение", который стал руководством для этого проекта.

 

Шаг 4: Черно-белая окраска фотографий

F20H2SEJTENDONY.LARGE

Каждый из следующих шагов - это отдельная ячейка в Jupyter.:

1. Import important Libraries / Импортируйте важные библиотеки:

import numpy as np
import matplotlib.pyplot as plt
import cv2

2. Define Image to be colorized / Определите цвет раскрашиваемого изображения:

IMAGE = "soldiers_1941"

Примечание: здесь Вы можете использовать любую фотографию. В данном случае, я использую черно-белую фотографию 1941 г. солдат во время Второй мировой войны. Фотография доступна на моем GitHub.

3. Define Model Paths / Определение Путей Моделей:

prototxt = "./model/colorization_deploy_v2.prototxt"
model = "./model/colorization_release_v2.caffemodel"
points = "./model/pts_in_hull.npy"
image =  "./input_images/"+IMAGE

4. Load serialized black and white colorizer model and cluster / Загрузить сериализованный черно-белый колорификатор модели и кластер:

net = cv2.dnn.readNetFromCaffe(prototxt, model)
pts = np.load(points)

5. Add the cluster centers as 1x1 convolutions to the model / Добавьте к модели кластерные центры в виде сверток 1x1:

class8 = net.getLayerId("class8_ab")
conv8 = net.getLayerId("conv8_313_rh")
pts = pts.transpose().reshape(2, 313, 1, 1)
net.getLayer(class8).blobs = [pts.astype("float32")]
net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]

6. Load the input image, scale it and convert it to Lab / Загрузите входное изображение, масштабируйте его и конвертируйте в Lab:

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

image = cv2.imread(image)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)

На данный момент у нас есть исходное изображение, но для того, чтобы показать его прямо на ячейке Jupyter, мы должны использовать библиотеку pyplot:

plt.imshow(image)
plt.axis('off');

soldiers 1941

7. Extracting "L" / Извлечение “l”:

Теперь возьмем наше "изображение" и перейдем к процессу окрашивания, где сначала нужно перемасштабировать, преобразовав его в Lab, чтобы извлечь компонент "L" и отцентрировать его:

scaled = image.astype("float32") / 255.0
lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB)
resized = cv2.resize(lab, (224, 224))
L = cv2.split(resized)[0]
L -= 50

8. Predicting "a" and "b" / Прогнозирование "a" and "b":

net.setInput(cv2.dnn.blobFromImage(L))
ab = net.forward()[0, :, :, :].transpose((1, 2, 0))
ab = cv2.resize(ab, (image.shape[1], image.shape[0]))

9. Creating a colorized Lab photo (L + a + b) / Создание цветной Lab фотографии (L + a + b):

L = cv2.split(lab)[0]
colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2)

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

plt.imshow(colorized)
plt.axis('off');
plt.title('colorized LAB image');

lab soldiers

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

10. Converting to RGB / Преобразование в RGB:

colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2RGB)
colorized = np.clip(colorized, 0, 1)
colorized = (255 * colorized).astype("uint8")
plt.imshow(colorized)
plt.axis('off');

Color soldiers 1941

Уау! Довольно удивительно! Это фотография 1941 года, которая, кажется, будто была всегда цветной! Давайте сохраним результат:

11. Saving the final RGB photo / Сохранение результата в формате RGB:

cv2.imwrite("./colorized_images/Color_"+IMAGE, cv2.cvtColor(colorized, cv2.COLOR_RGB2BGR))

Еще один результат: Чарльз Дарвин посетил Рио в 1832 году:

darwin in rio

 

Шаг 5: Окрашивание видео

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

  1. Получить черно-белые кадры и загрузить их в подкаталог input_video/.
  2. Читать видео по одному кадру за раз
  3. Имея один кадр, применить то, что мы сделали для фотографии
  4. Имея раскрашенный кадр, сохраните его в другой подпапке: colorized_video_frames
  5. Закрыть окна OpenCv.

Давайте займемся настоящим делом:

Загрузите B_W_Video_Colorization.ipynb Зеркало из моего GitHub.

Первым тестом, который я сделал, был скаченый с Youtube ч/б фильм:

Для этого я использовал бесплатный инструмент: VidPaw.

Применяяя описанные выше шаги, в конце мы сохраним все окрашенные кадры в подпапке colorized_video_frames. Давай сделаем это:

1. Начните с определения файла, который должен быть окрашен (который должен находиться в папке input_video):

VIDEO = "rio_32.mp4"

2. Определение путей, констант и переменных видео:

prototxt = "./model/colorization_deploy_v2.prototxt"
model = "./model/colorization_release_v2.caffemodel"
points = "./model/pts_in_hull.npy"
video =  "./input_video/"+VIDEO
width = 500
vs = cv2.VideoCapture(video)

3. Загрузка и подготовка модели:

net = cv2.dnn.readNetFromCaffe(prototxt,model)
pts = np.load(points)
class8 = net.getLayerId("class8_ab")
conv8 = net.getLayerId("conv8_313_rh")
pts = pts.transpose().reshape(2, 313, 1, 1)
net.getLayer(class8).blobs = [pts.astype("float32")]
net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")] 

4. Разделение видео, показ кадр за кадром и применение модель:

count = 0
success = True
while success:
	success, frame = vs.read()
	if frame is None:
		break

	frame = imutils.resize(frame, 500)
	frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)
	scaled = frame.astype("float32") / 255.0
	lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB)

	resized = cv2.resize(lab, (224, 224))
	L = cv2.split(resized)[0]
	L -= 50
    
	net.setInput(cv2.dnn.blobFromImage(L))
	ab = net.forward()[0, :, :, :].transpose((1, 2, 0))

	ab = cv2.resize(ab, (frame.shape[1], frame.shape[0]))
	L = cv2.split(lab)[0]
	colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2)

	colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR)
	colorized = np.clip(colorized, 0, 1)
	colorized = (255 * colorized).astype("uint8")

	cv2.imshow("Original", frame)
	cv2.imshow("Colorized", colorized)
    
	cv2.imwrite("./colorized_video_frames/frame%d.jpg" % count, colorized)
	count += 1
	key = cv2.waitKey(1) & 0xFF

	if key == ord("q"):
		break

vs.release()
cv2.destroyAllWindows()

Вышеуказанный цикл обычно занимает некоторое время. Например, процесс окрашивания этого видео (8 минут), имеющего около 14 000 кадров, занял у меня около 3 часов на MacBook Pro - 2,9 ГГц Core i7 с 16 ГБ 2133 МГц оперативной памяти.

5. После того, как у вас есть файлы с кадрами, вы должны "собрать" его заново, чтобы создать видео. Данная функция может это сделать:

def convert_frames_to_video(pathIn, pathOut, fps):
    frame_array = []
    files = [f for f in os.listdir(pathIn) if isfile(join(pathIn, f))]
 
    #for sorting the file names properly
    files.sort(key = lambda x: int(x[5:-4]))
 
    for i in range(len(files)):
        filename=pathIn + files[i]
        #reading each files
        img = cv2.imread(filename)
        height, width, layers = img.shape
        size = (width,height)
        print(filename)
        #inserting the frames into an image array
        frame_array.append(img)
 
    out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'MJPG'), fps, size)
 
    for i in range(len(frame_array)):
        # writing to a image array
        out.write(frame_array[i])
    out.release()

Обратите внимание, что в зависимости от того, какой Video Controler установлен на вашем компьютере, кодек (*'MJPG') должен быть изменен. Пожалуйста, ознакомьтесь с документацией OpenCV. В конце концов, это был бы опыт "проб и ошибок".

Теперь он применяется только для того, чтобы применить функцию на окрашенных кадрах:

pathIn= './colorized_video_frames/'
pathOut = './colorized_videos/color_rio_32.avi'
fps = 30.0
convert_frames_to_video(pathIn, pathOut, fps)

Полученное "сырое" видео можно посмотреть здесь:

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

 

Шаг 7: Итог

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

Для получения подробностей и окончательного кода, пожалуйста, посетите репозиторий GitHub: MJRoBot-Python4DS, Зеркало

Источник

Author

Bender

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

Комментарии (0)

There are no comments posted here yet

Оставьте свой комментарий

  1. Posting comment as a guest. Sign up or login to your account.
Вложения (0 / 3)
Share Your Location

О нас

Основой деятельностью портала является показ и объяснение что представляет собой выражени "Робот", "Робототехника", "Законы робототехники", "Мехатроника", "Искусственный интеллект(ИИ)". 

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