Alright, so I've got my motion detection program running here and as
you see this is capturing me moving at the moment. if I move away you can only
see some shadows there and so this is great but as I said you may want to
store the times when an object enters the frame so that you end up with
something like this. So this is the first entrance
as the start time and here is where the object exited the frame and then the second
entrance of the object and so on. So in this lecture I'll show you how to build to
that table using this script so we will add some more code here. The way to start
doing this is to first figure out the point, the line in the script where the
status is changing from let's say motion to no motion has, so we have no
motion in here so as soon as webcam triggers let's say the status is zero so
just a similar time choosing to denote that there's no motion in the current
frame, so then you get that first frame which has a status of zero and then you
grade out and then you check if the first frame is None, and then you
continue the loop again, and then you grab the second frame so the status is
still zero when you apply the difference, the threshold, and the dilate, and then iterate
through contours. So if you find an area that is less than, I change this earlier I put it
10,000 so I wanted to detect bigger objects because I was closer to the
camera so I wanted to adjust it. So depending on what objects
you want to capture you want to adjust these pixels here.
So 10 000 is something like 100 by 100 pixels window so we are checking if you
don't find a window that is bigger than 10 000 then you continue to the
beginning of the loop until you find a contour with this size
bigger than this. When python finds that contour with that size we want to change
the status to 1. Okay, and let us now print out that status variable, so what
you want to do is print it at the end of your loop, so status. Let me delete these
Numpy arrays which are being printed. We don't need those and make some room here.
So this is inside the loop and I now expect to see the status of 1 or 0
printed out depending on whether there is an object in the frame or not, so if
this is working that means we now have the actual status of the frame and we can
use that not 1 or 0 for other things, so let's see. Okay, there's nothing at the
moment. Let me minimize this so we can see the console. This is well, great.
So 0 is being printed out and if something shows up now you see ones.
Again 1, 0, 1, 1, 0, great. We can now simply apply a date-time
method, you know such as datetime.now. That would record the time of each frame
so we don't want that exactly, we want to use the datetime method, but not
like that because that would record times for every frame, so what we
want instead is we want to know when the status changes from 0 to 1 which
indicates that there is an object entering the frame, so we want to record
that time and we also want to record the other time when the status changes from
1 to 0, so the object exits the frame. Let's say status list that will be equal
to empty brackets, so an empty list and then I want to append the status of the
object to that list. So after this loop finishes which is here,
so I want to be here the same level with the loop, so I want to apply something
outside the loop. So status list.
I want to append the current status of the list here, in the status list, great.
And to illustrate to show you what this status list is a about, I would like to
print this out actually. And I would want to print out a list outside the while
loop so and don't want to print out every time the loop iterates.
So no movement, movement here, and quit. So this are the statuses for each of
the frames so 0, 0, 0 no movement, and then something entered the frame and that's
something entered like let's say 30 frames, and then the object exits the frame
frame, and that's it. So what we want to do now is we want to capture…
So what's next? So the next thing is we want to capture
the time that we switch from 0 to 1 and also from 1 to 0, so basically what we're
interested about is to capture the lost two items of the status list, so let's
say we have status 0, so we start with an empty list. The first item that will
be appended to the status list is 0 and then a second item let's say will be 0,
or let's say we'll do 1 and so we want to apply a conditional to check whether
the last two items of release are changing. So I know this may be confusing
but once I ride this four lines of code here you'll understand it and it will
make a lot of sense. So we want to check if status list, so the last item of the
status list which has an index of minus 1 remember list indexing, if that is
equal to 1 and status_list with index of minus 2, so the item that was added first
the item that was added a second is equal to 0, we want to record the
datetime of this event in the list. So let's create a list here. Say times equals
empty and then we go here, here and say times dot append datetime.now.
You know about this function already. So we want to append the current timestamp
when this change occurred, so that means we need to import. From datetime
import datetime, so datetime class from the datetime library.
So we're basically recording the time when the status changed to 1 and we also
want to record the time when the status changes from 1 to 0, so we would have
a similar conditional, but this would be 0. And this would be 1, okay. So what's
happening here is let's go back to the start of the loop, so python captured the
first frame and it converts it to gray, and blurs it,
and applies a Gaussian blur there to the first frame and then we store the first
frame in the first frame variable, and then we go ahead and calculate the
difference between the first frame and the current frame. Find contours and then
if this loop finds contours greater than 10 000, the statu variable changes from 0,
so it started at 0 so it changes at 1 here. And that means this empty status
list will get another value, but the first value is always 0 so the list will
start with 0, you know, like here so the very first value is 0 and so on. Let's
say for the next 10 frames it will be 0, 0, 0, 0, and so on. And then if an object
enters the frame and then status changes to 1 so we'll have 0, 0, 0, 0, and then 1,
and then what we're doing here we're comparing the last two items of
the list, okay. And here I would like to print out the times list so that you see
what's going on. And I expect to get an error at the first execution here
because we have something more to do, but let's see. So yeah it says list index is
out of range, so that means Python is having trouble accessing the second
item of the list because the list has no items here, so it has no items, and then
we add an item, so we add status, and then Python tries to find the second item, but
there is no second item. So we need to do a trick here. We need to add two items, okay.
Let's say none and none. Now let's execute the script again, so there's no object there
at the moment. Now an object appears. It goes out again. Two times, and one more
time, so three entrances, and I quit it. So let me go through this list now, this
is our times list, and so this is the time, so the year, the month, the day,
and hour, minutes, and seconds, and then microseconds in here. So this is the
start time when an object entered the frame for the first time, and then this
is the time when the object exits in frame, so I stayed there for two seconds,
so 51 up to 53, and then the next object enter the frame, so from these seconds to
these, so for two other seconds, and then another third time
from zero to one for one second. So we've got three entrances in the frame.
So I hope that makes sense! This is good, but sometimes see it can happen
that when you're running the script so you have background, then object shows,
and the object disappears, then shows again. And if you quit the program at this
point, so let me quit it, you'll see that you have the start time here for the
first entrance, then the end time, and then you have another start time here for the
second entrance, but then you don't have an exit time, so you may want to add the
time of the exit of your last object which happens to be when
that window was quit. So you want to go here at the end, and the script is waiting for
a key so if you press quit here the while loop will break, but before that you may
want to check the status. So if status is one, and in that case you
would end up with this scenario here, so if status is one when you press the Q
key from the keyboard, you want to add another item to your time list. So times append
datetime.now. Great, so that should work differently now, so let's
execute the script. No object, object, no object, object in the frame, quit, and now we
should have four datetimes here. Four timestamps, 1, 2, 3, and 4.
So this here was recorded in this expression here, great.
And the next thing we want to do now is to throw this list into a Pandas data
frame and then into a csv file. So we'll have a start and an end column
and in the start column we would have for instance this value,
and in the end column we would have the other value, so this one here and the
last one, this. Okay so first of all we need an empty data frame, the Pandas
data frame, so we'll be using Pandas to create data frames of course, so let me
import Pandas here and let's say data frame df equals to Pandas dot data frame
with columns "Start" and "End", as easy as that, so that will create a data frame
structure for us which has no values, but it has two columns and then the next
thing you want to do is outside the loop, so once you have created, once you have
generated your times list you want to iterate through that list and then
append those values into the pandas dataframe, so you need a loop. Let's say
for i in range, and so here you'd have to iterate with a step of two and
you'd want to iterate as many times as there are values in the list so you
start from zero and then you'd end up at how many values you have in the list. Well you
can find that using the length method, so length times with a step of 2.
Great, so and that would be, so for each iteration df, so the data frame will be
equal to itself dot append, so you are updating the data frame and here you'd
need to pass a dictionary, so for the start column,
you'd want to enter times I, and for the end column, so the keys of the dictionary
are stored, and end and you'd want to append times i plus one, and you want to
ignore index, so equal to true. Great, so what this is doing is let's say for i in
range this would be, let's say we have a list with six items so we have three
start times and three end times. So that'll mean a range 0 to 6 with a step of 2, so for 0 we
would do this, so we'd start from 0 in the loop and we would access the item with the
zero index in times which happens to be this item for instance, so the first item.
And then we append that item to the first row of the start column, and then
we access the item 0 + 1 which happens to be item with index 1 which should be
this item, so the second item, and we append that item to the end column for
the same row, so that's it. Then we go to the next item.
So for, so this time we would start with index 3, so 3 here add it to the start
column and then 4 add it to the start column, to the end column, sorry, and so on.
And lastly we would have a data frame and what you might want to do then is
df.tocsv. Let's say times.csv, so we are exporting the data frame to a CSV
file, great, so let's see how this will go. It's getting quite dark here, okay. And one
more time, three, quit, and as you see times.csv was created in my file system, so these
are the times. I can also open it using Excel, so these are the start and end times.
If you want you can format them. Just format cells here and you can see
the date now, great. Great, so that ends this lecture. I hope you enjoyed it.
We have quite a good script now, and to make it more beautiful we would want to
display these times in a graph, so that's how you turn your data into real
information, and we'll do that through the next lectures, but before I'd like to
introduce you to the Bokeh library which is a library for interactive
visualizations in the browser, so please follow the lectures in the correct order
and I'm sure you will learn a lot. Talk to you later!