1
A little while ago I learned to capture videos via webcam using Python with the Opencv library. After that, I had the idea of making a script that automatically starts and ends the recording of a video. Started the program, the capture would start, but would only start recording if the captured frame met a certain condition I created (based on a detection function I did). Video recording would automatically end when the captured frames did not contain what the detector function is programmed to detect. The detector function returns True if the image satisfies my condition and False if it does not satisfy. The script is as follows:
def webvideo(path):
import sys,cv2
begin=False
cap=cv2.VideoCapture(0)
if not cap.isOpened():
print('Não foi possível abrir a web cam.')
sys.exit(-1)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter(path,fourcc, 20.0, (640,480))
while True:
ret, frame = cap.read()
if ret:
cv2.imwrite('temp.jpg',frame)
if not begin:
if funcao_detectora('temp.jpg'):
begin=True
else:
if not funcao_detectora('temp.jpg'):
break
if begin:
out.write(frame)
else:
break
cap.release()
out.release()
webvideo('teste.avi')
The problem is that the detector function reads each frame, which takes a while. Thus, it takes a while for the next frame to be captured and the video looks like a sequence of fairly time-spaced photos. Question: how do I run the detector function in a process other than the process of recording frames so that frames are recorded without interruption?
NOTE: it is not necessary to apply the knowledge of multithreading to solve this specific case, but if someone shows an example that I understand and can apply in my script, I will also accept.
An "intuition" is that you do not immediately process each frame of the video, but put it on a list to be processed when it is processed (ideally, in a separate thread even). If I have time today I see if I can answer.
– Luiz Vieira
I don’t think it is necessary to store each frame in a list, I think it is enough to create a function that makes the detector function read each frame and make this function run in a different process. But I don’t know how you do it. I tried to read the documentation of the multiprocessing module, but besides being beginner in the area, I do not know much English and I end up understanding very little.
– Benedito
Well, your problem today is precisely the fact that your processing of the frames takes longer than capturing them. If you use another thread but block it in a call between threads, your end result will be the same: frames "skipped".
– Luiz Vieira
Ah, another thing: I used one thread different, and not a different process. That is, it runs everything in the same process, but in parallel. I believe that multiprocessing in this case is wrong, because there will be a frequent communication of potentially large data (the frames of the video, besides being captured 20x per second, have 480 thousand pixels - being conservative and considering a very low resolution of 800x600).
– Luiz Vieira