1
00:00:00,030 --> 00:00:06,690
Hi and welcome to this new lecture!
So what I'll do here is I'll give the final

2
00:00:06,690 --> 00:00:13,259
touch to our motion detection program
and specifically I'll build a plot using

3
00:00:13,259 --> 00:00:17,940
the Bokeh library and where I'm
visualize the times that the object

4
00:00:17,940 --> 00:00:23,760
enters and exits the frame, the video
frame and the final output will look

5
00:00:23,760 --> 00:00:31,859
something like this. So what we've got
here is a plot with an x axis which is

6
00:00:31,859 --> 00:00:38,460
ploting the date time, while the y axis
doesn't have any sense actually so a just

7
00:00:38,460 --> 00:00:44,280
a vertical extension of these bars
which is here and so what we've got here

8
00:00:44,280 --> 00:00:53,250
is let's say I started a camera but
these days on 17th of March and so this

9
00:00:53,250 --> 00:00:59,820
first capture here is you can see
started at this date and it ended after

10
00:00:59,820 --> 00:01:05,010
4 seconds, so this object entered the
frame if that's all date and stayed for

11
00:01:05,010 --> 00:01:10,710
4 seconds there and then exited
the video frame, so similarly we have

12
00:01:10,710 --> 00:01:20,100
this other object so still on 17th of
March and then we've got this other here.

13
00:01:20,100 --> 00:01:26,790
And then here start the other day so
18th of March and these are the hours

14
00:01:26,790 --> 00:01:35,040
between these days so 4 o'clock, 8, 12, 16,
and 20. And you can also see that I have

15
00:01:35,040 --> 00:01:39,869
added however capabilities here so that
when I hover the mouse over these bars

16
00:01:39,869 --> 00:01:46,049
I get this information. And you can also
zoom in here so if you want more

17
00:01:46,049 --> 00:01:52,590
information about this, you can see the
information quickly over here so that's the

18
00:01:52,590 --> 00:01:59,790
product. Now what the scrip is doing at
the moment is it is producing the start time

19
00:01:59,790 --> 00:02:05,399
and the end time of the object entering
the frame in a CSV file, so specifically

20
00:02:05,399 --> 00:02:13,140
the program is triggering the video from
the webcam and then you got some objects

21
00:02:13,140 --> 00:02:15,470
in there.
Press Q for quitting and so what you get

22
00:02:26,640 --> 00:02:35,280
is this times.csv where each row
represents the start time and

23
00:02:35,280 --> 00:02:41,490
the end time. Okay, you know this already and
so at the moment what we've got here is

24
00:02:41,490 --> 00:02:49,410
also a list with a status of the
current frame, so this s let's say 100

25
00:02:49,410 --> 00:02:57,420
items so that means we had 100 frames in
this seven second video. Now the first

26
00:02:57,420 --> 00:03:05,370
thing you may want to do is a small
improvement here very quickly. This list

27
00:03:05,370 --> 00:03:10,020
if you're having a webcam captured a
long video, so if you're running it for

28
00:03:10,020 --> 00:03:14,480
many hours,
this means this list may get too big

29
00:03:14,480 --> 00:03:23,190
so to avoid memory problems you may want
to go here, so here you're checking the

30
00:03:23,190 --> 00:03:28,230
last item of the list and the item
before the last item, so the last two

31
00:03:28,230 --> 00:03:36,360
items. That means we don't need these
other items, so we only need to keep two

32
00:03:36,360 --> 00:03:47,760
last items only. That means just after we
append the new status here, so we say

33
00:03:47,760 --> 00:03:58,680
status list equals to status list but
with only the last two items, so if I

34
00:03:58,680 --> 00:04:04,860
execute this now what I'll get is only
the last two statuses of the video

35
00:04:04,860 --> 00:04:11,940
frame printed all this a list, so the list
is printing here. So that's

36
00:04:11,940 --> 00:04:17,850
an improvement for the sake of memory.
Now how do we get around to building a

37
00:04:17,850 --> 00:04:24,960
plot with Bokeh? So first we have to
think about the structure of our script.

38
00:04:24,960 --> 00:04:31,590
So this plotting object that will be
creating using a quadrant, so this will

