From 40d6339c3c7b6f1c82a65b05d8072d89f49a75ac Mon Sep 17 00:00:00 2001 From: Askill Date: Wed, 23 Sep 2020 22:02:46 +0200 Subject: [PATCH] first video synopsis working kinda jank tho --- ContourExctractor.py | 44 ++++++++++++------- Exporter.py | 13 +++++- __pycache__/ContourExctractor.cpython-37.pyc | Bin 2056 -> 2274 bytes __pycache__/Exporter.cpython-37.pyc | Bin 0 -> 647 bytes main.py | 17 ++++--- short.mp4 | Bin 0 -> 23266 bytes 6 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 __pycache__/Exporter.cpython-37.pyc create mode 100644 short.mp4 diff --git a/ContourExctractor.py b/ContourExctractor.py index fd0edbf..880a9a4 100644 --- a/ContourExctractor.py +++ b/ContourExctractor.py @@ -8,15 +8,17 @@ import os import numpy as np import traceback import _thread +import imageio +import numpy as np class ContourExtractor: - #X = {frame_number: contours, } + #X = {frame_number: [(contour, (x,y,w,h)), ...], } extractedContours = dict() def __init__(self, videoPath): - print("ContourExtractror initiated") - print(videoPath) + print("ContourExtractor initiated") + min_area = 100 max_area = 30000 @@ -37,10 +39,10 @@ class ContourExtractor: # resize the frame, convert it to grayscale, and blur it if frame is None: return - #frame = imutils.resize(frame, width=500) + frame = imutils.resize(frame, width=500) cv2.imshow( "frame", frame ) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) - gray = cv2.GaussianBlur(gray, (31, 31), 0) + gray = cv2.GaussianBlur(gray, (5, 5), 0) # if the first frame is None, initialize it if firstFrame is None: @@ -58,15 +60,17 @@ class ContourExtractor: cnts = imutils.grab_contours(cnts) # loop over the contours + contours = [] for c in cnts: if cv2.contourArea(c) < min_area or cv2.contourArea(c) > max_area: continue (x, y, w, h) = cv2.boundingRect(c) - cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + contours.append((frame[y:y+h, x:x+w], (x, y, w, h))) + #cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) text = "Occupied" - self.extractedContours[frameCount] = cnts + self.extractedContours[frameCount] = contours frameCount += 1 #cv2.imshow( "annotated", frame ) @@ -77,14 +81,24 @@ class ContourExtractor: values = self.extractedContours.values() frame = np.zeros(shape=[1080, 1920, 3], dtype=np.uint8) - #frame = imutils.resize(frame, width=500) + frame = imutils.resize(frame, width=512) + frames = [] + writer = imageio.get_writer(os.path.join(os.path.dirname(__file__), "./short.mp4"), fps=30) + for xx in values: + for v1 in xx: + (x, y, w, h) = v1[1] + v = v1[0] + + #cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) - for x in values: - for v in x: - (x, y, w, h) = cv2.boundingRect(v) - cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + frame[y:y+v.shape[0], x:x+v.shape[1]] = v + frames.append(frame) + writer.append_data(np.array(frame)) + #cv2.imshow("changes overlayed", frame) + #cv2.waitKey(10) & 0XFF + #cv2.waitKey(0) + #cv2.destroyAllWindows() - cv2.imshow("changes overlayed", frame) - cv2.waitKey(0) - cv2.destroyAllWindows() + writer.close() + return frames diff --git a/Exporter.py b/Exporter.py index 5d61c84..93ac311 100644 --- a/Exporter.py +++ b/Exporter.py @@ -1,3 +1,12 @@ +import imageio +import numpy as np class Exporter: - def __init__(self): - print("Layer constructed") \ No newline at end of file + fps = 30 + def __init__(self, data, outputPath): + print("Exporter initiated") + fps = self.fps + writer = imageio.get_writer(outputPath, fps=fps) + for frame in data: + writer.append_data(np.array(frame)) + + writer.close() \ No newline at end of file diff --git a/__pycache__/ContourExctractor.cpython-37.pyc b/__pycache__/ContourExctractor.cpython-37.pyc index eea2bae31c907178f49f21655cf4d90c24ed4a0d..be4952ae04d86ee6d732b34d774b0338d6f74903 100644 GIT binary patch delta 1356 zcmZuv&2QX96rUN7?XlPPe&(wRAyJCx9-4{|6%H*bEvOe%C%K`ODjD9C0%6La+R?(7BJe!ReQX(=SNqpMNV`3sA&h-Gh~$VuU2( z`6_<(?2fX&!$K-^X3WuJl3AIf9FF#x_=uxNNYcIu*y8pRk~tF3EY6fOCm4ZmD~R;j zoMbK_N4ebL=G@3!WtSa(P;O>VZo;0cAO?9A@GGjKD2Ix^H>YR3vVt-XfUorRJ?=j- zG@b>@n^os#Dhgz9OmyZ$o=MvVy>`tA=X!XphV>Mm)$`lZ$Pn z0)_gEirqqr@yZ)0W0RZPNYANVeQ>79<0D%m|{XavPf%q z5xWM(E?$F318q+34 zgIqY{4&>0OR2Y~ZWahM|Oz=L-EM;+b1p%XW#xe&aXO&9Q;v$N{Tj>WnQj%*cyTnkj zbXIZ<3>velD%n+ZR+D5_*GRKH+1W;uPk?QZ+ZFgBf{12XSg?0m*}9SLjfC7f7{C5(O=siK=#5k1BB&Lh3Dj52Ox!Ypx?zc%;+`vE?X@B&3brS>qqDzi0j(?*XOdC zju~JASgD>KGc3Yxm$7z`5A1eJj|fDW9K^y0S6l^?|7dSq-_%GK|6kXF-8vZY!$JI( Qo_D&O|7kCpm|;f#1_Jy_d;kCd delta 1161 zcmZWoNpIUm6rPRbkRqwYieqPSy##I9Ls9h70C8MrYk@X!(dHmPaayPvI;Jg4){v?t zV+a>W4!IPl%}WkFke33zlC(DA=Sf(rH&3HF3^-P7NaD{XM%uDnfo!XqVuC}YQ!rsKqSOVsrd)wegd=LdP_4*a<>p=i*X;SQ>X6n; z8hKNB1x~%GP~KhiXgdX4-co*n71>AetMe1xXYdeztTl7mzRl8l+DMye3p8zItGa6J z5Wwa|q#CMq5$zCh(-mG}U?lu>Zv3i)l&8?%1;y8q;==w6rF^{6LAnz`ee3x0ozXBE zP2|04B76NrW-rKcqcnD8?;s4w%lDwk(#l?w<<)>nXf~3%_m%XLfYjyR^!t;;C=|hb zwm?_1ujrXwTG7EIi3V}@7rpXv>HavH3`I12{9V{jN?QWJV4&7*OK@)CRh->5KJ@jAY*^Jqon^#!^I4WdI9QnZSaftcnFgn3{y~Cml3?zk|S&3-GOm&d6=S3q7$$ z?i2{9(q!0M(RGGU^s|M~Evf$t0V$1mw|5wJ4Ux{vHSjvFb#|j9T)sW%4fiWz zf|_h+zne=Z9++iI!<>dXK-W6zMakFUtlJb}oXFAa)?mgBov)fRQni>A~{HsQwdlxROd`Gtc-o~=2ExD zDRcW26N^9{WcE*A;c4HZaoEN+0O`pZwvnUjsHZ)G{h(WR`J{)}pTy<5Ag^t`ttm41BcGHcNc0P1!iZkkQY}TAZu0&C_$` z_%~Bxm-#)RwQ3}n!U<0s?PFn#*!Z}pTC1{|XI51!&%%A4ww=?R`ykwx5pp)7_;_VR zt$q=6fJA?u6)%?Bv};v3yL4r(j*7O{Mp;|7&2nn@x!(AM^UyTsahS^<8UhK--~duM zq*o9B=T3QxFk;RdWaHeYoY$@Fs^IT&e$k0)ycxPP4-jtX=#IG`VquwKGd9d60R}@P jVvvb%eZSA%XP?*J=e+khXTMJu!!W#8L`;Zp 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