I'm doing a motion detection program where it snaps an image when it detects movement and snaps an image of the person's face if in view while this is all recorded and sends it all to Dropbox.
It's moving very slowly and lagging like crazy, showing 1 frame in like a minute. Is there a way to optimize it?
I'm using a Raspberry Pi to code all this, and a webcam.
import sys
sys.path.append('/usr/local/lib/python3.4/site-packages')
import numpy as np
import cv2
import imutils
from imutils import contours
import datetime
import time
import dropbox
#Function fo Drawing rect and changing text to REC
def draw_rect_movement(c):
#Draw Rectangle around found contour object
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)
text = "REC"
return c
def saveNupload(roi_color):
#writing image of face as png in the file
timestring = time.strftime("%Y_%m_%d_%H_%M_%S")
face_timestr = 'face_' + timestring + '.png'
cv2.imwrite(face_timestr, roi_color)
#Opening for [r]eading as [b]inary
FaceFile = open(face_timestr, mode = "rb")
#Reads the number of bytes of the video
data = FaceFile.read()
#Setting the save location with file name
SavetoLocation = '/FYP_Face_Save/'+ face_timestr
SaveToLocation = str(SavetoLocation)
dbx.files_upload(data, SaveToLocation)
#Close for reading and binary
FaceFile.close()
dbx = dropbox.Dropbox('Access Token')
dbx.users_get_current_account()
#cap = cv2.VideoCapture("/home/pi/Desktop/Proj/VideoTestSample.mp4")
cap = cv2.VideoCapture(1)
#Creating froeground and removing Background
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False)
#Set format
fourcc = cv2.VideoWriter_fourcc(*'XVID')
#Get Datetime
timestr = time.strftime("%Y_%m_%d_%H_%M_%S")
#Creating name of folder
timestr = timestr + '.avi'
#Setting Name, Format, FPS, FrameSize
out = cv2.VideoWriter(timestr,fourcc, 10.0, (640, 480))
#setting casacade for use
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#setting criteria for termination
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
#As long as the VideoCapture is open loop to show the frames
while (cap.isOpened()):
#capture frame-by-frame
(grabbed, frame) = cap.read()
text = " "
if not grabbed:
break
#Convert frame to Black white and gray
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#placing Cascade detection
faces = face_cascade.detectMultiScale(gray, 1.2,)
#Drawing around the detected "face"
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x -20,y-20), (x + w + 20, y + h + 20), (255,0,0), 2)
roi_color = frame[y-20:y + h + 20, x -20:x + w + 20]
saveNupload(roi_color = roi_color)
#Apply the Background SubtractionMOG2
fgmask = fgbg.apply(gray)
#Erode away the boundaries of the foreground object
thresh = cv2.erode(fgmask, None, iterations=2)
#Set detect as none
detect = None
#FindContours returns a list of the outlines of the white shapes in the mask (and a heirarchy that we shall ignore)
(_,cnts,hierarchy) = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#Draw the DateTime on the bottom left hand corner
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35,(0,0,255), 1)
#detect is object found or not found
detect = (_,cnts,hierarchy)
#if object found is detected run these codes
if detect == (_,cnts,hierarchy):
#if area of object is lower than 300 ignore it
for (i,c) in enumerate(cnts):
if cv2.contourArea(c) < 1100:
print("ignore small contours", cv2.contourArea(c))
continue
#Uncomment this function call to display motion detected
###draw_rect_movement(c = c)
#Temporary code
text = "Movement Detected ... Snapping"
#Capture image
timestring = time.strftime("%Y_%m_%d_%H_%M_%S")
image_timestr = 'image_' + timestring + '.png'
cv2.imwrite(image_timestr, frame)
#Opening for [r]eading as [b]inary
ImageFile = open(image_timestr, mode = "rb")
#Reads the number of bytes of the video
data = ImageFile.read()
#Setting the save location with file name
SavetoLocation = '/FYP_Image_Save/'+ image_timestr
SaveToLocation = str(SavetoLocation)
dbx.files_upload(data, SaveToLocation)
#Close for reading and binary
ImageFile.close()
detect= None
if detect != (_,cnts,hierarchy):
continue
elif detect != (_,cnts,hierarchy):
print("Not Snaping")
else:
continue
#Draw the text at top right hand corner
cv2.putText(frame, "{}". format(text), (10,20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
#Write which window into video in this case Frame
out.write(frame)
#Display the following windows
cv2.imshow('frame',frame)
cv2.imshow('gray', gray)
cv2.imshow('fgmask', fgmask)
#if q is pressed break loop
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#Stop recording
out.release()
#Kill all windows
cap.release()
cv2.destroyAllWindows()
#Opening for [r]eading as [b]inary
VideoFile = open(timestr, mode = "rb")
#Reads the number of bytes of the video
data = VideoFile.read()
#Setting the save location with file name
SavetoLocation = '/FYP_Video_Save/'+timestr
SaveToLocation = str(SavetoLocation)
#Upload the file
print("Sending to Dropbox")
dbx.files_upload(data, SaveToLocation)
#Close for reading and binary
VideoFile.close()