As part of an interactive installation, I would like to program an audio filter LPF (cut high frequencies) on a sound that runs in a loop on python. In addition I would like to vary the cutoff frequency of the filter according to the distance of an obstacle measured by a distance sensor, all on a Raspberry Pi 3.
I have already managed to program the distance measurement by the sensor and to run a looping sound but I do not know how to do it for the audio filter. By searching on the internet I can not find an answer and a clear method on my situation.
Here is my code:
#Libraries
import RPi.GPIO as GPIO
import time
import pygame
pygame.init()
caca = pygame.mixer.Sound("bells001.wav")
pygame.mixer.music.load("bells001.wav")
#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
pygame.mixer.music.play(-1)
#set GPIO Pins
GPIO_TRIGGER = 23
GPIO_ECHO = 24
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
def distance():
# set Trigger to HIGH
GPIO.output(GPIO_TRIGGER, True)
# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
StartTime = time.time()
StopTime = time.time()
# save StartTime
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()
# save time of arrival
while GPIO.input(GPIO_ECHO) == 1:
StopTime = time.time()
# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2
return distance
if __name__ == '__main__':
try:
while True:
dist = distance()
print (dist)
time.sleep(0.2)
# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()
I tried this for now
from pydub import AudioSegment
from pydub.playback import play
song = AudioSegment.from_wav("bells001.wav")
new = song.low_pass_filter(10000)
play(new)
Unfortunately instead of me out a filtered sound, I have the sound very degraded with lots of crunches ... Anyone have an idea?
I tried other scripts but I still have problems with module or library not found while I install and reinstall all these modules.
Can anyone help me?
Related
I have to stitch the images captured from many (9) cameras. Initially, I tried to capture the frames from 2 cameras with rate 15 FPS. Then, I connected 4 cameras (I also used externally powered USB hub to provide enough power) but I could only see only one stream.
For testing, I used the following script:
import numpy as np
import cv2
import imutils
index = 0
arr = []
while True:
cap = cv2.VideoCapture(index)
if not cap.read()[0]:
break
else:
arr.append(index)
cap.release()
index += 1
video_captures = [cv2.VideoCapture(idx) for idx in arr]
while True:
# Capture frame-by-frame
frames = []
frames_preview = []
for i in arr:
# skip webcam capture
if i == 1: continue
ret, frame = video_captures[i].read()
if ret:
frames.append(frame)
small = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
frames_preview.append(small)
for i, frame in enumerate(frames_preview):
cv2.imshow('Cam {}'.format(i), frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
for video_capture in video_captures:
video_capture.release()
cv2.destroyAllWindows()
Is there any limit for the number of cameras? Does anyone know what is the right way to capture frames from multiple cameras?
To capture multiple streams with OpenCV, I recommend using threading which can improve performance by alleviating the heavy I/O operations to a separate thread. Since accessing the webcam/IP/RTSP stream using cv2.VideoCapture().read() is a blocking operation, our main program is stuck until the frame is read from the camera device. If you have multiple streams, this latency will definitely be visible. To remedy this problem, we can use threading to spawn another thread to handle retrieving the frames using a deque in parallel instead of relying on a single thread to obtain the frames in sequential order. Threading allows frames to be continuously read without impacting the performance of our main program. The idea to capture a single stream using threading and OpenCV, is from a previous answer in Python OpenCV multithreading streaming from camera.
But if you want to capture multiple streams, OpenCV alone is not enough. You can use OpenCV in combination with a GUI framework to stitch each image onto a nice display. I will use PyQt4 as the framework, qdarkstyle for GUI CSS, and imutils for OpenCV convenience functions.
Here is a very stripped down version of the camera GUI I currently use without the placeholder images, credential admin login page, and camera switching ability. I've kept the automatic camera reconnect feature incase the internet dies or the camera connection is lost. I only have 8 cameras as shown in the image above, but it is very simple to add in another camera and should not impact performance. This camera GUI currently performs at about ~60 FPS so it is real-time. You can easily rearrange the layout using PyQt layouts so feel free to modify the code! Remember to change the stream links!
from PyQt4 import QtCore, QtGui
import qdarkstyle
from threading import Thread
from collections import deque
from datetime import datetime
import time
import sys
import cv2
import imutils
class CameraWidget(QtGui.QWidget):
"""Independent camera feed
Uses threading to grab IP camera frames in the background
#param width - Width of the video frame
#param height - Height of the video frame
#param stream_link - IP/RTSP/Webcam link
#param aspect_ratio - Whether to maintain frame aspect ratio or force into fraame
"""
def __init__(self, width, height, stream_link=0, aspect_ratio=False, parent=None, deque_size=1):
super(CameraWidget, self).__init__(parent)
# Initialize deque used to store frames read from the stream
self.deque = deque(maxlen=deque_size)
# Slight offset is needed since PyQt layouts have a built in padding
# So add offset to counter the padding
self.offset = 16
self.screen_width = width - self.offset
self.screen_height = height - self.offset
self.maintain_aspect_ratio = aspect_ratio
self.camera_stream_link = stream_link
# Flag to check if camera is valid/working
self.online = False
self.capture = None
self.video_frame = QtGui.QLabel()
self.load_network_stream()
# Start background frame grabbing
self.get_frame_thread = Thread(target=self.get_frame, args=())
self.get_frame_thread.daemon = True
self.get_frame_thread.start()
# Periodically set video frame to display
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.set_frame)
self.timer.start(.5)
print('Started camera: {}'.format(self.camera_stream_link))
def load_network_stream(self):
"""Verifies stream link and open new stream if valid"""
def load_network_stream_thread():
if self.verify_network_stream(self.camera_stream_link):
self.capture = cv2.VideoCapture(self.camera_stream_link)
self.online = True
self.load_stream_thread = Thread(target=load_network_stream_thread, args=())
self.load_stream_thread.daemon = True
self.load_stream_thread.start()
def verify_network_stream(self, link):
"""Attempts to receive a frame from given link"""
cap = cv2.VideoCapture(link)
if not cap.isOpened():
return False
cap.release()
return True
def get_frame(self):
"""Reads frame, resizes, and converts image to pixmap"""
while True:
try:
if self.capture.isOpened() and self.online:
# Read next frame from stream and insert into deque
status, frame = self.capture.read()
if status:
self.deque.append(frame)
else:
self.capture.release()
self.online = False
else:
# Attempt to reconnect
print('attempting to reconnect', self.camera_stream_link)
self.load_network_stream()
self.spin(2)
self.spin(.001)
except AttributeError:
pass
def spin(self, seconds):
"""Pause for set amount of seconds, replaces time.sleep so program doesnt stall"""
time_end = time.time() + seconds
while time.time() < time_end:
QtGui.QApplication.processEvents()
def set_frame(self):
"""Sets pixmap image to video frame"""
if not self.online:
self.spin(1)
return
if self.deque and self.online:
# Grab latest frame
frame = self.deque[-1]
# Keep frame aspect ratio
if self.maintain_aspect_ratio:
self.frame = imutils.resize(frame, width=self.screen_width)
# Force resize
else:
self.frame = cv2.resize(frame, (self.screen_width, self.screen_height))
# Add timestamp to cameras
cv2.rectangle(self.frame, (self.screen_width-190,0), (self.screen_width,50), color=(0,0,0), thickness=-1)
cv2.putText(self.frame, datetime.now().strftime('%H:%M:%S'), (self.screen_width-185,37), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255,255,255), lineType=cv2.LINE_AA)
# Convert to pixmap and set to video frame
self.img = QtGui.QImage(self.frame, self.frame.shape[1], self.frame.shape[0], QtGui.QImage.Format_RGB888).rgbSwapped()
self.pix = QtGui.QPixmap.fromImage(self.img)
self.video_frame.setPixmap(self.pix)
def get_video_frame(self):
return self.video_frame
def exit_application():
"""Exit program event handler"""
sys.exit(1)
if __name__ == '__main__':
# Create main application window
app = QtGui.QApplication([])
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt())
app.setStyle(QtGui.QStyleFactory.create("Cleanlooks"))
mw = QtGui.QMainWindow()
mw.setWindowTitle('Camera GUI')
mw.setWindowFlags(QtCore.Qt.FramelessWindowHint)
cw = QtGui.QWidget()
ml = QtGui.QGridLayout()
cw.setLayout(ml)
mw.setCentralWidget(cw)
mw.showMaximized()
# Dynamically determine screen width/height
screen_width = QtGui.QApplication.desktop().screenGeometry().width()
screen_height = QtGui.QApplication.desktop().screenGeometry().height()
# Create Camera Widgets
username = 'Your camera username!'
password = 'Your camera password!'
# Stream links
camera0 = 'rtsp://{}:{}#192.168.1.43:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
camera1 = 'rtsp://{}:{}#192.168.1.45/axis-media/media.amp'.format(username, password)
camera2 = 'rtsp://{}:{}#192.168.1.47:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
camera3 = 'rtsp://{}:{}#192.168.1.40:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
camera4 = 'rtsp://{}:{}#192.168.1.44:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
camera5 = 'rtsp://{}:{}#192.168.1.42:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
camera6 = 'rtsp://{}:{}#192.168.1.46:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
camera7 = 'rtsp://{}:{}#192.168.1.41:554/cam/realmonitor?channel=1&subtype=0'.format(username, password)
# Create camera widgets
print('Creating Camera Widgets...')
zero = CameraWidget(screen_width//3, screen_height//3, camera0)
one = CameraWidget(screen_width//3, screen_height//3, camera1)
two = CameraWidget(screen_width//3, screen_height//3, camera2)
three = CameraWidget(screen_width//3, screen_height//3, camera3)
four = CameraWidget(screen_width//3, screen_height//3, camera4)
five = CameraWidget(screen_width//3, screen_height//3, camera5)
six = CameraWidget(screen_width//3, screen_height//3, camera6)
seven = CameraWidget(screen_width//3, screen_height//3, camera7)
# Add widgets to layout
print('Adding widgets to layout...')
ml.addWidget(zero.get_video_frame(),0,0,1,1)
ml.addWidget(one.get_video_frame(),0,1,1,1)
ml.addWidget(two.get_video_frame(),0,2,1,1)
ml.addWidget(three.get_video_frame(),1,0,1,1)
ml.addWidget(four.get_video_frame(),1,1,1,1)
ml.addWidget(five.get_video_frame(),1,2,1,1)
ml.addWidget(six.get_video_frame(),2,0,1,1)
ml.addWidget(seven.get_video_frame(),2,1,1,1)
print('Verifying camera credentials...')
mw.show()
QtGui.QShortcut(QtGui.QKeySequence('Ctrl+Q'), mw, exit_application)
if(sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
Related camera/IP/RTSP, FPS, video, threading, and multiprocessing posts
Python OpenCV streaming from camera - multithreading, timestamps
Video Streaming from IP Camera in Python Using OpenCV cv2.VideoCapture
How to capture multiple camera streams with OpenCV?
OpenCV real time streaming video capture is slow. How to drop frames or get synced with real time?
Storing RTSP stream as video file with OpenCV VideoWriter
OpenCV video saving
Python OpenCV multiprocessing cv2.VideoCapture mp4
As you can see below I have a program that uses pyqtgraph to display a spectrum of two signals on some noise using numpy. It may well be I am pushing the limits here. I am using a sample rate of 300000 to put some pressure on things. None-the-less I saw no improvements in splitting up this app using multiprocess or threading from putting the code lines in the signal() function from having it all under the update() function. I also tried pyfftw, which showed no improvement when substituting that in for np.fft. I show 1 core always at 100% so I suspect multiprocess (or threading) may not really be working the way I expect it either. Depending on your computer at aa rate 300000 it updates and pauses and updates and pauses. I would like to hit something like 2400000 smoothly without the pauses between updates. Anyone know how I can speed this up please?
# -*- coding: utf-8 -*-
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
from threading import Thread
from queue import Queue
from numpy import arange, sin, cos, pi
from scipy.fftpack import fft, rfft
import pyqtgraph as pg
import sys
import multiprocessing
class Plot2D():
def __init__(self):
self.traces = dict()
#QtGui.QApplication.setGraphicsSystem('raster')
self.app = QtGui.QApplication([])
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
self.win = pg.GraphicsWindow(title="Basic plotting examples")
self.win.resize(1000,600)
self.win.setWindowTitle('pyqtgraph example: Plotting')
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
self.canvas = self.win.addPlot(title="Pytelemetry")
self.canvas.setYRange(-10, 100, padding=0)
def start(self):
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
def trace(self,name,dataset_x,dataset_y):
if name in self.traces:
self.traces[name].setData(dataset_x,dataset_y)
else:
self.traces[name] = self.canvas.plot(pen='y')
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
p = Plot2D()
i = 0
def signal():
rate = 300000 # sampling rate
t = np.arange(0, 10, 1/rate)
sig = np.sin(2000*np.pi*4*t) + np.sin(2000*np.pi*7*t) + np.random.randn(len(t))*0.02 #4k + 7k tone + noise
return sig
def update():
rate = 300000 # sampling rate
z = 20*np.log10(np.abs(np.fft.rfft(signal()))) #rfft trims imag and leaves real values
f = np.linspace(0, rate/2, len(z))
p.trace("Amplitude", f, z)
timer = QtCore.QTimer()
timer.timeout.connect(lambda: update())
timer.start(10)
p.start()
t1 = multiprocessing.Process(target=signal)
t1.start
I'm using the following script to play all the WAV files in the current path. I will be modifying it to print the output of some text files. That part is easy.
Need to know how/where in the loop of playing the WAV files, where to add some code to pause/interupt the execution of the code with the keyboard.
#!/usr/bin/python3
import vlc
import time
import glob
wav_files = glob.glob("*.wav")
instance=vlc.Instance(["--no-sub-autodetect-file"])
# You should not recreate a player for each file, just reuse the same
# player
player=instance.media_player_new()
for wav in wav_files:
player.set_mrl(wav)
player.play()
playing = set([1,2,3,4])
time.sleep(5) #Give time to get going
duration = player.get_length() / 1000
mm, ss = divmod(duration, 60)
print("Playing", wav, "Length:", "%02d:%02d" % (mm,ss))
while True:
state = player.get_state()
if state not in playing:
break
continue
Steal the getch right out of vlc.py
I've added the windows option, as you didn't specify an OS.
#!/usr/bin/python3
import vlc
import time
import glob
import sys
import termios, tty
try:
from msvcrt import getch # try to import Windows version
except ImportError:
def getch(): # getchar(), getc(stdin) #PYCHOK flake
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
return ch
wav_files = glob.glob("*.wav")
print("Play List")
for f in wav_files:
print(f)
instance=vlc.Instance(["--no-sub-autodetect-file"])
# You should not recreate a player for each file, just reuse the same
# player
player=instance.media_player_new()
for wav in wav_files:
player.set_mrl(wav)
player.play()
playing = set([1,2,3,4])
time.sleep(1) #Give time to get going
duration = player.get_length() / 1000
mm, ss = divmod(duration, 60)
print("Playing", wav, "Length:", "%02d:%02d" % (mm,ss))
while True:
state = player.get_state()
if state not in playing:
break
k = getch()
if k in ["N","n"]:#Next
player.stop()
break
elif k in ["Q","q"]:#Quit
player.stop()
sys.exit()
break
elif k == " ":#Toggle Pause
player.pause()
else:
print("[Q - Quit, N - Next, Space - Pause]")
continue
I am using opencv(cv2) in python to record videos(only video required) from multiple webcams simultaneously. Though they are not synchronized they record at a constant framerate. The problems are
They record at 4fps when resolution is set to 1080p, while desired is 30fps. The cameras I am using support this. While previewing though the framerate is 30fps which leads me to believe I may be doing some thing wrong while recording. I am using threading as in imutils library to get the videos as suggested in this blog post.
Is there anyway to synchronize the different camera outputs(videos).
PC specs:
Intel i5 7thgen,
8gb ddr3 ram,
SSD harddrive.
The webcams I'm using are Genius 32200312100 WideCam F100 USB 2.0 WebCam.
I do not think these are a limitation as I've been monitoring the CPU and memory usage while recording.
Any help is appreciated and if any further information is required please feel free to ask.
I'm open to using any encodings that will not compromise the quality of the picture.
Edit: I'm posting the code below.
class VideoRecorder():
#Function that runs once when the VideoRecorder class is called.
def __init__(self,cam_id = 0):
#Initialize the camera and set its properties
self.cam_id = cam_id
self.framerate = 30
self.video_height = 720
self.video_width = 1280
self.cap = cv2.VideoCapture(self.cam_id)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT,self.video_height)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH,self.video_width)
self.cap.set(cv2.CAP_PROP_FPS,self.framerate)
# Grab a initial frame, It is to warm up the camera.
# This frame will not be used
temp1, temp2 = self.cap.read()
#Set the place where the file is to be stored
storage_path = "{Output_folder}"
file_name = datetime.datetime.now().strftime("%m%d%Y_%H%M%S")
file_name = "cam_" + str(self.cam_id) + "_" + file_name + ".avi"
self.file = os.path.join(storage_path,file_name)
#Initialize a videowriter object to save the recorded frames to a file
self.fourcc = cv2.VideoWriter_fourcc(*'H264')
self.out = cv2.VideoWriter(self.file,self.fourcc,self.framerate,
(self.video_width,self.video_height))
def record(self, timer = 10):
#Start a timer for the recording to see how long the recording should be
self.start_time = time.time()
#Start a frame counter to calculate the framerate at the end
self.frame_count = 0
#Run an loop for given time to get frames from camera and store them
while(self.cap.isOpened()):
tora1 = time.time()
ret, frame = self.cap.read()
print("Time for reading the frame",time.time()-tora1)
if ret == True:
tora2 = time.time()
self.out.write(frame)
print("Time for write",tora2-time.time())
self.frame_count += 1
else:
break
current_time = time.time()
self.elapsed_time = current_time - self.start_time
if(self.elapsed_time > timer):
self.stop()
break
#Start the recording in a thread
def start(self, timer):
video_thread = threading.Thread(target = self.record, args = (timer,))
#video_thread.daemon = True
video_thread.start()
#Print the fps and release all the objects
def stop(self):
print("Frame count: %d"%self.frame_count)
self.fps = self.frame_count/self.elapsed_time
print(self.elapsed_time)
print("fps: %f"%self.fps)
self.out.release()
self.cap.release()
print("Done")
if __name__ == "__main__":
#Giving which arguments to pass to the script form command line ans
#getting them in a args structure
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--runtime", type = int, default = 10,
help = "TIme for which the videorecoder runs")
ap.add_argument("-id", "--cam_id", type=int, default= 0,
help="give camera id")
args = vars(ap.parse_args())
required_time = args["runtime"]
video_thread = []
for i in range(args["cam_id"]+1):
t = VideoRecorder(i)
video_thread.append(t)
t.start(required_time)
I made a motion detector solely software-based by referring a few books and then adding my own code. The added code saves a frame of the detected motion locally on the Raspberry Pi and also uploads the same to my Google Drive. Another set of code, sends an email to my email-address informing me of the motion detected.
The problem is that when the file is being saved and uploaded, the Open CV output window freezes until the above processes finish. I tried multiprocessing and multi-threading on python but it didn't help. Is there any way I could improve my logic in a way that it doesn't freeze the output window?
EDIT : The issue was somewhat fixed by removing join() from the two processes. There is a very slight lag but I think that's good enough. Thanks to everyone who replied :)
from pydrive.drive import GoogleDrive
from pydrive.auth import GoogleAuth
import cv2
from multiprocessing import Process
import numpy as np
import datetime
import time
import smtplib
# make count 0
count = 0
def sf(t2):
cv2.imwrite("/home/pi/Desktop/StoredImages/frame%d.jpg" % count, t2)
# 'google drive authentication' stuff
gauth = GoogleAuth()
# try to load saved client credentials
gauth.LoadCredentialsFile("mycreds.txt")
if gauth.credentials is None:
# authenticate if not there
gauth.LocalWebserverAuth()
elif gauth.access_token_expired:
# Refresh them if expired
gauth.Refresh()
else:
# Initialize the saved creds
gauth.Authorize()
# Save the current credentials to a file
gauth.SaveCredentialsFile("mycreds.txt")
drive = GoogleDrive(gauth)
def upload_file():
file1 = drive.CreateFile({'parent':'/home/pi/Desktop/StoredImages/'})
file1.SetContentFile('/home/pi/Desktop/StoredImages/frame%d.jpg' % count)
file1.Upload()
# 'sending an email' stuff
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login("Removed Intentionally","Removed Intentionally")
msg = "Motion Detected! For more details check your Drive."
# capture Video from the camera module
cap = cv2.VideoCapture(0)
# stores the present date and time
lastUploaded = datetime.datetime.now()
# kernel is created for the dilation process
k = np.ones((3,3),np.uint8) # creates a 3X3 Matrix filled with ones and
# has the data type uint8 (unsigned integer)
# which can contain values from 0 to 255
# first two subsequent frames captured
t0 = cap.read()[1]
t1 = cap.read()[1]
# initially motion detected 0 times
motionCounter = 0
while True:
# difference between two subsequent frames
d=cv2.absdiff(t1,t0)
# stores present date and time
timestamp = datetime.datetime.now()
# converting difference to grayscale
grey = cv2.cvtColor(d,cv2.COLOR_BGR2GRAY)
# grayscale converted to gaussian blur
blur = cv2.GaussianBlur(grey,(3,3),0)
# gaussian blur converted to binary image
ret, th = cv2.threshold(blur, 15, 155, cv2.THRESH_BINARY)
# dilating the image before using the contour function
dilated = cv2.dilate(th,k,iterations=2)
# contour function to find edges
_, contours, heierarchy = cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# copying the original frame to a temporary frame for display
t2 = t0
# drawing green edges around the area with movement
cv2.drawContours(t2, contours, -1, (0,255,0), 2)
# showing output in a new window
cv2.imshow('Output',t2)
# going through each and every contour in the image
for c in contours:
# if contour is lesser than a threshold size, ignore
if cv2.contourArea(c) < 5000:
continue
# if motion occurred after 2 secs
if (timestamp - lastUploaded).seconds >= 2.0:
motionCounter += 1
# if 8 motions occured in 2 secs
if motionCounter >= 8:
# write to a temporary file location using threads
new_process = Process(target=sf, args=(t2,))
new_process.start()
new_process.join()
# upload the temporary pic to Google drive using threads
new_process = Process(target=upload_file)
new_process.start()
new_process.join()
# sending a mail about motion detected
server.sendmail("Removed Intentionally","Removed Intentionally",msg)
# increasing count by 1 and resetting everything
count=count+1
lastUploaded = timestamp
motionCounter = 0
# making the next frame the previous and reading a new frame
t0 = t1
t1 = cap.read()[1]
# esc key breaks the entire loop
if cv2.waitKey(5) == 27:
break
# stops the video stream and exits the window
cap.release()
cv2.destroyAllWindows()
# stops the email server connection
server.quit()
I think you used the multiprocessing in a wrong way. Your code
# write to a temporary file location using threads
new_process = Process(target=sf, args=(t2,))
new_process.start()
new_process.join()
will actually create and start a process, but then it will also wait for it (new_process.join()) to finish. So basically you want to start a parallel running process, but then you wait for it to finish.
Better would be to create and start the processes at the beginning of your program and wait for them to finish at the very end of your program.
Also create a queue for each process (also in the multiprocessing module).
Each process should run in an endless loop and wait for a queue. In your main thread, you feed each process' queue with what it should do (store a file locally, store file remotely)
At the end of your program, you should send your processes a final indication to leave their endless loop, so your new_process.join() statement in the main thread will pick up the fact, that the processes have ended.