Как добавить изображение позади объекта в видео

машинное обучение

Автор|PRATEEK JOSHI Компилировать|ВКонтакте Источник | Аналитика Видья

Обзор

  • Добавление изображений позади движущихся объектов — типичный проект компьютерного зрения.

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

вводить

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

Как вы понимаете, это очень интересный проект.

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

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

Я построил эту систему компьютерного зрения, используя Python и OpenCV, и делюсь своим подходом в этой статье.

содержание

  • понять постановку задачи

  • Получить данные для этого элемента

  • Создайте план для нашего проекта компьютерного зрения

  • Реализуем эту технику на Python — давайте добавим логотип!

понять постановку задачи

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

Однако логотип может просто скрывать какое-то интересное действие в видео. Что делать, если знак мешает движущимся впереди объектам? Это будет выглядеть очень низко.

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

Видео ниже — левая половина оригинального видео, правая половина с логотипом на стене позади танцора:

видео:youtu.be/L9KsuvO0VMs

Именно эту идею мы реализуем в этой статье.

Получить данные для этого элемента

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

Итак, пока мы будем использовать собственные флаги OpenCV. Вы можете использовать любой логотип (может быть, ваша любимая спортивная команда?).

Видео и логотип можно скачать отсюда.

drive.Google.com/file//1MX J…

Создайте план для нашего проекта компьютерного зрения

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

Предположим, мы хотим поместить прямоугольник (изображение 1) на изображение (изображение 2), чтобы круг на втором изображении оказался поверх прямоугольника:

Итак, ожидаемый результат должен быть примерно таким:

Однако это не так просто. Когда мы выберем прямоугольник с изображения 1 и вставим его в изображение 2, он появится поверх розового круга:

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

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

Следовательно, мы можем установить значение пикселя прямоугольника равным 1, где он должен перекрывать круг (на рис. 5), оставив остальную часть значения пикселя прямоугольника без изменений.

На рис. 6 область, обведенная синей пунктирной линией, — это область, в которой мы разместили прямоугольник. Обозначим эту область в R. Мы также устанавливаем все значения пикселей R равными 1. Однако мы сохраним значения пикселей всего розового круга без изменений:

Наш следующий шаг — умножить значение пикселя прямоугольника на значение пикселя R. Поскольку любое число, умноженное на 1, получает само число, все значения пикселей R будут заменены пикселями прямоугольника.

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

Это метод, который мы собираемся использовать, обоснование встраивания логотипов OpenCV в видео. Вот так!

Реализация этой техники в Python

Вы можете использовать Jupyter Notebook или любую IDE по вашему выбору и продолжить. Сначала мы импортируем необходимые библиотеки.

библиотека импорта

import cv2
import re
import os
import random
import numpy as np
import matplotlib.pyplot as plt
from os.path import isfile, join

Примечание. Версия библиотеки OpenCV, используемая в этом руководстве, — 4.0.0.

загрузить изображение

Далее укажем путь к рабочей директории, куда будут сохранены логотип и видео. Обратите внимание, что вы должны указать «путь» в приведенном ниже фрагменте кода:

# 指定工作目录的路径
path = ".../"

# 读取logo图像
logo = cv2.imread(path+"opencv_logo.png")

# 阅读视频的第一帧
cap = cv2.VideoCapture(path+"Pexels Videos 2675513.mp4")
ret, frame = cap.read()

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

logo.shape, frame.shape

вывод: ((240, 195, 3), (1080, 1920, 3))

Оба выхода трехмерные. Первое измерение — это высота изображения, второе — ширина изображения, а третье — количество каналов в изображении, т. е. синий, зеленый и красный.

Теперь нарисуем и просмотрим логотип и первый кадр видео:

plt.imshow(logo)
plt.show()

plt.imshow(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
plt.show()

техника маскирования изображения

Размер рамки намного больше логотипа. Поэтому мы можем разместить логотип во многих местах.

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

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

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

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

Мы должны сделать так, чтобы пиксели стены, заключенные в зеленую пунктирную рамку, имели одинаковое значение. Мы можем сделать это с помощью цветового пространства HSV (Hue, Saturation, Value):

Наше изображение находится в цветовом пространстве RGB. Мы преобразуем его в изображение HSV. На картинке ниже показана версия HSV:

Следующим шагом является поиск только диапазона значений HSV для частей внутри зеленой пунктирной рамки. Результаты показывают, что большинство пикселей в рамке находятся в диапазоне от [6, 10, 68] до [30, 36, 122]. Это верхний и нижний диапазоны HSV соответственно.

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

Ниже представлена ​​маска, приготовленная из изображения HSV. Все пиксели в желтой области имеют значение 255 пикселей, а остальные имеют значение 0:

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

# HSV的范围
lower = np.array([6,10,68])
upper = np.array([30,36,122])

# 为图像创建核
kernel = np.ones((3,3),np.uint8)

# 每次运行以下while循环时,执行下面的两行
cap = cv2.VideoCapture(path+"Pexels Videos 2675513.mp4")
cnt = 0

# 循环加载、预处理和显示帧
while(True):
    ret, f = cap.read()

    # 提取我们将放置logo的区域
    # 此区域的尺寸应与logo的尺寸相匹配
    mini_frame = f[500:740,875:1070,:]

    # 创建 HSV 图像
    hsv = cv2.cvtColor(f, cv2.COLOR_BGR2HSV)

    # 创建掩码
    mask = cv2.inRange(hsv, lower, upper)

    dil = cv2.dilate(mask,kernel,iterations = 5)

    # 创建3个通道
    mini_dil = np.zeros_like(mini_frame)
    mini_dil[:,:,0] = dil[500:740,875:1070]
    mini_dil[:,:,1] = dil[500:740,875:1070]
    mini_dil[:,:,2] = dil[500:740,875:1070]

    # 复制logo图像
    logo_copy = logo.copy()

    # 当掩码的像素值为0时,将像素值设置为1
    logo_copy[mini_dil == 0] = 1

    # 将标识的像素值设置为1,其中标识的像素值为0
    logo_copy[logo == 0] = 1    

    # 当logo的像素值不为1时,将像素值设置为1
    mini_frame[logo_copy != 1] = 1

    # 合并图像(数组乘法)
    mini_frame = mini_frame*logo_copy

    # 在框架中插入logo
    f[500:740,875:1070,:] = mini_frame

    # 调整框架的大小(可选)
    f = cv2.resize(f, (480, 270), interpolation = cv2.INTER_AREA)

    # 显示帧
    cv2.imshow('frame', f)

    # 保存帧
    # cv2.imwrite(path+'frames/'+str(cnt)+'.png',f)
    cnt+= 1

    if cv2.waitKey(20) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

Приведенный выше фрагмент кода загрузит кадры из видео, предварительно обработает их, создаст изображение и маску HSV и, наконец, вставит логотип в видео. вы сделали!

конец

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

Это поможет вам при решении других задач компьютерного зрения.

Оригинальная ссылка:Woohoo.Со слов аналитиков vi.com/blog/2020/0…

Добро пожаловать на сайт блога Panchuang AI:panchuang.net/

sklearn машинное обучение китайские официальные документы:sklearn123.com/

Добро пожаловать на станцию ​​сводки ресурсов блога Panchuang:docs.panchuang.net/