39
00:04:31,590 --> 00:04:36,360
expect a data frame to be sent as an
input so we actually have a data frame

40
00:04:36,360 --> 00:04:49,470
here and we are sending that data frame
to the times.csv file. What I'll do here

41
00:04:49,470 --> 00:04:57,360
is I'd create another file so the
Python script say plotting.py.

42
00:04:57,360 --> 00:05:04,320
Here is where I'd write the script,
the code for plotting the data. In that case

43
00:05:04,320 --> 00:05:11,910
that means we need to fetch the data
frame of this motion detector program to

44
00:05:11,910 --> 00:05:20,910
this script, so what you can do is you
want to say from motion detector import

45
00:05:20,910 --> 00:05:26,970
df so that will make available the df
data frame that is being generated in

46
00:05:26,970 --> 00:05:32,880
this motion detector program, which means
the way you when you want to run the

47
00:05:32,880 --> 00:05:38,490
program later you'll be running the
plotting.py with Python, and so when you

48
00:05:38,490 --> 00:05:44,370
execute plotting.py, plotting.py
will call for execution this motion

49
00:05:44,370 --> 00:05:52,349
detected dot py script, so the video
from webcam will start and then when

50
00:05:52,349 --> 00:05:59,130
these loops and this data frame will be
generated. That means after that the

51
00:05:59,130 --> 00:06:04,139
script, the code of the plotting.py
will be executed. So here you'll be

52
00:06:04,139 --> 00:06:10,590
getting the data frame and putting in
and so on. I hope that is clear, so let's

53
00:06:10,590 --> 00:06:15,810
go ahead now and import the plotting
interface of Bokeh, so from bokeh.plotting,

54
00:06:15,810 --> 00:06:21,360
actually we will not be importing
the entire plotting interface.

55
00:06:21,360 --> 00:06:32,940
We only need figure, show
and output_file. Let's keep it tight

56
00:06:32,940 --> 00:06:43,040
there, and then let's go ahead and
create the figure object, and x_axis type

57
00:06:43,040 --> 00:06:55,140
will be of type datetime. Let's set the
height of 100 and the width of 500

58
00:06:55,140 --> 00:07:13,140
and let's make it responsive. Title
of the graph, motion graph. Okay, so once we

59
00:07:13,140 --> 00:07:20,010
have a figure there we want to plot
a glyph in that figure and that glyph in this

60
00:07:20,010 --> 00:07:26,280
case would be a quadrant, so quad so
a quadrant would be more appropriate to

61
00:07:26,280 --> 00:07:32,340
close this time intervals there, and so
the trick to have this quad glyph to

62
00:07:32,340 --> 00:07:40,470
visualize your date and your times along
this x-axis is to pass left, right, bottom,

63
00:07:40,470 --> 00:07:50,250
and top parameters. So for left you'd
want to pass the start time, so left of

64
00:07:50,250 --> 00:07:58,560
the box of these boxes that you see here.
So the left border would be the start

65
00:07:58,560 --> 00:08:10,140
time, while the right border so df would
be the end time. So here is our CSV which

66
00:08:10,140 --> 00:08:17,670
is not what we are using but this is the
structure of the data, so start time on

67
00:08:17,670 --> 00:08:22,710
the left and then end time on the border
in the right of the rectangle, of the

68
00:08:22,710 --> 00:08:29,130
quadrant, and then here is the trick we
can do. For bottom we want to keep

69
00:08:29,130 --> 00:08:38,100
a fixed value, so 0 for every quadrant and
then 1 for every quadrant as well.

70
00:08:38,100 --> 00:08:43,979
And that's it. Color it's not
a problem, let's say green, and I'd

71
00:08:43,979 --> 00:08:55,380
like to try this for now, so output_file.
That would be Graph.html.

72
00:08:55,380 --> 00:09:04,140
And show the p figure, and let's see what
is going to happen this far.

73
00:09:04,140 --> 00:09:08,280
So Python and we don't want to execute
motion detector now, but we want to

74
00:09:08,280 --> 00:09:21,060
execute plotting.py, so that's our
main script where we get started, and I've

