fixed layer.add()

This commit is contained in:
Askill 2020-11-08 16:28:47 +01:00
parent 01b5d7f9a9
commit 3c3c8da9cd
14 changed files with 78 additions and 81 deletions

View File

@ -3,25 +3,27 @@ class Config:
c = {
"min_area" : 100,
"max_area" : 40000,
"threashold" : 5,
"threashold" : 8,
"resizeWidth" : 512,
"inputPath" : None,
"outputPath": None,
"maxLayerLength": 900,
"minLayerLength": 20,
"tolerance": 20,
"tolerance": 10,
"maxLength": None,
"ttolerance": 60,
"videoBufferLength": 500,
"noiseThreashold": 0.3,
"noiseThreashold": 0.25,
"noiseSensitivity": 3/4,
"LayersPerContour": 5,
"averageFrames": 10
"LayersPerContour": 2,
"avgNum":10
}
def __init__(self):
'''This is basically just a wrapper for a json / python dict'''
print("Current Config:", self.c)
print("Current Config:")
for key, value in self.c.items():
print(f"{key}:\t\t{value}")
def __getitem__(self, key):
if key not in self.c:

View File

@ -109,7 +109,9 @@ class ContourExtractor:
def computeMovingAverage(self, frames):
avg = []
averageFrames = self.config["averageFrames"]
averageFrames = self.config["avgNum"]
nth = int(averageFrames/3) # only take /x x frames to average
if frames[0][0] < averageFrames:
frame = frames[0][1]
frame = self.prepareFrame(frame)
@ -123,7 +125,7 @@ class ContourExtractor:
if self.lastFrames is not None:
frames = self.lastFrames + frames
tmp = [[j, frames, averageFrames]for j in range(averageFrames, len(frames))]
tmp = [[j, frames, averageFrames] for j in range(averageFrames, len(frames))]
with ThreadPool(16) as pool:
pool.map(self.averageDaFrames, tmp)
@ -136,6 +138,6 @@ class ContourExtractor:
frame = self.prepareFrame(frame)
avg = frame/averageFrames
for jj in reversed(range(averageFrames-1)):
for jj in range(0,averageFrames-1):
avg += self.prepareFrame(frames[j-jj][1])/averageFrames
self.averages[frameNumber] = np.array(np.round(avg), dtype=np.uint8)

View File

@ -16,17 +16,13 @@ class Exporter:
self.config = config
print("Exporter initiated")
def export(self, layers, raw = True, layered = False, overlayed = True):
def export(self, layers, contours, raw = True, overlayed = True):
if raw:
self.exportRawData(layers)
if layered and overlayed:
print("Layered and Individual are mutually exclusive, individual was choosen automatically")
overlayed = False
if layered and not overlayed:
self.exportLayers(layers)
if overlayed and not layered:
self.exportRawData(layers, contours)
if overlayed:
self.exportOverlayed(layers)
else:
self.exportLayers(layers)
def exportLayers(self, layers):
@ -37,7 +33,6 @@ class Exporter:
maxLength = self.getMaxLengthOfLayers(layers)
underlay = cv2.VideoCapture(self.footagePath).read()[1]
underlay = cv2.cvtColor(underlay, cv2.COLOR_BGR2RGB)
frames = [underlay]*maxLength
exportFrame = 0
self.fps = videoReader.getFPS()
@ -52,7 +47,7 @@ class Exporter:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame2 = np.copy(underlay)
for layer in layers:
for xi, layer in enumerate(layers):
if layer.startFrame <= frameCount and layer.startFrame + len(layer.bounds) > frameCount:
for (x, y, w, h) in layer.bounds[frameCount - layer.startFrame]:
if x is None:
@ -64,7 +59,7 @@ class Exporter:
h = int(h * factor)
frame2[y:y+h, x:x+w] = np.copy(frame[y:y+h, x:x+w])
cv2.putText(frame2, str(int(frameCount/self.fps)), (int(x+w/2), int(y+h/2)), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,255,255), 2)
cv2.putText(frame2, str(xi) + " " + str(int(frameCount/self.fps)), (int(x+w/2), int(y+h/2)), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,255,255), 2)
writer.append_data(frame2)
@ -119,9 +114,10 @@ class Exporter:
writer.close()
def exportRawData(self, layers):
with open(self.outputPath.split(".")[-2] + ".txt", "wb+") as file:
pickle.dump(layers, file)
def exportRawData(self, layers, contours):
with open(self.config["importPath"], "wb+") as file:
pickle.dump((layers, contours), file)
def getMaxLengthOfLayers(self, layers):

View File

@ -5,6 +5,7 @@ class Importer:
self.path = config["importPath"]
def importRawData(self):
print("Loading previous results")
with open(self.path, "rb") as file:
layers = pickle.load(file)
return layers
layers, contours = pickle.load(file)
return (layers, contours)

View File

