From c1bd5bb5d035fa2c8f5eeae73b9c31eabf1c7f86 Mon Sep 17 00:00:00 2001 From: Askill Date: Mon, 5 Oct 2020 09:43:27 +0200 Subject: [PATCH] . --- .gitignore | 2 + Analyzer.py | 2 +- ContourExctractor.py | 111 +++++++++++-------- LayerFactory.py | 3 +- __pycache__/Analyzer.cpython-37.pyc | Bin 0 -> 430 bytes __pycache__/ContourExctractor.cpython-37.pyc | Bin 3201 -> 3956 bytes __pycache__/LayerFactory.cpython-37.pyc | Bin 2365 -> 2372 bytes main.py | 8 +- short.mp4 | Bin 39146 -> 0 bytes 9 files changed, 74 insertions(+), 52 deletions(-) create mode 100644 __pycache__/Analyzer.cpython-37.pyc delete mode 100644 short.mp4 diff --git a/.gitignore b/.gitignore index 5c18a8d..7dab839 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ generate test footage/images/ generate test footage/3.MP4 + +short.mp4 diff --git a/Analyzer.py b/Analyzer.py index 1e5d111..0d36f40 100644 --- a/Analyzer.py +++ b/Analyzer.py @@ -1,3 +1,3 @@ class Analyzer: - def __init__(self): + def __init__(self, footage): print("Analyzer constructed") \ No newline at end of file diff --git a/ContourExctractor.py b/ContourExctractor.py index f143ef2..0b20bfb 100644 --- a/ContourExctractor.py +++ b/ContourExctractor.py @@ -10,6 +10,10 @@ import traceback import _thread import imageio import numpy as np +from threading import Thread +from multiprocessing import Queue, Process, Pool +from multiprocessing.pool import ThreadPool +import concurrent.futures class ContourExtractor: @@ -28,9 +32,7 @@ class ContourExtractor: print("ContourExtractor initiated") def extractContours(self, videoPath, resizeWidth): - min_area = self.min_area - max_area = self.max_area - threashold = self.threashold + # initialize the first frame in the video stream vs = cv2.VideoCapture(videoPath) @@ -40,58 +42,73 @@ class ContourExtractor: self.yDim = image.shape[0] firstFrame = None # loop over the frames of the video - frameCount = 0 + frameCount = -1 + extractedContours = dict() + + results = [] extractedContours = dict() - while res: - res, frame = vs.read() - # resize the frame, convert it to grayscale, and blur it - if frame is None: - print("ContourExtractor: frame was None") - break - frame = imutils.resize(frame, width=resizeWidth) - - gray = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB) - gray = np.asarray(gray[:,:,1]/2 + gray[:,:,2]/2).astype(np.uint8) - - #gray = cv2.GaussianBlur(gray, (5, 5), 0) - - # if the first frame is None, initialize it - if firstFrame is None: - firstFrame = gray - continue - - frameDelta = cv2.absdiff(gray, firstFrame) - - thresh = cv2.threshold(frameDelta, threashold, 255, cv2.THRESH_BINARY)[1] - # dilate the thresholded image to fill in holes, then find contours - thresh = cv2.dilate(thresh, None, iterations=3) - cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - cnts = imutils.grab_contours(cnts) - - contours = [] - for c in cnts: - ca = cv2.contourArea(c) - if ca < min_area or ca > max_area: - continue - (x, y, w, h) = cv2.boundingRect(c) - #print((x, y, w, h)) - contours.append((x, y, w, h)) + imageBuffer = [] + + with concurrent.futures.ProcessPoolExecutor() as executor: + while res: + frameCount += 1 + if frameCount % (60*30) == 0: + print("Minutes processed: ", frameCount/(60*30)) - #cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) - if len(contours) != 0: - extractedContours[frameCount] = contours - if frameCount % (60*30) == 0: - print("Minutes processed: ", frameCount/(60*30)) - frameCount += 1 + res, frame = vs.read() + # resize the frame, convert it to grayscale, and blur it + if frame is None: + print("ContourExtractor: frame was None") + break - #cv2.imshow( "annotated", thresh ) - #cv2.waitKey(10) & 0XFF + frame = imutils.resize(frame, width=resizeWidth) + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB) + + # if the first frame is None, initialize it + if firstFrame is None: + gray = np.asarray(gray[:,:,1]/2 + gray[:,:,2]/2).astype(np.uint8) + gray = cv2.GaussianBlur(gray, (5, 5), 0) + firstFrame = gray + continue + + results.append(executor.submit(self.getContours, frameCount, gray, firstFrame)) + + #contours = self.getContours(frameCount, gray, firstFrame) + + for f in concurrent.futures.as_completed(results): + x=f.result() + if x is not None: + extractedContours = {**extractedContours, **x} + self.extractedContours = extractedContours return extractedContours - + def getContours(self, frameCount, gray, firstFrame): + gray = np.asarray(gray[:,:,1]/2 + gray[:,:,2]/2).astype(np.uint8) + gray = cv2.GaussianBlur(gray, (5, 5), 0) + frameDelta = cv2.absdiff(gray, firstFrame) + thresh = cv2.threshold(frameDelta, self.threashold, 255, cv2.THRESH_BINARY)[1] + # dilate the thresholded image to fill in holes, then find contours + thresh = cv2.dilate(thresh, None, iterations=3) + cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + cnts = imutils.grab_contours(cnts) + + contours = [] + for c in cnts: + ca = cv2.contourArea(c) + if ca < self.min_area or ca > self.max_area: + continue + (x, y, w, h) = cv2.boundingRect(c) + #print((x, y, w, h)) + contours.append((x, y, w, h)) + + if len(contours) != 0: + return {frameCount: contours} + else: + return None + def displayContours(self): values = self.extractedContours.values() for xx in values: diff --git a/LayerFactory.py b/LayerFactory.py index 77a1a55..3e7c2c8 100644 --- a/LayerFactory.py +++ b/LayerFactory.py @@ -35,7 +35,8 @@ class LayerFactory: layers.append(Layer(frameNumber, contour)) # inserts all the fucking contours as layers? - for frameNumber, contours in data.items(): + for frameNumber in sorted(data): + contours = data[frameNumber] for (x,y,w,h) in contours: foundLayer = False i = 0 diff --git a/__pycache__/Analyzer.cpython-37.pyc b/__pycache__/Analyzer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..405b5718706641c5ffe7b672daabc6d742e3472a GIT binary patch literal 430 zcmYjLu};G<5Vf5YqNWtU^xmC)_wL@~dc9;A7e5`mV*aMb903+Pgu6m|W|B#MKzxdnN%6wspuqoQ2&{Gp zw?R@Y<&vdBaw!fh4P=1x;SfFOyy|*o3!0{&On5@L6_Te5oZ~fAh@{`ll5JtM^R_L# zk})3^jV-m0#Sl7G?bGwUF+P7&U(ANMyG&-Ai-Zb41 z0hGG*0A$0BzIcCmoS3@_*$2>htpJ84Ky74OQN05AX!C07*fZQRS~#Hv{c$A1cp~EC XJBg=!GE43)35MuyI&n{`Uj+LH)}CKN literal 0 HcmV?d00001 diff --git a/__pycache__/ContourExctractor.cpython-37.pyc b/__pycache__/ContourExctractor.cpython-37.pyc index 44b2a71fcac9d6efa922fdeef128185469962986..49b7ae754b9b5cb0999bacc7c12e4699bdcdf9c3 100644 GIT binary patch literal 3956 zcmai1OK;rP6~6b9LvlC|JtIqwo2ZWz9kfszw@m^gO)bgt19fCYHX`@J#ekm6ktoee zmmGN{kXh78S52Em(Nz~S%XZ;ae@T~Ibkmjg1qyVNe&^0ekrf9e!E?`jzrOFB!?jAq zXLz>$b6gK+8T%Jy&K?WOO?>g+AQV%)#oAnQPP%9bDNJff%cQonOvJM|)6J&B_ZO^}~LcyIZ>32;(@n zx4PXHTKMA@lxxr+XODn#6JPu>M93spOp4HY&ai2Y4GV16!bWZB;VY_waz16)sH;4r zB~?^D(y}V4GSZ5ws4CK`no`q9r_>CVJ)2LjcRNY9uQvvX4jM^UNB`!GMUP)+?6iW3 zHFB&$f*wlgTgMkW5GmVd7>CnVXTtFqp_+^tqtK4SR`ah+m(lpYZ#Ql{>FMr%*hu0h zNz@LP8{KwK<20gf=gIj>8k420^p5lS-7xvuxYuZUIv>VQ-a7Ag*6US0UfKcmG&`V0 zB>>rT12F7EY@S@bJl=BDiIONtLWS)VdOGSPHLgqOYBn_%bX2)luT$H4{Y~V~*0*$d zyp^+74FWqo)A)+`%$h#I`6g`0Q$FIEm0CkFVoyY7XN9z|Zz;ZnGq2l57e)v4Gaw;z z6X!Y0yj_+R&ow`B_q}0p#J=EvT+B*?f2Q^qT)&gLioeS;7pc7fVjT$m+r(D|%D>K@ z3(hXgTTVfi15Xdp!l9GeVo7NqrKwQv=OQa(wUrcdzd90GB?Sc!Jj`+}nHo-~6%dVm zMzkf#o7NIj-s|jAxp!86g^l=dCYjow#qKK@c@8a$N{lRwT*;h6nHGohX=(TxkhhS! zDdrp5BdqFB?y$j6%zm$=#Sy>7ezTla)9P?>#ImV$3act&Rku?wo%*xLu)@RJJ8TE* z`iO0_#|-7HzLa`Efxmf5AUDuI{Sr^)xs096eHeB6Nf<8!!o=WE-B>uY4o)YJBf6ged-d+xrt378?rG78-4ItPhpDOjoSSrYQ?#OcF{>F zy~a_p-feZYtgJt{|6semc4zzg{nfQxbb7fP#DUhqaqa|ha*X*4eW3llynH9DA(rJJt`n(Spsg~q_FIW2gI}9Aq>;rVvXEOrvX_^} zi`t>%k>V)MEfnO1s2%Kvx!;U*oZP0vgigtNx8E6$mAhz&fn!-Rjo13kW~ikXPBxzx zOo!awrQPsm&IgytIyJE>XDj~>mKd)=FxwYpPOmL&?u z3?jRrub-A+LMqKMd0*_X1ayARm3?4=rqd};-H1QL35>s*x2b1vP zB?+>pH7@-q33ZUbrNp%>dKrcK+a&0Q^>;}ukoX>ibc3g{ikeMXOyH;Ey>3h8KBudKmSGRu+j~lh%31qn$bHK%dvo=^oLj%U zdT+D7y0x|a;Bo!oy$`qUZ|FB@&I&;J6eKZz7YLqctC%$R+EJ$-jJ053G+BNM+^eXw zyA8jo-@*{N)e1Yc>evbWh&J;txy8h1-DZgI-p^ zt18|^taEsEhaFA>o&K;gLZ0vl2QkK?@e)77E&#|SBzZxR*^HPVAnG|3oy;`$g3d0y zM)xSxt>8FRr*sJVr_`-#EMx8*1+9J<8?5GqlTdeKjR1`4t0W9$2|1eL3Nw*Guymp} zQ2I=|&w?oVRd_6CR2V0^d%W6e?Es+NXK~FRgMK)swbBl_fQ=ZeV9Rj&!=JauEGZX0Jd@ARhIA40Ov@c0O}kGLu9@} z0_=+z{NAA9)65!tl3GB+QHFb)puu1v^N=Sr6u%J-Cj3be*eC~R@PP$Cb?_E1pn=dq z`3q=B#n4ZE6I8r`+n?Wo<;AVL-*D^tCRTs(&TA!et(p#fY=0=S`#(2IyhcY8SDM>$ zj0=nPE$X{Lg7|vr-t=uMd)3WV!$GgB&mD7ycIOv2rteo*H_K1n{2F~~a=m`o4_f0IO`-XC_wSPS9*LimFi&7K0iEs*`Nz~1ay9mfAYw|kz zR2$JqGzko;lpMS^p&tDv$@xq5D?Nm2nmoUpg;}0NbSsm9PJfGf(|%rc9J%-Y`0zg< T`x7ril)=JRy=B;F)QSHAN7T^= delta 1656 zcmaJ>&2Jk;6rY*>@Osy~YbTE5#7Qtxqv94S5L3T;yrA(c?lh)Pz$+GaM%CjQFo z+O?xuSr9lzO4)zFmMZZVaNvSC^}q=ZaM%+?0E(q~v)1(kZ>}Y=boA)vA&CHwm zeeRPf>xOCS2)-v@^=seTkE|l@KDxMd?HxoVDu0Hkd_bxuC3jIpc`EEGI5s}?sN1?5 zFxP3UZV2JYM}S;|?yp9R_6DxjIxv=spQkp~kfxmEtL|ucZ=B z60T7crYQ;aAbo&B;|TZmdFlwW@BZbR;Tei{HP#LE0hJCgMt4wP?0}dPDj$+C10hWg zxMPh-Xa@E$%T0`nC1?QjgNXSfJF&d0g5i;l3r3{2jYVJGMj-dhHXSz$4_FNgVXA}oZHJU5)< zc|O4ld~#DB!LA6ydnkB;=MFF>yAn7*<~eR~eF<@$rV9w91f<^vI@N`wgboN6I(!v{ z`rg_-1lFil<_6S&Fsv{aEoD&X!x%H$CPDx0urqT>MsG;vktMRuVx~-h#ZMkJFb2 zG492Gx|-RdD|9x>v&CS*Qs}0pUo!5`z~wwYzjCNH=2p0SxLZ*05K!WN4JbitI3=2 zDvV>&>&2wIz$!v{Nx)?RFAE*+vUxE$^LW_Q^V@Z&f3i2V=o{nj!MO`ySHS-?ec%-% zNt}t;N!DyZu>a4weC+rs{yoSs2f|3?gc(c=J_t|Xp*eX{NkMqLC+ESxMJ9T$i+;6`a JePB;x@((~AZ^!@u diff --git a/__pycache__/LayerFactory.cpython-37.pyc b/__pycache__/LayerFactory.cpython-37.pyc index 4c526cfe4824eb171a6a319405d91a41bfee52a2..84f01634ea423aff1b80452774d50c54f8d9ee83 100644 GIT binary patch delta 186 zcmdlhbVP{PiIm*c$h)42v0?IFrX*3Z61Ez~W=0o=35>BEwJbG^H7t@0 zlMR?XrB9SFrLZ+KGBOk{s9~w$&Ek?^NMX-roWNM*HhBtjFr(Y#7tG3v3&I&{xQlCQ zm=~~=umaVw*KpKu)^Me8+Wp!!ntjtvJ7^BsFF7QI_3|c9R=frJ02oIVR6# leZuHCxryxvqwi#Q_63Z=lV7lBG6qf#;#ke7JNX}nJpg9FH9`OY delta 201 zcmX>iv{#7NiIcStl>&yX=Yjo(pxdvfMqfpYi3DmZt>((EW2fGKrUcpW8z}u074cfHYOGj t3&l4CWa&SX|jdjNYPGKK&E diff --git a/main.py b/main.py index ffeeab3..2c2c6dd 100644 --- a/main.py +++ b/main.py @@ -3,17 +3,19 @@ import time from ContourExctractor import ContourExtractor from Exporter import Exporter from LayerFactory import LayerFactory +from Analyzer import Analyzer import cv2 #TODO # finden von relevanten Stellen anhand von zu findenen metriken für vergleichsbilder def demo(): print("startup") - resizeWidth = 512 + resizeWidth = 1024 maxLayerLength = 1*60*30 start = time.time() - footagePath = os.path.join(os.path.dirname(__file__), "./generate test footage/out.mp4") + footagePath = os.path.join(os.path.dirname(__file__), "./generate test footage/3.MP4") + analyzer = Analyzer(footagePath) contours = ContourExtractor().extractContours(footagePath, resizeWidth) print("Time consumed in working: ", time.time() - start) layerFactory = LayerFactory(contours) @@ -21,7 +23,7 @@ def demo(): layerFactory.sortLayers() layerFactory.fillLayers(footagePath) underlay = cv2.VideoCapture(footagePath).read()[1] - Exporter().exportLayers(underlay, layerFactory.layers, os.path.join(os.path.dirname(__file__), "./short.mp4"), resizeWidth) + Exporter().exportOverlayed(underlay, layerFactory.layers, os.path.join(os.path.dirname(__file__), "./short.mp4"), resizeWidth) print("Total time: ", time.time() - start) def init(): print("not needed yet") diff --git a/short.mp4 b/short.mp4 deleted file mode 100644 index 0fc15fd6fb84862054c7a2a345f13f6a889b8a7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39146 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