docs
This commit is contained in:
parent
c828e2e0d2
commit
529459aa97
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
c = {
|
c = {
|
||||||
"min_area" : 5000,
|
"min_area" : 50,
|
||||||
"max_area" : 40000,
|
"max_area" : 40000,
|
||||||
"threashold" : 7,
|
"threashold" : 7,
|
||||||
"resizeWidth" : 512,
|
"resizeWidth" : 512,
|
||||||
|
|
@ -11,7 +11,7 @@ class Config:
|
||||||
"minLayerLength": 40,
|
"minLayerLength": 40,
|
||||||
"tolerance": 20,
|
"tolerance": 20,
|
||||||
"maxLength": None,
|
"maxLength": None,
|
||||||
"ttolerance": 20,
|
"ttolerance": 60,
|
||||||
"videoBufferLength": 500,
|
"videoBufferLength": 500,
|
||||||
"LayersPerContour": 220,
|
"LayersPerContour": 220,
|
||||||
"avgNum":10
|
"avgNum":10
|
||||||
|
|
|
||||||
|
|
@ -50,19 +50,21 @@ class ContourExtractor:
|
||||||
|
|
||||||
def extractContours(self):
|
def extractContours(self):
|
||||||
videoReader = VideoReader(self.config)
|
videoReader = VideoReader(self.config)
|
||||||
|
self.fps = videoReader.getFPS()
|
||||||
|
self.length = videoReader.getLength()
|
||||||
videoReader.fillBuffer()
|
videoReader.fillBuffer()
|
||||||
|
|
||||||
threads = self.config["videoBufferLength"]
|
threads = self.config["videoBufferLength"]
|
||||||
self.start = time.time()
|
self.start = time.time()
|
||||||
# start a bunch of frames and let them read from the video reader buffer until the video reader reaches EOF
|
# start a bunch of frames and let them read from the video reader buffer until the video reader reaches EOF
|
||||||
with ThreadPool(16) as pool:
|
with ThreadPool(2) as pool:
|
||||||
while not videoReader.videoEnded():
|
while not videoReader.videoEnded():
|
||||||
if videoReader.buffer.qsize() == 0:
|
if videoReader.buffer.qsize() == 0:
|
||||||
time.sleep(.5)
|
time.sleep(.5)
|
||||||
|
|
||||||
tmpData = [videoReader.pop() for i in range(0, videoReader.buffer.qsize())]
|
tmpData = [videoReader.pop() for i in range(0, videoReader.buffer.qsize())]
|
||||||
self.computeMovingAverage(tmpData)
|
pool.map(self.computeMovingAverage, (tmpData,))
|
||||||
pool.map_async(self.getContours, tmpData)
|
pool.map(self.async2, (tmpData,))
|
||||||
#for data in tmpData:
|
#for data in tmpData:
|
||||||
# self.getContours(data)
|
# self.getContours(data)
|
||||||
frameCount = tmpData[-1][0]
|
frameCount = tmpData[-1][0]
|
||||||
|
|
@ -70,6 +72,10 @@ class ContourExtractor:
|
||||||
videoReader.thread.join()
|
videoReader.thread.join()
|
||||||
return self.extractedContours, self.extractedMasks
|
return self.extractedContours, self.extractedMasks
|
||||||
|
|
||||||
|
def async2(self, tmpData):
|
||||||
|
with ThreadPool(16) as pool2:
|
||||||
|
pool2.map(self.getContours, tmpData)
|
||||||
|
|
||||||
def getContours(self, data):
|
def getContours(self, data):
|
||||||
frameCount, frame = data
|
frameCount, frame = data
|
||||||
# wait for the reference frame, which is calculated by averaging some revious frames
|
# wait for the reference frame, which is calculated by averaging some revious frames
|
||||||
|
|
@ -77,8 +83,8 @@ class ContourExtractor:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
firstFrame = self.averages.pop(frameCount, None)
|
firstFrame = self.averages.pop(frameCount, None)
|
||||||
|
|
||||||
if frameCount % (60*30) == 1:
|
if frameCount % (10*self.fps) == 1:
|
||||||
print(f" \r {frameCount/(60*30)} Minutes processed in {round((time.time() - self.start)/(frameCount/(60*30)), 2)} each", end='\r')
|
print(f" \r {round((frameCount/self.fps)/self.length, 4)*100} % processed in {round(time.time() - self.start, 2)}s", end='\r')
|
||||||
|
|
||||||
gray = self.prepareFrame(frame)
|
gray = self.prepareFrame(frame)
|
||||||
frameDelta = cv2.absdiff(gray, firstFrame)
|
frameDelta = cv2.absdiff(gray, firstFrame)
|
||||||
|
|
@ -88,7 +94,6 @@ class ContourExtractor:
|
||||||
#cv2.imshow("changes x", thresh)
|
#cv2.imshow("changes x", thresh)
|
||||||
#cv2.waitKey(10) & 0XFF
|
#cv2.waitKey(10) & 0XFF
|
||||||
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||||
self.diff.append(np.count_nonzero(thresh))
|
|
||||||
cnts = imutils.grab_contours(cnts)
|
cnts = imutils.grab_contours(cnts)
|
||||||
|
|
||||||
contours = []
|
contours = []
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ class VideoReader:
|
||||||
self.stopped = False
|
self.stopped = False
|
||||||
self.getWH()
|
self.getWH()
|
||||||
self.calcFPS()
|
self.calcFPS()
|
||||||
|
self.calcLength()
|
||||||
self.calcStartTime()
|
self.calcStartTime()
|
||||||
if setOfFrames is not None:
|
if setOfFrames is not None:
|
||||||
self.listOfFrames = sorted(setOfFrames)
|
self.listOfFrames = sorted(setOfFrames)
|
||||||
|
|
@ -103,12 +104,22 @@ class VideoReader:
|
||||||
self.fps = self.vc.get(cv2.CAP_PROP_FPS)
|
self.fps = self.vc.get(cv2.CAP_PROP_FPS)
|
||||||
|
|
||||||
def getFPS(self):
|
def getFPS(self):
|
||||||
|
if self.fps is None:
|
||||||
|
self.calcFPS()
|
||||||
return self.fps
|
return self.fps
|
||||||
|
|
||||||
|
def calcLength(self):
|
||||||
|
fc = int(self.vc.get(cv2.CAP_PROP_FRAME_COUNT))
|
||||||
|
self.length = fc / self.getFPS()
|
||||||
|
|
||||||
|
def getLength(self):
|
||||||
|
if self.length is None:
|
||||||
|
self.calcLength()
|
||||||
|
return self.length
|
||||||
|
|
||||||
def calcStartTime(self):
|
def calcStartTime(self):
|
||||||
starttime = os.stat(self.videoPath).st_mtime
|
starttime = os.stat(self.videoPath).st_mtime
|
||||||
fc = int(self.vc.get(cv2.CAP_PROP_FRAME_COUNT))
|
length = self.getLength()
|
||||||
length = fc / self.getFPS()
|
|
||||||
starttime = starttime - length
|
starttime = starttime - length
|
||||||
self.starttime = starttime
|
self.starttime = starttime
|
||||||
|
|
||||||
|
|
|
||||||
20
README.md
20
README.md
|
|
@ -1,12 +1,18 @@
|
||||||
|
|
||||||
# wip
|
# Video Synopsis and Classification
|
||||||
|
|
||||||
|
## Example:
|
||||||
|

|
||||||
|
What you see above is a 15 second exerpt of a 2 minute overlayed synopsis of a 2.5h video from an on campus web cam.
|
||||||
|
The synopsis took 40 minutes from start to finish on a 8 core machine and used a maximum of 6Gb of RAM.
|
||||||
|
|
||||||
|
## Benchmark
|
||||||
|
Below you can find the benchmark results for a 10 minutes clip, with the stacked time per componenent on the x-axis.
|
||||||
|
The tests were done on a machine with a Ryzen 3700X with 8 cores 16 threads and 32 Gb of RAM.
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### notes:
|
#### notes:
|
||||||
|
|
||||||
Time consumed reading video: 369.0188868045807s 3.06GB 26min 1080p downscaled 500p 30fps
|
|
||||||
Time consumed reading video: 240.s 3.06GB 26min 1080p downscaled 500p 30fps when multithreaded
|
|
||||||
contour extraction: 10.5 Sec. when only 2 Threads
|
|
||||||
8 secs when also mapping getContours()
|
|
||||||
|
|
||||||
|
|
||||||
install tensorflow==1.15.0 and tensorflow-gpu==1.15.0, cuda 10.2 and 10.0, copy missing files from 10.0 to 10.2, restart computer, set maximum vram
|
install tensorflow==1.15.0 and tensorflow-gpu==1.15.0, cuda 10.2 and 10.0, copy missing files from 10.0 to 10.2, restart computer, set maximum vram
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 MiB |
22
docs/plot.py
22
docs/plot.py
|
|
@ -1,22 +0,0 @@
|
||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import pandas as pd
|
|
||||||
[
|
|
||||||
{"threads": "32, 16", "Contour Extractor": 106.0405707359314, "Layer Factory": 0.5175004005432129, "Layer Manager": 1.4864997863769531, "Exporter": 34.591999769210815},
|
|
||||||
{"threads": "1, 1", "Contour Extractor": 463.66750025749207, "Layer Factory": 0.5290005207061768, "Layer Manager": 1.551999807357788, "Exporter": 34.5339994430542},
|
|
||||||
{"threads": "1, 4", "Contour Extractor": 193.51898574829102, "Layer Factory": 0.5249984264373779, "Layer Manager": 1.5125021934509277, "Exporter": 35.06749963760376},
|
|
||||||
{"threads": "4, 4", "Contour Extractor": 186.46951842308044, "Layer Factory": 0.5295009613037109, "Layer Manager": 1.545145034790039, "Exporter": 34.260000705718994},
|
|
||||||
{"threads": "4, 8", "Contour Extractor": 126.90402793884277, "Layer Factory": 0.5275006294250488, "Layer Manager": 1.536078929901123, "Exporter": 34.61099886894226},
|
|
||||||
{"threads": "16, 16", "Contour Extractor": 109.17592716217041, "Layer Factory": 0.4179983139038086, "Layer Manager": 1.5620002746582031, "Exporter": 33.80550146102905},
|
|
||||||
|
|
||||||
]
|
|
||||||
x = {
|
|
||||||
"threads":["1, 1","1, 4","4, 4","4, 8","16, 16", "32, 16"],
|
|
||||||
"Contour Extraction":[ 463.66750025749207, 193.51898574829102,186.46951842308044,126.90402793884277,109.17592716217041,106.0405707359314],
|
|
||||||
}
|
|
||||||
|
|
||||||
df = pd.DataFrame.from_dict(x)
|
|
||||||
ax = df.plot.bar(x="threads", title="Benötigte Zeit für Konturenextraktion mit unterschiedlicher Anzahlen von Threads", figsize=(10,4))
|
|
||||||
ax.set_xlabel("Threads für Durchschnittsbildung | Threads für Differenzberechnung")
|
|
||||||
ax.set_ylabel("Zeit in Sekunden")
|
|
||||||
plt.show()
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
[
|
|
||||||
{"File Name": "c:/projects/time compression\\output\\X23-1.txt", "threads": "32, 16", "Contour Extractor": 106.0405707359314, "Layer Factory": 0.5175004005432129, "Layer Manager": 1.4864997863769531, "Exporter": 34.591999769210815},
|
|
||||||
{"File Name": "c:/projects/time compression\\output\\X23-1.txt", "threads": "1, 1", "Contour Extractor": 463.66750025749207, "Layer Factory": 0.5290005207061768, "Layer Manager": 1.551999807357788, "Exporter": 34.5339994430542},
|
|
||||||
{"File Name": "c:/projects/time compression\\output\\X23-1.txt", "threads": "1, 4", "Contour Extractor": 193.51898574829102, "Layer Factory": 0.5249984264373779, "Layer Manager": 1.5125021934509277, "Exporter": 35.06749963760376},
|
|
||||||
{"File Name": "c:/projects/time compression\\output\\X23-1.txt", "threads": "4, 4", "Contour Extractor": 186.46951842308044, "Layer Factory": 0.5295009613037109, "Layer Manager": 1.545145034790039, "Exporter": 34.260000705718994},
|
|
||||||
{"File Name": "c:/projects/time compression\\output\\X23-1.txt", "threads": "4, 8", "Contour Extractor": 126.90402793884277, "Layer Factory": 0.5275006294250488, "Layer Manager": 1.536078929901123, "Exporter": 34.61099886894226},
|
|
||||||
{"File Name": "c:/projects/time compression\\output\\X23-1.txt", "threads": "16, 16", "Contour Extractor": 109.17592716217041, "Layer Factory": 0.4179983139038086, "Layer Manager": 1.5620002746582031, "Exporter": 33.80550146102905},
|
|
||||||
|
|
||||||
]
|
|
||||||
19
main.py
19
main.py
|
|
@ -15,7 +15,7 @@ def main():
|
||||||
start = startTotal
|
start = startTotal
|
||||||
config = Config()
|
config = Config()
|
||||||
|
|
||||||
fileName = "3.mp4"
|
fileName = "x23.mp4"
|
||||||
outputPath = os.path.join(os.path.dirname(__file__), "output")
|
outputPath = os.path.join(os.path.dirname(__file__), "output")
|
||||||
dirName = os.path.join(os.path.dirname(__file__), "generate test footage")
|
dirName = os.path.join(os.path.dirname(__file__), "generate test footage")
|
||||||
|
|
||||||
|
|
@ -25,26 +25,20 @@ def main():
|
||||||
config["importPath"] = os.path.join(outputPath, fileName.split(".")[0] + ".txt")
|
config["importPath"] = os.path.join(outputPath, fileName.split(".")[0] + ".txt")
|
||||||
|
|
||||||
config["w"], config["h"] = VideoReader(config).getWH()
|
config["w"], config["h"] = VideoReader(config).getWH()
|
||||||
stats = []
|
|
||||||
if not os.path.exists(config["importPath"]):
|
if not os.path.exists(config["importPath"]):
|
||||||
contours, masks = ContourExtractor(config).extractContours()
|
contours, masks = ContourExtractor(config).extractContours()
|
||||||
stats.append(time.time() - start)
|
|
||||||
start = time.time()
|
|
||||||
|
|
||||||
print("Time consumed extracting contours: ", stats["Contour Extractor"])
|
|
||||||
layerFactory = LayerFactory(config)
|
layerFactory = LayerFactory(config)
|
||||||
layers = layerFactory.extractLayers(contours, masks)
|
layers = layerFactory.extractLayers(contours, masks)
|
||||||
stats.append(time.time() - start)
|
|
||||||
start = time.time()
|
|
||||||
else:
|
else:
|
||||||
layers, contours, masks = Importer(config).importRawData()
|
layers, contours, masks = Importer(config).importRawData()
|
||||||
#layerFactory = LayerFactory(config)
|
layerFactory = LayerFactory(config)
|
||||||
#layers = layerFactory.extractLayers(contours, masks)
|
layers = layerFactory.extractLayers(contours, masks)
|
||||||
|
|
||||||
layerManager = LayerManager(config, layers)
|
layerManager = LayerManager(config, layers)
|
||||||
layerManager.transformLayers()
|
layerManager.transformLayers()
|
||||||
stats.append(time.time() - start)
|
|
||||||
start = time.time()
|
|
||||||
|
|
||||||
#layerManager.tagLayers()
|
#layerManager.tagLayers()
|
||||||
layers = layerManager.layers
|
layers = layerManager.layers
|
||||||
|
|
@ -54,11 +48,8 @@ def main():
|
||||||
exporter = Exporter(config)
|
exporter = Exporter(config)
|
||||||
print(f"Exporting {len(contours)} Contours and {len(layers)} Layers")
|
print(f"Exporting {len(contours)} Contours and {len(layers)} Layers")
|
||||||
exporter.export(layers, contours, masks, raw=True, overlayed=True)
|
exporter.export(layers, contours, masks, raw=True, overlayed=True)
|
||||||
stats.append(time.time() - start)
|
|
||||||
|
|
||||||
print("Total time: ", time.time() - startTotal)
|
print("Total time: ", time.time() - startTotal)
|
||||||
stats.append(time.time() - startTotal)
|
|
||||||
print(stats)
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue