【问题标题】:How to Batch Chroma Key Photos (Masking Green Screen)如何批处理色度键照片(屏蔽绿屏)
【发布时间】:2021-09-15 14:18:25
【问题描述】:

目标

我这里有数百张看起来都与这张相似的图片:

我只是想使用绿屏为每个看起来像这里的图像创建一个蒙版(最好将边框平滑一点):

如果你想做测试,这里是原图:https://mega.nz/#!0YJnzAJR!GRYI4oNWcsKztHGoK7e4uIv_GvXBjMvyry7cPmyRpRA


我尝试过的

我发现this 帖子中用户使用 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;

但无论我如何调整数字,结果都不完美:


我觉得自己真的很愚蠢,我自己找不到解决如此简单问题的方法。另请注意,我使用的是 Linux。所以没有 Photoshop 或 After Effects! :)

但我确信必须有解决这个问题的办法。

更新 1

我刚刚通过运行./greenscreen infile.jpg outfile.png 尝试使用this greenscreen script by fmw42,我对结果相当满意。 但是处理一张图像大约需要 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 GiB
  • 处理器:AMD® Ryzen 9 3900x 12 核处理器 × 24
  • 显卡:GeForce GTX 970/PCIe/SSE2 (其中两个)

【问题讨论】:

  • 你试过这个:fmwconcepts.com/imagemagick/greenscreen/index.php?如果这是用于商业项目,您需要付费才能使用它。
  • 是的,它工作得很好,但是处理图像需要很长时间(请参阅我更新的问题)
  • 关于我脚本中的错误消息,您的 ImageMagick 版本是多少?

标签: image image-processing imagemagick batch-processing chromakey


【解决方案1】:

我们知道背景是绿色的,可以通过颜色与对象区分开来,所以我建议使用颜色阈值。为此,我编写了一个简单的 OpenCV Python 代码来演示结果。

首先,我们需要安装 OpenCV。

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

然后,我们在与图像相同的目录中创建一个名为skull.py 的脚本。

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()

您可以轻松找到有关使用 OpenCV 进行 HSV 颜色操作的教程。我不会详细介绍这里使用的功能,但有一部分很重要。图像操作通常在 RGB 颜色空间中完成,其中包含红色、绿色和蓝色分量。然而,HSV 更像是人类视觉系统,它包含色调、饱和度和值组件。您可以找到conversion here。由于我们根据感知来区分颜色,因此 HSV 更适合这项任务。

关键部分是适当地选择阈值。我通过检查选择了 80 左右的色调(最大 180),分别选择 200 和 100 以上的饱和度和值(最大 255)。您可以通过以下几行打印特定像素的值:

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

注意原点在左上角。

结果如下:

可能需要两件事。一个是对一组图像进行操作,这对于使用 for 循环来说是微不足道的。另一个是如果您不喜欢结果的某些部分,您可能想知道像素位置并相应地更改阈值。这可以通过鼠标事件来实现。

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 函数会根据比例因子调整图像大小。

如果您不想处理像素位置,而是想要平滑的结果,您可以申请morphological transformations。特别是打开和关闭将完成工作。

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

打开结果(内核=11x11):

【讨论】:

  • 哇,这正是我想要的,谢谢!我不知道为什么我没有使用 OpenCV :D
【解决方案2】:

我真的无法将其放入评论中,因此我将其作为答案。如果你想使用 Fred 的 greenscreen 脚本,你可以使用 GNU Parallel 来加速它。

假设你使用命令:

mkdir out
greenscreen image.png out/image.png

要处理一个图像,并且您有数千个图像,您可以执行以下操作以保持所有 CPU 内核并行忙碌,直到它们全部处理完毕:

mkdir out
parallel greenscreen {} out/{} ::: *.png

【讨论】:

  • 绝对是使用这个脚本的方法!但我更喜欢使用@Burak 的解决方案,因为它更快,代码也更容易。还是谢谢你!
【解决方案3】:

如果在类 Unix 系统上,您可以尝试我的调用 ImageMagick 并用 Bash Unix 编写的绿屏脚本。例如:

输入:

greenscreen img.jpg result.png

结果(绿色变透明):

结果的大小减少了 50%,只是为了让 StackOverflow 不会反对原始结果太大。但是,StackOverflow 已将图像从透明 PNG 更改为白色背景 JPG。

请注意,其他图像可能需要默认值以外的参数值。您可以在http://www.fmwconcepts.com/imagemagick/ 获取我的脚本。请注意,对于商业用途,您需要就许可事宜与我联系。

【讨论】:

  • 那真是太好了!但不幸的是,这对我来说不可行,因为处理一张图像需要 40 秒,这意味着对所有图像执行此操作大约需要 8 小时(尽管我有一个相当强大的工作站)
  • 也许这与处理时发生的错误有关?(请参阅我更新的问题)
  • 您的 ImageMagick 版本是多少?在我的 Mac Mini 上只用了 18 秒。
  • 当我运行 convert -version 我得到这个输出:Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101... 我可能需要更新 :)
  • 但是当我运行 sudo apt install imagemagick 它告诉我:imagemagick is already the newest version (8:6.9.10.23+dfsg-2.1ubuntu3.1).
猜你喜欢
  • 2011-11-25
  • 2012-08-02
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 2020-12-28
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多