cv2 动作捕捉,.avi 文件被拉伸 - Python

发布于 2025-01-12 14:58:36 字数 1417 浏览 1 评论 0原文

所以我试图让我的网络摄像头捕捉运动,并且我如何注册运动进展顺利,但由于所有这些嵌套的 while 循环,我的保存文件被拖到 30 分钟长,而不是像预期的 10 秒。我不明白我做错了什么。

我所说的拖长是指我录制了 10 秒,但当我进入文件查看素材时,发现只有一些帧,长达 30 分钟。

我们的想法是让它记录运动,然后录制 10 秒并将录制内容保存为 .avi 文件。

import cv2
from datetime import datetime
import time


vid_capture = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')

ret, cur_frame = vid_capture.read()
prev_frame = cur_frame

capture_duration = 10
motion = False

while True:    
    frame_diff = cv2.absdiff(cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY), cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY))

    if frame_diff.max() > 150:
        motion = True

    if motion:
        start_time = time.time()
        name = str(datetime.now().date()) + "_" + str(datetime.now().time().hour) + "-" + str(datetime.now().time().minute) + "-" + str(datetime.now().time().second) + ".avi"
        out = cv2.VideoWriter(name, fourcc, 20.0, (640,480))
        ret, cur_frame = vid_capture.read()

        while time.time() - start_time < capture_duration:
            if ret:
                out.write(cur_frame)
                cv2.imshow('Input', cur_frame)

            else:
                break
        
        out.release()
        cv2.destroyAllWindows()

    motion = False

    prev_frame = cur_frame.copy()
    ret, cur_frame = vid_capture.read()

    if cv2.waitKey(1) == 27:
        break
    
vid_capture.release()

So Im trying to make my webcam capture motion, and I how to register motion is going fine but with all these nested while loops my save files are dragged to 30 min long and not 10 sec like intended. I can't figure out what Im doing wrong.

What I mean by dragged out is that I record for 10 sec, but when I go into my files to review the footage it's 30 mins of just some frames.

The idea is to make it register motion and then record for 10 seconds and save the recording as a .avi file.

import cv2
from datetime import datetime
import time


vid_capture = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')

ret, cur_frame = vid_capture.read()
prev_frame = cur_frame

capture_duration = 10
motion = False

while True:    
    frame_diff = cv2.absdiff(cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY), cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY))

    if frame_diff.max() > 150:
        motion = True

    if motion:
        start_time = time.time()
        name = str(datetime.now().date()) + "_" + str(datetime.now().time().hour) + "-" + str(datetime.now().time().minute) + "-" + str(datetime.now().time().second) + ".avi"
        out = cv2.VideoWriter(name, fourcc, 20.0, (640,480))
        ret, cur_frame = vid_capture.read()

        while time.time() - start_time < capture_duration:
            if ret:
                out.write(cur_frame)
                cv2.imshow('Input', cur_frame)

            else:
                break
        
        out.release()
        cv2.destroyAllWindows()

    motion = False

    prev_frame = cur_frame.copy()
    ret, cur_frame = vid_capture.read()

    if cv2.waitKey(1) == 27:
        break
    
vid_capture.release()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梓梦 2025-01-19 14:58:36

您的代码可能运行得非常快,并且可能会创建 ie.每秒 100 帧。

但是 VideoWriter 中的 20.0 不会以每秒 20 帧的速度写入视频,而只是通知播放器必须每秒显示 20 帧。但如果每秒创建 100 帧,那么最终将需要 5 秒而不是 1 秒来显示它 (100frames/20FPS = 5seconds)。

您必须放慢速度,每50ms创建新帧 - (1000ms/20FPS) - 您可以尝试waitKey(50)

编辑:

因为代码可能需要一些时间来创建框架,所以它可能需要 waitKey 中较小的交易 - 即 48 - 或者您可以尝试测量循环内的时间并使用

waitKey( 50 - (loop_end-loop_start) )

您运行内部 while 循环,该循环始终写入同一帧 - 您应该在此 内使用 ret, cur_frame = vid_capture.read() >while-循环


较短:

name = datetime.now().strftime("%Y-%m-%d_%H-%M-%S.avi")
motion = (frame_diff.max() > 150) 

I看到一个可能的问题:窗口关闭时,cv2.waitKey 不起作用 - 因为系统仅向活动窗口发送键/鼠标事件,而当窗口关闭时,cv2 可能不起作用获取按键/鼠标事件。


from datetime import datetime
import time
import cv2

vid_capture = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')

ret, cur_frame = vid_capture.read()
prev_frame = cur_frame

capture_duration = 10

while True:    
    frame_diff = cv2.absdiff(cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY), cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY))

    motion = (frame_diff.max() > 150) 

    if motion:
        name = datetime.now().strftime("%Y-%m-%d_%H-%M-%S.avi")
        print(name)
        
        out = cv2.VideoWriter(name, fourcc, 20.0, (640,480))

        start_time = time.time()
        while time.time() - start_time <= capture_duration:
            ret, cur_frame = vid_capture.read()
            if ret:
                out.write(cur_frame)
                cv2.imshow(name, cur_frame)
                if cv2.waitKey(50) == 27:
                    break
            else:
                break
        
        out.release()
        cv2.destroyAllWindows()

    prev_frame = cur_frame.copy()
    ret, cur_frame = vid_capture.read()

    if cv2.waitKey(1) == 27:
        break
    
vid_capture.release()

Your code may run very fast and it may create ie. 100 frames every second.

But 20.0 in VideoWriter doesn't write it video with speed 20 frames per second but it only inform players that they have to display 20 frames per second. But if you create 100 frames per second so finally it wll need 5 seconds instead of 1 second to display it (100frames/20FPS = 5seconds).

You have to slow down to create new frame every 50ms - (1000ms/20FPS) - you can try waitKey(50).

EDIT:

Because code may need some time to create frame so it may need little smaller dealy in waitKey - i.e. 48 - or you may try to measure time inside loop and use

waitKey( 50 - (loop_end-loop_start) )

You run inner while-loop which all time write the same frame - you should use ret, cur_frame = vid_capture.read() inside this while-loop


Shorter:

name = datetime.now().strftime("%Y-%m-%d_%H-%M-%S.avi")
motion = (frame_diff.max() > 150) 

I see one possible problem: cv2.waitKey not work when window is closed - because system sends keys/mouse events only to active window, and when window is closed then cv2 may not get keys/mouse events.


from datetime import datetime
import time
import cv2

vid_capture = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')

ret, cur_frame = vid_capture.read()
prev_frame = cur_frame

capture_duration = 10

while True:    
    frame_diff = cv2.absdiff(cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY), cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY))

    motion = (frame_diff.max() > 150) 

    if motion:
        name = datetime.now().strftime("%Y-%m-%d_%H-%M-%S.avi")
        print(name)
        
        out = cv2.VideoWriter(name, fourcc, 20.0, (640,480))

        start_time = time.time()
        while time.time() - start_time <= capture_duration:
            ret, cur_frame = vid_capture.read()
            if ret:
                out.write(cur_frame)
                cv2.imshow(name, cur_frame)
                if cv2.waitKey(50) == 27:
                    break
            else:
                break
        
        out.release()
        cv2.destroyAllWindows()

    prev_frame = cur_frame.copy()
    ret, cur_frame = vid_capture.read()

    if cv2.waitKey(1) == 27:
        break
    
vid_capture.release()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文