Как сделать фотографии с хроматическим ключом (маскировка зеленого экрана) - PullRequest
2 голосов
/ 02 марта 2020

Цель

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

Source photo Я просто хочу использовать зеленый экран для создания маска для каждого изображения, которое выглядит здесь вот так (границу желательно немного сгладить):

mask

Вот исходное изображение, если Вы хотите сделать тесты: https://mega.nz/#! 0YJnzAJR! GRYI4oNWcsKztHGoK7e4uIv_GvXBjMvyry7cPmyRpRA


Что я пробовал

Я нашел эту * 1024 пользователь использовал Imagemagick для достижения цветового ввода.

for i in *; do convert $i -colorspace HSV -separate +channel \
  \( -clone 0 -background none -fuzz 3% +transparent grey43 \) \
  \( -clone 1 -background none -fuzz 10% -transparent grey100 \) \
  -delete 0,1 -alpha extract -compose Multiply -composite \
  -negate mask_$i; done;

Но как бы я ни настраивал числа, результаты не идеальны: result


Я чувствую себя действительно глупо, что я не могу найти решение такой простой проблемы сам. Также обратите внимание, что я использую Linux. Так что нет Photoshop или After Effects! :)

Но я уверен, что должно быть решение этой проблемы.

Обновление 1

Я только что попытался использовать этот сценарий greenscreen на fmw42 , запустив ./greenscreen infile.jpg outfile.png, и я довольно доволен результатом. Но требуется около 40 секунд для обработки одного изображения, что дает в общей сложности 8 часов для всех моих изображений (хотя у меня довольно мощная рабочая станция, см. Спецификации ниже ) Возможно, в этом есть что-то что делать с теми ошибками, которые возникают при обработке?:

convert-im6.q16: width or height exceeds limit `black' @ error/cache.c/OpenPixelCache/3911.
convert-im6.q16: ImageSequenceRequired `-composite' @ error/mogrify.c/MogrifyImageList/7995.
convert-im6.q16: no images defined `./GREENSCREEN.6799/lut.png' @ error/convert.c/ConvertImageCommand/3258.
convert-im6.q16: unable to open image `./GREENSCREEN.6799/lut.png': No such file or directory @ error/blob.c/OpenBlob/2874.
convert-im6.q16: ImageSequenceRequired `-clut' @ error/mogrify.c/MogrifyImageList/7870.
convert-im6.q16: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `mask.png' @ warning/png.c/MagickPNGWarningHandler/1667.

Характеристики рабочей станции

  • Память : 125,8 ГиБ
  • Процессор : AMD® Ryzen 9 3900x 12-ядерный процессор × 24
  • Графика : GeForce GTX 970 / PCIe / SSE2 (два из них)

Ответы [ 3 ]

2 голосов
/ 09 марта 2020

Мы знаем, что фон имеет зеленый цвет и отличается от объекта по цвету, поэтому я предлагаю использовать цветовой порог. Для этого я написал простой код OpenCV Python, чтобы продемонстрировать результаты.

Сначала нам нужно установить OpenCV.

sudo apt update
pip3 install opencv-python
# verify installation
python3 -c "import cv2; print(cv2.__version__)"

Затем мы создадим скрипт с именем * 1006. * в одном каталоге с изображениями.

import cv2
import numpy as np

def show_result(winname, img, wait_time):
    scale = 0.2
    disp_img = cv2.resize(img, None, fx=scale, fy=scale)
    cv2.imshow(winname, disp_img)
    cv2.waitKey(wait_time)

img = cv2.imread('skull.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# define range of green color in HSV
lower_green = np.array([70, 200, 100])
upper_green = np.array([90, 255, 255])
# Threshold the HSV image to extract green color
mask = cv2.inRange(hsv, lower_green, upper_green)
mask = cv2.bitwise_not(mask)

#cv2.imwrite('mask.png', mask)
show_result('mask', mask, 0)
cv2.destroyAllWindows()

Вы можете легко найти учебное пособие по цветовым операциям HSV, используя OpenCV. Я не буду go рассматривать функции, используемые здесь, но важна одна часть. Операции с изображениями обычно выполняются в цветовом пространстве RGB, которое содержит красные, зеленые и синие компоненты. Тем не менее, HSV больше похож на систему человеческого зрения, которая содержит компоненты оттенка, насыщенности и значения. Вы можете найти преобразование здесь . Поскольку мы разделяем цвет на основе нашего восприятия, HSV больше подходит для этой задачи.

Важной частью является правильный выбор пороговых значений. При осмотре я выбрал около 80 для оттенка (что составляет максимум 180) и выше 200 и 100 для насыщенности и значения (максимум 255) соответственно. Вы можете напечатать значения определенного пикселя следующими строками:

rows,cols,channels = hsv.shape
print(hsv[row, column])

Обратите внимание, что начало координат находится в левом верхнем углу.

Вот результат: mask.png

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

for i in range(1, 100):
    img = imread(str(i) + '.jpg')
def mouse_callback(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        row = y
        column = x
        print(row, column)

winname = 'img'
cv2.namedWindow(winname)
cv2.setMouseCallback(winname, mouse_callback)

Имейте в виду, что функция show_result изменяет размер изображения по коэффициенту масштабирования.

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

kernel = np.ones((11,11), np.uint8)
opened = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
closed = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

Результат с открытием (ядро = 11x11): opened.png

2 голосов
/ 09 марта 2020

Я не могу вписать это в комментарий, поэтому я поставил это как ответ. Если вы хотите использовать greenscreen сценарий Фреда, вы можете использовать GNU Parallel , чтобы ускорить его.

Допустим, вы используете команды:

mkdir out
greenscreen image.png out/image.png

для обрабатывая один образ, и у вас есть тысячи, вы можете сделать следующее, чтобы все ядра вашего ЦП работали параллельно, пока все они не будут обработаны:

mkdir out
parallel greenscreen {} out/{} ::: *.png
2 голосов
/ 03 марта 2020

Если в Unix -подобной системе вы можете попробовать мой зеленый экранный скрипт, который выполняет вызовы ImageMagick и написан на Bash Unix. Например:

Ввод:

enter image description here

greenscreen img.jpg result.png

Результат (зеленый стал прозрачным):

enter image description here

Результат был уменьшен в размере на 50%, просто чтобы StackOverflow не возражал против слишком большого исходного результата. Однако StackOverflow изменил изображение с прозрачного PNG на белый фон JPG.

Обратите внимание, что другим изображениям могут потребоваться значения для аргументов, отличных от значений по умолчанию. Вы можете получить мой сценарий на http://www.fmwconcepts.com/imagemagick/. Обратите внимание, что для коммерческого использования вам необходимо связаться со мной по поводу лицензирования.

...