Video-Summary/Application/Exporter.py

180 lines
7.7 KiB
Python
Raw Normal View History

2022-01-02 22:40:05 +00:00
from Application.Config import Config
2020-12-26 13:58:58 +00:00
from Application.Layer import Layer
from Application.VideoReader import VideoReader
from datetime import datetime
import imageio
2020-09-25 17:52:41 +00:00
import imutils
import numpy as np
2020-09-25 17:52:41 +00:00
import cv2
2020-10-16 08:36:52 +00:00
import pickle
2022-01-09 19:25:44 +00:00
import time
2020-12-26 13:58:58 +00:00
2020-09-20 20:01:54 +00:00
class Exporter:
fps = 30
2020-09-24 13:47:49 +00:00
2020-10-11 15:09:49 +00:00
def __init__(self, config):
self.footagePath = config["inputPath"]
self.outputPath = config["outputPath"]
self.resizeWidth = config["resizeWidth"]
self.config = config
print("Exporter initiated")
2020-09-24 13:47:49 +00:00
2020-12-26 13:58:58 +00:00
def export(self, layers, contours, masks, raw=True, overlayed=True):
2020-10-23 22:14:43 +00:00
if raw:
self.exportRawData(layers, contours, masks)
2020-11-08 15:28:47 +00:00
if overlayed:
2020-10-23 22:14:43 +00:00
self.exportOverlayed(layers)
2020-11-08 15:28:47 +00:00
else:
self.exportLayers(layers)
2020-09-25 17:52:41 +00:00
2020-11-11 17:37:25 +00:00
def exportLayers(self, layers):
2021-02-05 19:04:10 +00:00
# TODO: fix videoreader instanciation
2020-10-11 12:13:27 +00:00
listOfFrames = self.makeListOfFrames(layers)
2020-10-11 15:09:49 +00:00
videoReader = VideoReader(self.config, listOfFrames)
2020-10-11 12:13:27 +00:00
videoReader.fillBuffer()
maxLength = self.getMaxLengthOfLayers(layers)
2020-10-11 15:09:49 +00:00
underlay = cv2.VideoCapture(self.footagePath).read()[1]
2020-10-11 12:13:27 +00:00
underlay = cv2.cvtColor(underlay, cv2.COLOR_BGR2RGB)
exportFrame = 0
2020-10-11 15:09:49 +00:00
self.fps = videoReader.getFPS()
writer = imageio.get_writer(self.outputPath, fps=self.fps)
2020-11-11 17:37:25 +00:00
start = time.time()
for i, layer in enumerate(layers):
2022-01-09 19:25:44 +00:00
print(f"\r {i}/{len(layers)} {round(i/len(layers)*100,2)}% {round((time.time() - start), 2)}s", end="\r")
2020-11-11 17:37:25 +00:00
if len(layer.bounds[0]) == 0:
2020-09-29 20:52:36 +00:00
continue
2020-12-18 20:27:19 +00:00
videoReader = VideoReader(self.config)
2020-11-11 17:37:25 +00:00
listOfFrames = self.makeListOfFrames([layer])
2020-12-18 20:27:19 +00:00
videoReader.fillBuffer(listOfFrames)
2020-11-11 17:37:25 +00:00
while not videoReader.videoEnded():
frameCount, frame = videoReader.pop()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame2 = np.copy(underlay)
for (x, y, w, h) in layer.bounds[frameCount - layer.startFrame]:
if x is None:
continue
factor = videoReader.w / self.resizeWidth
2022-01-09 19:25:44 +00:00
x, y, w, h = (int(x * factor), int(y * factor), int(w * factor), int(h * factor))
frame2[y : y + h, x : x + w] = np.copy(frame[y : y + h, x : x + w])
timestr = datetime.fromtimestamp(int(frameCount / self.fps) + videoReader.getStartTime())
cv2.putText(
frame2,
str(i) + " " + f"{timestr.hour}:{timestr.minute}:{timestr.second}",
(int(x + w / 2), int(y + h / 2)),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(255, 255, 255),
2,
)
# cv2.putText(frame2, str(layer.stats["avg"]) + " " + str(layer.stats["var"]) + " " + str(layer.stats["dev"]), (int(500), int(500)), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,0,255), 2)
2020-11-11 17:37:25 +00:00
writer.append_data(frame2)
2020-11-21 18:13:17 +00:00
videoReader.vc.release()
2020-12-18 20:27:19 +00:00
videoReader.thread.join()
videoReader.vc.release()
videoReader.thread.join()
writer.close()
2020-10-11 15:09:49 +00:00
def exportOverlayed(self, layers):
listOfFrames = self.makeListOfFrames(layers)
2020-10-11 15:09:49 +00:00
videoReader = VideoReader(self.config, listOfFrames)
videoReader.fillBuffer()
2020-09-30 17:22:10 +00:00
maxLength = self.getMaxLengthOfLayers(layers)
2020-10-11 15:09:49 +00:00
underlay = cv2.VideoCapture(self.footagePath).read()[1]
underlay = cv2.cvtColor(underlay, cv2.COLOR_BGR2RGB)
2022-01-09 19:25:44 +00:00
# underlay = np.zeros(shape=[videoReader.h, videoReader.w, 3], dtype=np.uint8)
frames = []
for i in range(maxLength):
frames.append(np.copy(underlay))
exportFrame = 0
2020-09-30 17:22:10 +00:00
while not videoReader.videoEnded():
frameCount, frame = videoReader.pop()
2022-01-09 19:25:44 +00:00
if frameCount % (60 * self.fps) == 0:
print("Minutes processed: ", frameCount / (60 * self.fps), end="\r")
if frame is None:
print("ContourExtractor: frame was None")
continue
2020-10-13 22:16:39 +00:00
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
2020-09-30 17:22:10 +00:00
for layer in layers:
if layer.startFrame <= frameCount and layer.startFrame + len(layer.bounds) > frameCount:
2020-11-27 00:06:25 +00:00
for i in range(0, len(layer.bounds[frameCount - layer.startFrame])):
2022-01-02 22:40:05 +00:00
try:
underlay1 = underlay
2022-01-09 19:25:44 +00:00
(x, y, w, h) = layer.bounds[frameCount - layer.startFrame][i]
2022-01-02 22:40:05 +00:00
mask = layer.masks[frameCount - layer.startFrame][i]
if x is None:
break
factor = videoReader.w / self.resizeWidth
2022-01-09 19:25:44 +00:00
x, y, w, h = (int(x * factor), int(y * factor), int(w * factor), int(h * factor))
2022-01-02 22:40:05 +00:00
2022-01-09 19:25:44 +00:00
mask = imutils.resize(mask, width=w, height=h + 1)
2022-01-02 22:40:05 +00:00
mask = np.resize(mask, (h, w))
mask = cv2.erode(mask, None, iterations=10)
mask *= 255
frame2 = frames[frameCount - layer.startFrame + layer.exportOffset]
2022-01-09 19:25:44 +00:00
xx = np.copy(
cv2.bitwise_and(
frame2[y : y + h, x : x + w],
frame2[y : y + h, x : x + w],
mask=cv2.bitwise_not(mask),
)
)
frame2[y : y + h, x : x + w] = cv2.addWeighted(
xx,
1,
np.copy(cv2.bitwise_and(frame[y : y + h, x : x + w], frame[y : y + h, x : x + w], mask=mask)),
1,
0,
)
frames[frameCount - layer.startFrame + layer.exportOffset] = np.copy(frame2)
2022-01-09 19:25:44 +00:00
# cv2.imshow("changes x", frame2)
# cv2.waitKey(10) & 0XFF
time = datetime.fromtimestamp(int(frameCount / self.fps) + videoReader.getStartTime())
cv2.putText(
frames[frameCount - layer.startFrame + layer.exportOffset],
f"{time.hour}:{time.minute}:{time.second}",
(int(x + w / 2), int(y + h / 2)),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(255, 255, 255),
2,
)
2022-01-02 22:40:05 +00:00
except:
continue
videoReader.thread.join()
2020-11-21 18:13:17 +00:00
videoReader.vc.release()
2020-10-11 15:09:49 +00:00
self.fps = videoReader.getFPS()
fps = self.fps
2020-10-11 15:09:49 +00:00
writer = imageio.get_writer(self.outputPath, fps=fps)
for frame in frames:
writer.append_data(frame)
writer.close()
2020-09-30 17:22:10 +00:00
def exportRawData(self, layers, contours, masks):
2020-11-08 15:28:47 +00:00
with open(self.config["importPath"], "wb+") as file:
2020-11-27 00:06:25 +00:00
pickle.dump((layers, contours, masks), file)
2020-12-26 13:58:58 +00:00
2020-09-30 17:22:10 +00:00
def getMaxLengthOfLayers(self, layers):
maxLength = 0
for layer in layers:
if layer.getLength() > maxLength:
maxLength = layer.getLength()
return maxLength
def makeListOfFrames(self, layers):
2022-01-09 19:25:44 +00:00
"""Returns set of all Frames which are relavant to the Layers"""
frameNumbers = set()
for layer in layers:
2022-01-09 19:25:44 +00:00
frameNumbers.update(list(range(layer.startFrame, layer.startFrame + len(layer))))
2020-10-19 19:35:15 +00:00
return sorted(list(frameNumbers))