Video-Summary/ContourExctractor.py

120 lines
3.9 KiB
Python

from imutils.video import VideoStream
import argparse
import datetime
import imutils
import time
import cv2
import os
import traceback
import _thread
import imageio
import numpy as np
import time
from threading import Thread
from multiprocessing import Queue, Process, Pool
from multiprocessing.pool import ThreadPool
import concurrent.futures
from VideoReader import VideoReader
class ContourExtractor:
#X = {frame_number: [(contour, (x,y,w,h)), ...], }
extractedContours = dict()
min_area = 100
max_area = 1000
threashold = 13
xDim = 0
yDim = 0
def getextractedContours(self):
return self.extractedContours
def __init__(self):
print("ContourExtractor initiated")
def extractContours(self, videoPath, resizeWidth):
firstFrame = None
extractedContours = dict()
videoReader = VideoReader(videoPath)
self.xDim = videoReader.w
self.yDim = videoReader.h
videoReader.fillBuffer()
while not videoReader.videoEnded():
frameCount, frame = videoReader.pop()
if frameCount % (60*30) == 0:
print("Minutes processed: ", frameCount/(60*30))
if frame is None:
print("ContourExtractor: frame was None")
continue
# resize the frame, convert it to grayscale, and blur it
frame = imutils.resize(frame, width=resizeWidth)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 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
x = self.getContours(gray, firstFrame)
if x is not None:
extractedContours[frameCount] = x
print("done")
videoReader.thread.join()
self.extractedContours = extractedContours
return extractedContours
def getContours(self, gray, firstFrame):
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 and contours is not None:
return contours
def displayContours(self):
values = self.extractedContours.values()
for xx in values:
for v1 in xx:
(x, y, w, h) = v1[1]
v = v1[0]
frame = np.zeros(shape=[self.yDim, self.xDim, 3], dtype=np.uint8)
frame = imutils.resize(frame, width=512)
frame[y:y+v.shape[0], x:x+v.shape[1]] = v
cv2.imshow("changes overlayed", frame)
cv2.waitKey(10) & 0XFF
cv2.destroyAllWindows()
def exportContours(self):
values = self.extractedContours.values()
frames = []
for xx in values:
for v1 in xx:
(x, y, w, h) = v1[1]
v = v1[0]
frame = np.zeros(shape=[self.yDim, self.xDim, 3], dtype=np.uint8)
frame = imutils.resize(frame, width=512)
frame[y:y+v.shape[0], x:x+v.shape[1]] = v
frames.append(frame)
return frames