せっかくのグリーンスクリーンなので、らしい遊びをしてみた (2)

そりゃぁ「アレ」をするだけさ、てことで。

一つ前のまんまでやめちゃうと、やや消化不良よね、と。

tolerance を見りゃいいだけの話で:

 1 #
 2 import sys
 3 import argparse
 4 import logging
 5 import json
 6 
 7 import numpy as np
 8 import av
 9 from PIL import Image
10 
11 if __name__ == '__main__':
12     logging.basicConfig(stream=sys.stderr, level=logging.INFO)
13     parser = argparse.ArgumentParser()
14     parser.add_argument("background")
15     parser.add_argument("greenback")
16     parser.add_argument("outfile")
17     parser.add_argument("--pick", type=str, default="[0, 0]")
18     parser.add_argument("--atol", type=int, default=30)
19     args = parser.parse_args()
20     pick = tuple(json.loads(args.pick))
21 
22     icontbg = av.open(args.background)
23     icontgb = av.open(args.greenback)
24     ivstrbg = next(s for s in icontbg.streams if s.type == b'video')
25     ivstrgb = next(s for s in icontgb.streams if s.type == b'video')
26     ocont = av.open(args.outfile, "w")
27     ovstr = ocont.add_stream(codec_name="h264", rate=ivstrbg.rate)
28     ovstr.width = ivstrbg.width
29     ovstr.height = ivstrbg.height
30     for packets in zip(icontbg.demux(ivstrbg), icontgb.demux(ivstrgb)):
31         for iframes in zip(packets[0].decode(), packets[1].decode()):
32             logging.info(iframes)
33             imgbg = iframes[0].to_image()
34             imggb = iframes[1].to_image().resize(imgbg.size)
35             keyclr = imggb.getpixel(pick)
36 
37             r = np.array(imggb.getdata(0))
38             g = np.array(imggb.getdata(1))
39             b = np.array(imggb.getdata(2))
40             a = np.zeros(r.shape)
41             a[np.logical_and(
42                     np.isclose(r, keyclr[0], atol=args.atol),
43                     np.isclose(g, keyclr[1], atol=args.atol),
44                     np.isclose(b, keyclr[2], atol=args.atol))] = 255
45             alpha = Image.new("L", imggb.size)
46             alpha.putdata(a.flatten())
47             mask = imggb.copy()
48             mask.putalpha(alpha)
49 
50             dimg = Image.composite(imgbg, imggb, mask)
51 
52             ofr = av.VideoFrame.from_image(dimg)
53             for p in ovstr.encode(ofr):
54                 ocont.mux(p)
55     ocont.close()

isclose 使っただけね、本質的には。あとは抜く色のピックアップをする位置指定をオプション指定出来るようにもしてるけど。

てわけで(atol=50):

まぁこんなもんでしょ。