简体   繁体   English

Python方式记录while循环内的更改

[英]Pythonic way to record changes inside a while loop

I have a Python script that triggers the computer webcam and is able to detect movement in the video being captured using opencv. 我有一个Python脚本,可以触发计算机网络摄像头,并且能够检测使用opencv捕获的视频中的运动。

The way it works is Python reads the very first frame of the video and stores it as a numpy array in a variable. 它的工作方式是Python读取视频的第一帧并将其作为numpy数组存储在变量中。 Then, there is a while loop running in the script that basically compares the first video frame with each current frame of the video. 然后,脚本中将运行一个while循环,该循环基本上将第一个视频帧与视频的每个当前帧进行比较。 There are around 30 frames every second being iterated in the loop. 循环中每秒大约循环30帧。 When the current frame is different than the first frame, I update a variable inside the while loop by assigning the value 1 to it. 当当前帧与第一帧不同时,我在while循环中通过为其分配值1来更新变量。 So, as the loop goes on, you may have 0, 0, 0 and then 1, 1, 1, 1 depending on whether there is motion or not. 因此,随着循环的进行,您可能有0、0、0,然后有1、1、1、1,这取决于是否有运动。 My purpose is to record the time when motion starts. 我的目的是记录运动开始的时间。 In other words, the time when my variable changes from 0 to 1. 换句话说,我的变量从0变为1的时间。

Here is my pseudo code: 这是我的伪代码:

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())

So, at the end I have a time_list with all times when motion started. 因此,最后我有了一个time_list,其中包含运动开始时的所有时间。

Is this a good solution or am I missing something here? 这是一个好的解决方案,还是我在这里错过了什么?

Update: 更新:

First suggestion: 第一条建议:

There are few improvements you could do, especially if, as it is often in practice (but not necessarily), you intend to run your application on Raspberry Pi . 您可以做的改进很少,特别是如果您打算在Raspberry Pi上运行您的应用程序时(但不一定),通常会这样做。

In total, there are 4 cases to consider about and that your program must cover them all: 总共要考虑4种情况,您的程序必须涵盖所有这些情况:

  1. No motion: ⇢ ⓪ ⇢ ⓪ ⇢ ⓪ ⇢ 不动:motion⇢⓪⇢⓪

  2. Continuous motion: ⇢ ❶ ⇢ ❶ ⇢ ❶ ⇢ 连续运动:motion⇢❶⇢❶

  3. From no motion to motion: ⓪ ⇢ ❶ 从一动不动:⓪⓪❶

  4. From motion to no motion: ❶ ⇢ ⓪ 从运动到不运动:❶⇢⓪

The only time to register is the one described by the case 3; 唯一的注册时间是案例3所述的时间; while during the motion (case 2), we won't care about the time. 而在运动过程中(案例2),我们不会在乎时间。

To resolve this, I suppose , previous to the while loop: 为了解决这个问题,我想在while循环之前:

  • You saved first_frame somewhere 您将first_frame保存在某处
  • You set my_variable to 0 您将my_variable设置为0

Here is the pseudocode: 这是伪代码:

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

Notes: 笔记:

  1. For the sake of performance, it is better to test cases 1 and 2 before the rest as, in practice, they occur more frequently than the two other cases. 为了提高性能,最好在其余情况之前先测试案例1和2,因为实际上它们比其他两个案例更频繁地出现。 So by running continue you avoid wasting time in checking cases 3 and 4 which are less frequent. 因此,通过继续运行,您可以避免浪费时间检查不太常见的情况3和4。
  2. We got rid of motion_list and not need to allocate a memory for this list anymore because my_variable plays the role of a flag and it satisfies your need when by re-setting its value to 0 or 1 in the last two cases. 我们摆脱了motion_list并且不再需要为此列表分配内存,因为my_variable充当标志的角色,并且在最后两种情况下将其值重新设置为01可以满足您的需要。

Second suggestion: 第二个建议:

If you are not doing this application as a university project but for more practical/commercial reasons, you may think of this improvement: as reading frames from camera is an I/O bound task, you may be interested in increasing webcam FPS (and more probably in increasing Raspberry Pi FPS ) 如果您不是将本应用程序作为大学项目来进行,而是出于更实际/商业的原因,您可能会想到这种改进:由于从摄像头读取帧是一项I / O绑定任务,因此您可能会对提高摄像头FPS感兴趣(更多可能会增加Raspberry Pi FPS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM