在while循环中记录更改的Pythonic方法

在while循环中记录更改的Pythonic方法,python,list,while-loop,Python,List,While Loop,我有一个Python脚本,可以触发计算机网络摄像头,并且能够检测使用opencv捕获的视频中的运动 它的工作方式是Python读取视频的第一帧,并将其作为numpy数组存储在变量中。然后,在脚本中运行一个while循环,基本上将第一个视频帧与视频的每个当前帧进行比较。循环中每秒迭代大约30帧。当当前帧与第一帧不同时,我通过为其赋值1来更新while循环中的变量。因此,随着循环的进行,根据是否存在运动,可能会有0,0,0,然后是1,1,1,1。 我的目的是记录运动开始的时间。换句话说,变量从0变为

我有一个Python脚本,可以触发计算机网络摄像头,并且能够检测使用opencv捕获的视频中的运动

它的工作方式是Python读取视频的第一帧,并将其作为numpy数组存储在变量中。然后,在脚本中运行一个while循环,基本上将第一个视频帧与视频的每个当前帧进行比较。循环中每秒迭代大约30帧。当当前帧与第一帧不同时,我通过为其赋值1来更新while循环中的变量。因此,随着循环的进行,根据是否存在运动,可能会有0,0,0,然后是1,1,1,1。 我的目的是记录运动开始的时间。换句话说,变量从0变为1的时间

这是我的伪代码:

start webcam
times_list=[]
motion_list=[]
while True:
    my_variable=0
    frame_difference=current_frame - first_frame
    if frame_difference > 0:
        continue
    my_variable=1
    motion_list.append(my_variable)
    #The motion_list will get big, so let's keep only the last two items to avoid memory problems
    #The last two items is all we need.
    #Check if there was a change from non-motion to motion
    if motion_list[-1]==1 and motion_list[-2]==0:
        times_list.append(datetime.datetime.now())
所以,在最后,我有一个时间列表,列出了运动开始的所有时间


这是一个好的解决方案还是我遗漏了什么?

更新:

第一项建议: 您可以做的改进很少,特别是如果您打算在上运行应用程序,这在实践中经常发生(但不一定发生)

总的来说,有4种情况需要考虑,并且你的程序必须覆盖它们:

  • 无动议:⇢ ⓪ ⇢ ⓪ ⇢ ⓪ ⇢

  • 连续运动:⇢ ❶ ⇢ ❶ ⇢ ❶ ⇢

  • 从没有动议到动议:⓪ ⇢ ❶

  • 从动议到不动议:❶ ⇢ ⓪

  • 注册的唯一时间是案例3中描述的时间;在动议(案例2)期间,我们不关心时间

    为了解决这个问题,我想在
    while
    循环之前:

    • 您将
      第一帧
      保存在某个地方
    • 您将
      my\u变量设置为
      0
    以下是伪代码:

    times_list=[]
    my_variable = 0
    while True:
        frame_difference = current_frame - first_frame
        # Case 1:
        if difference_frame == 0 and my_variable == 0:
            continue
        # Case 2:
        if difference_frame != 0 and my_variable == 1:
            continue
        # Case 3:
        if difference_frame != 0 and my_variable == 0:
            my_variable = 1
            # Your comments say this is the only instant you are interested in
            times_list.append(datetime.datetime.now())
        # Case 4:
        if difference_frame == 0 and my_variable == 1:
            my_variable = 0
    
    注意事项:

  • 为了提高性能,最好先测试案例1和案例2,因为在实践中,它们比其他两个案例发生得更频繁。因此,通过运行continue,您可以避免在检查不太频繁的案例3和案例4时浪费时间
  • 我们去掉了
    motion\u list
    ,不再需要为此列表分配内存,因为
    my\u variable
    起到了标志的作用,在最后两种情况下,它通过将其值重新设置为
    0
    1
    来满足您的需要
  • 第二项建议:
    如果您不是作为一个大学项目,而是出于更实际/商业的原因,那么您可能会想到这一改进:因为从相机读取帧是一项I/O绑定任务,您可能会感兴趣(并且更可能感兴趣)

    因此,在您的代码中,如果第一帧与当前帧相同,while循环将重复上述
    继续
    ,而不执行
    now()
    。如果当前帧与第一帧不同,将执行
    now()
    ,while循环将再次迭代,如果下一个当前帧与第一帧仍然不同,则将使用
    now()
    记录另一个时间戳。这意味着,您的代码将在其中包含运动的每个帧上记录一个时间戳。我错了吗?没错。但我想让你的结论(最后一句)更清楚:什么定义了运动的瞬间?答案是:这是一个帧(
    current\u frame
    )与第一个帧不同的时刻。实际上,在while循环中,我使用
    absdiff()
    方法计算帧差,然后应用
    findcontours()
    方法检测帧差的轮廓。然后在while循环中,我有一个for循环,循环遍历轮廓,检查countour区域是否小于某个最小给定区域,如果该区域小于最小区域,则继续操作。Ok。如果我能很好地理解你,你总是将当前帧与相同的第一帧进行比较,对吗@答案的更新版本是有意义的!谢谢你的时间!嗨,今天是周末,所以我有时间陪你:)昨天我们讨论之后,我相应地更新了我的答案。通过您的评论,您似乎只对运动开始时的第一个瞬间感兴趣,而不是对整个运动时间线感兴趣。