-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpyvirtualbackground.py
109 lines (88 loc) · 3.67 KB
/
pyvirtualbackground.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import cv2 as cv
from segmentor import FaceSegmentation
from moviepy.video.io.VideoFileClip import VideoFileClip
import os
import tempfile
import shutil
import subprocess
import argparse
class Processor(FaceSegmentation):
x, y, w, h = 0, 0, 400, 400
def __init__(self, foreground: str, background: str) -> None:
self.foreground = foreground
self.background = background
self.tempdir = tempfile.mkdtemp()
self.curDir = os.getcwd()
self.foreSampled = "foreSampled.mp4"
self.backSampled = "backSampled.mp4"
self.outSampled = "output.mp4"
super().__init__()
def min(self, x: int, y: int):
if x < y:
return x
return y
def prep(self):
path = self.tempdir
foreGround = VideoFileClip(self.foreground)
backGround = VideoFileClip(self.background)
fps = self.min(foreGround.fps, backGround.fps)
self.fps = fps
foreSampled = foreGround.set_fps(fps)
backSampled = backGround.set_fps(fps)
forPath = os.path.join(path, self.foreSampled)
backPath = os.path.join(path, self.backSampled)
foreSampled.write_videofile(forPath)
backSampled.write_videofile(backPath)
return forPath, backPath
def convert(self):
backPath = self.tempdir + "/" + self.backSampled
outPath = self.tempdir + "/" + self.outSampled
subprocess.run(["ffmpeg", "-i", backPath, "-i", outPath, "-r", str(self.fps),
"-c:a", "copy", "-filter_complex", f"[0:v][1:v]overlay={self.x}:{self.y}", "out.mp4"])
shutil.rmtree(self.tempdir)
def outPath(self):
forTemp = os.path.join(self.tempdir, "output.mp4")
return forTemp
def process(self):
(fore, back) = self.prep()
outPath = self.outPath()
foreCapture = cv.VideoCapture(fore)
backCapture = cv.VideoCapture(back)
fourcc = cv.VideoWriter_fourcc(*'mp4v')
fFps = int(foreCapture.get(cv.CAP_PROP_FPS))
bFps = int(backCapture.get(cv.CAP_PROP_FPS))
out = cv.VideoWriter(outPath, fourcc,
self.min(fFps, bFps), (self.w, self.h))
print("processing")
while foreCapture.isOpened() and backCapture.isOpened():
gRet, foreFrame = foreCapture.read()
bRet, backFrame = backCapture.read()
if not gRet or not bRet:
break
foreFrame = cv.GaussianBlur(foreFrame, (3, 3), 0)
backFrame = cv.GaussianBlur(backFrame, (3, 3), 0)
try:
foreFrame = cv.resize(foreFrame, (self.w, self.h))
roi = backFrame[self.x:self.x + self.w, self.y: self.y+self.h]
outFrame = self.remove_bg(
foreFrame, roi, threshold=0.8, blur=(3, 3))
out.write(outFrame)
except ValueError:
print("Images not same size")
print(ValueError)
except:
print("Something else went WRONG!!")
foreCapture.release()
backCapture.release()
out.release()
cv.destroyAllWindows()
self.convert()
print("processing done... ")
if __name__ == "__main__":
description = "It eliminates backgrounds from videos and can be utilized in other applications as well."
parser = argparse.ArgumentParser(prog="pyvirtualbackground", description=description, epilog="text at the bottom of file")
parser.add_argument("-fore", "--inputfile")
parser.add_argument("-back", "--backgroundfile")
args = parser.parse_args()
processor = Processor(foreground=args.inputfile, background=args.backgroundfile)
processor.process()