Ask Your Question
0

How to save video using thread

asked 2020-07-24 00:30:43 -0600

tester gravatar image

updated 2020-07-24 00:58:33 -0600

I am making a program that takes a video for 10 seconds when an object is detected.
If 'out' is created before 'while', the video is saved only once
when use this code .avi file is just created and there is nothing saved
Is it the right way to use threads? Or is there any other way?

import cv2
import numpy as np
import time
import threading

def thread():
    global recording,out
    recording = True
    print("recording start")
    time.sleep(10)
    recording = False
    out.release()
    print("recording end")

global recording, out

cap = cv2.VideoCapture("rtsp://128.1.1.6/profile2/media.smp")

fgbg = cv2.createBackgroundSubtractorMOG2(varThreshold=200, detectShadows=0)

fps = 60
width = int(cap.get(3))
height = int(cap.get(4))
fcc = cv2.VideoWriter_fourcc(*'XVID') 
recording = False

while(1):
    ret, frame = cap.read()
    hms = time.strftime('%H:%M:%S', time.localtime())
    hmss = time.strftime('%H_%M_%S', time.localtime())

    fgmask = fgbg.apply(frame)

    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(fgmask)
    cv2.putText(frame,str(hms),(0,15),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,255,255))

    for index, centroid in enumerate(centroids):

        if stats[index][0] == 0 and stats[index][1] == 0:
            continue
        if np.any(np.isnan(centroid)):
            continue

        x, y, width, height, area = stats[index]
        centerX, centerY = int(centroid[0]), int(centroid[1])

        if area > 50: #Minimum size detected
            cv2.circle(frame, (centerX, centerY), 1, (0, 255, 0), 2) 
            cv2.rectangle(frame, (x, y), (x + width, y + height), (0, 0, 255)) 
            cv2.putText(frame, str(area), (centerX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255)) # detected size

        if area > 1000 and not recording:
            t1 = threading.Thread(target=thread)
            path = 'E:\\test_' + str(hmss) + '.avi'
            out = cv2.VideoWriter(path, fcc, fps, (width, height))
            recording = True
            print(str(hms))
            t1.start()

    cv2.imshow('mask', fgmask)
    cv2.imshow('frame', frame)

    if recording:
        out.write(frame)

    k = cv2.waitKey(1) & 0xff 

cap.release()
out.release()
cv2.destroyAllWindows()
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2020-07-24 02:10:20 -0600

berak gravatar image

please do not use threads to implement "state logic", you don't need this, and it's a terrible idea.

also, NEVER share data between threads (w/o locks) (esp. VideoCapture is NOT thread-safe), and NEVER have global variables in your program

all you need here, is a timer, not a seperate thread, you could use recording to keep the time like:

recording = 0 # not recording

in your contours loop:

    if area > 1000 and recording == 0:
        out = cv2.VideoWriter(path, fcc, fps, (width, height))
        recording = time.time() # start timer

then, later:

if recording > 0:
    out.write(frame)
    if time.time() - recording >= 10: # 10 seconds have passed
       recording = 0 # reset timer
       out.release()
edit flag offensive delete link more

Comments

Thank you very much for letting me know about the thread.
But the result is still same, Only files are created and nothing is saved..

tester gravatar imagetester ( 2020-07-24 04:04:40 -0600 )edit

@supra56 please mention downvote reason

sturkmen gravatar imagesturkmen ( 2020-08-06 01:53:51 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2020-07-24 00:30:43 -0600

Seen: 2,036 times

Last updated: Jul 24 '20