75
00:09:21,060 --> 00:09:27,000
got a stupid syntax error here from
Bokeh plotting figure. I bet he knew it

76
00:09:27,000 --> 00:09:32,700
that I need the import keyword here so
from Bokeh.plotting import figure show for

77
00:09:32,700 --> 00:09:46,580
file, save and try again. And here is the
webcam. Object, object again, another time.

78
00:09:46,580 --> 00:09:54,980
Quit and let's see what is gonna happen
now, and yet another error. Responsive.

79
00:09:54,980 --> 00:10:05,970
Good. Sorry about that!
Try again. First object, second object

80
00:10:05,970 --> 00:10:15,960
there, and one more, quit. And we should
see the graph, yeah it's looking good.

81
00:10:15,960 --> 00:10:23,400
So I can see here and you can also
notice that we've got quite unnecessary

82
00:10:23,400 --> 00:10:29,900
granularity here, so we don't
need all these stickers here and also

83
00:10:29,900 --> 00:10:35,790
you can see here that this says
19 seconds

84
00:10:35,790 --> 00:10:41,810
which means that it's 19 seconds past
the last minute, so if it was let's say

85
00:10:41,810 --> 00:10:50,520
15 minutes and 19 seconds so 20 seconds
of the 15 minute and so on. So you

86
00:10:50,520 --> 00:10:54,610
don't really see the big picture in just
10 seconds of video.

87
00:10:54,610 --> 00:11:00,910
But also to make it more informative I
would add over to this bar so that

88
00:11:00,910 --> 00:11:07,089
when I run over the mouse here as you know
you should see the start and end time so

89
00:11:07,089 --> 00:11:12,360
that you can see the complete time there
if the labels here are not enough.

90
00:11:12,360 --> 00:11:21,009
But first let's remove these stickers
here, so we go back to the script and let

91
00:11:21,009 --> 00:11:26,259
me put this down, and the way to do that
would be we need to modify the figure

92
00:11:26,259 --> 00:11:34,959
object, so the P variable, and so we're
working on the y-axis, so Y axis, so we

93
00:11:34,959 --> 00:11:46,239
access the y-axis object of the figure
object, then minor tick color, and we want

94
00:11:46,239 --> 00:11:55,869
to set it to none so these ticks here.
Also you can see that we also have

95
00:11:55,869 --> 00:12:00,279
a grid, so we don't want this
intermediate lines here.

96
00:12:00,279 --> 00:12:09,309
And we can do that by accessing the grid
object which is a list, so you need to

97
00:12:09,309 --> 00:12:13,989
access the first item of the list, so
that's quite a trick there, but you have

98
00:12:13,989 --> 00:12:24,549
to make peace with that. So ticker say
desired number of ticks, so that's the

99
00:12:24,549 --> 00:12:33,369
method and set it to one. So let's see
how the graph has changed this time.

100
00:12:33,369 --> 00:12:38,319
And it's a good idea to put the graph
another name so that we compare the two

101
00:12:38,319 --> 00:12:51,269
graphs, so graph one for this, and let's
see. Here, yeah.

102
00:12:51,700 --> 00:13:04,580
And quit, and I've got an attribute error
Minor tick color. I tend to put this wrongly.

103
00:13:04,580 --> 00:13:10,820
The good thing is Bokeh has quite a good
error handling, so it says similar

104
00:13:13,910 --> 00:13:18,050
it's actually able to read what you
improve there and it suggests you what

105
00:13:18,050 --> 00:13:27,940
to imput, so minor tick line color.
So we've got a line here. So try again.

106
00:13:33,880 --> 00:13:43,070
Let's see this time what we get. So now
it looks cleaner as you can see. Here is

107
00:13:43,070 --> 00:13:48,220
our previous graph, this is the new one.
So we don't have the horizontal gridlines

108
00:13:48,220 --> 00:13:56,180
and the ticks in here, and I thought of
stopping this lecture at this point and

109
00:13:56,180 --> 00:14:01,370
in the other lecture I'll show you how to
add these hover capabilities to your

110
00:14:01,370 --> 00:14:05,000
graph, so I'll talk to you
in the next lecture.