@ -37,15 +37,13 @@ class Layer:
def add(self, frameNumber, bound):
'''Adds a bound'''
if not self.startFrame + len(self.bounds) < frameNumber:
if len(self.bounds[self.startFrame - frameNumber]) >= 1:
self.bounds[self.startFrame - frameNumber].append(bound)
if self.startFrame + len(self.bounds) - 1 > frameNumber:
if len(self.bounds[frameNumber - self.startFrame]) >= 1:
self.bounds[frameNumber - self.startFrame].append(bound)
else:
self.lastFrame = frameNumber
self.bounds.append([bound])
self.getLength()
def getLength(self):
return len(self)
@ -53,25 +51,6 @@ class Layer:
self.length = len(self.bounds)
return self.length
def fill(self, inputPath, resizeWidth):
'''deprecated
Fills the data[] array by iterateing over the bounds'''
cap = cv2.VideoCapture(inputPath)
self.data = [None]*len(self.bounds)
i = 0
cap.set(1, self.startFrame)
while i < len(self.bounds):
ret, frame = cap.read()
if ret:
frame = imutils.resize(frame, width=resizeWidth)
(x, y, w, h) = self.bounds[i]
self.data[i] = frame[y:y+h, x:x+w]
i+=1
cap.release()
def clusterDelete(self):
'''Uses a cluster analysis to remove contours which are not the result of movement'''
org = self.bounds
@ -146,13 +125,14 @@ class Layer:
newContours = [[]]
for i, dis in enumerate(dists):
# copy contours which are spread out, delete rest by not copying them
if dis > noiseThreashold:
for j in classed[i]:
x, y = mapping[j]
while x >= len(newContours):
newContours.append([])
while y > len(newContours[x]):
newContours[x].append((None, None, None, None))
if dis > noiseThreashold:
newContours[x].append(org[x][y])
self.bounds = newContours

View File

@ -45,9 +45,9 @@ class LayerFactory:
print(f"{int(round(frameNumber/max(data.keys()), 2)*100)}% done with Layer extraction")
tmp = [[frameNumber, contour] for contour in contours]
pool.map(self.getLayers, tmp)
#for x in tmp:
#self.getLayers(x)
#pool.map(self.getLayers, tmp)
for x in tmp:
self.getLayers(x)
return self.layers
@ -59,20 +59,28 @@ class LayerFactory:
foundLayer = 0
for i in range(0, len(self.layers)):
if foundLayer >= self.config["LayersPerContour"]:
break
if i in self.oldLayerIDs:
continue
if frameNumber - self.layers[i].lastFrame > self.ttolerance:
self.oldLayerIDs.append(i)
continue
for bounds in self.layers[i].bounds[-1]:
if bounds is None or foundLayer >= self.config["LayersPerContour"]:
lastXframes = 3
if len(self.layers[i].bounds) < lastXframes:
lastXframes = len(self.layers[i].bounds)
lastBounds = [bound for bounds in self.layers[i].bounds[-lastXframes:] for bound in bounds]
for bounds in lastBounds:
if bounds is None:
break
(x2,y2,w2,h2) = bounds
if self.contoursOverlay((x-tol,y+h+tol), (x+w+tol,y-tol), (x2,y2+h2), (x2+w2,y2)):
self.layers[i].add(frameNumber, (x,y,w,h))
foundLayer += 1
#break
break
if foundLayer == 0:
self.layers.append(Layer(frameNumber, (x,y,w,h), self.config))

View File

@ -28,7 +28,7 @@ class LayerManager:
print("'Cleaning' Layers")
self.freeMin()
self.sortLayers()
self.cleanLayers2()
#self.cleanLayers2()
self.freeMax()
def removeStaticLayers(self):
@ -107,5 +107,8 @@ class LayerManager:
self.layers.sort(key = lambda c:c.startFrame)
def cleanLayers2(self):
#with ThreadPool(16) as pool:
# pool.map(self.getContours, tmpData)
for layer in self.layers:
layer.clusterDelete()

View File

@ -2,7 +2,7 @@
import cv2
import imageio
import time
writer = imageio.get_writer("./x23.mp4", fps=20)
writer = imageio.get_writer("./x23.mp4", fps=15)
url = "http://50.227.41.1/mjpg/video.mjpg"
i = 0
@ -20,15 +20,15 @@ while True :
print("Error in cap.read()") # this is for preventing a breaking error
# break;
time.sleep(1)
continue
break
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
writer.append_data(frame)
i+=1
if i > 20*60*60:
if i > 20*60*60*2:
break
except Exception as e:
cap.release()
cv2.destroyAllWindows()
writer.close()
print("meh")
cap.release()
cv2.destroyAllWindows()
writer.close()

25
main.py
View File

@ -14,22 +14,26 @@ def main():
start = time.time()
config = Config()
config["inputPath"] = os.path.join(os.path.dirname(__file__), "generate test footage/Merica-1.m4v")
#config["importPath"] = os.path.join(os.path.dirname(__file__), "output/short.txt")
config["outputPath"] = os.path.join(os.path.dirname(__file__), "output/shor.mp4")
fileName = "3.mp4"
outputPath = os.path.join(os.path.dirname(__file__), "output")
dirName = os.path.join(os.path.dirname(__file__), "generate test footage")
vr = VideoReader(config)
config["w"], config["h"] = vr.getWH()
config["inputPath"] = os.path.join(dirName, fileName)
config["outputPath"] = os.path.join(outputPath, fileName)
if config["importPath"] is None:
config["importPath"] = os.path.join(outputPath, fileName.split(".")[0] + ".txt")
config["w"], config["h"] = VideoReader(config).getWH()
if not os.path.exists(config["importPath"]):
contours = ContourExtractor(config).extractContours()
print("Time consumed extracting: ", time.time() - start)
layerFactory = LayerFactory(config)
layers = layerFactory.extractLayers(contours)
else:
layers = Importer(config).importRawData()
layers, contours = Importer(config).importRawData()
#layerFactory = LayerFactory(config)
#layers = layerFactory.extractLayers(contours)
layerManager = LayerManager(config, layers)
layerManager.cleanLayers()
@ -37,7 +41,8 @@ def main():
#layerManager.tagLayers()
layers = layerManager.layers
exporter = Exporter(config)
exporter.export(layers, raw=False)
print(f"Exporting {len(contours)} Contours and {len(layers)} Layers")
exporter.export(layers, contours, raw=True, overlayed=False)
print("Total time: ", time.time() - start)

Binary file not shown.

BIN
output/out.txt Normal file

Binary file not shown.

Binary file not shown.

BIN
output/x23.txt Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 313 KiB