People Counting From CCTV Security Camera Footage

One of the data streams being logged for the Sensing SEC platform includes data derived from CCTV footage captured from a number of security cameras located around the QUT campus. The security camera footage is captured and fed into various image tracking algorithms in order to estimate the number of people present in the scene and also the number of people entering/exiting the scenes over time.

The first crowd counting algorithm, known as ‘scene invariant multi-camera crowd counting’ tracks and logs how many people are present in the scene over 10 second intervals, and is computed using the approach of Ryan et al. (as documented here The second approach, known as a ‘virtual gate’ tracks the total number of people passing forwards and backwards across a line (the ‘virtual gate‘), also over 10 second intervals, and this is computed using the method of Denman et al. (see Each camera feed is processed by a virtual machine instance running one of these algorithms, and the results are logged into a text file in a CSV format.

Floor plan of the monitored areas, showing approximate camera locations and landmarks
A floor plan of the monitored areas (QUT Gardens Point – P Block). Approximate camera locations include: approach to the building (C1), covered areas outside the main entrance (C2-C5), two external elevators (C3 and C4), main entrance (C11), The Cube area (C6- C9), internal elevators (C10) and internal stairs (C12)

Thanks to our colleague Dr Simon Denman from the QUT Science and Engineering Faculty for access to the CCTV derived data produced using these algorithms, and the images shown in this post.

Example CCTV analysis log files:

Log File Example for Crowd Counting:


09/22/2015 14:13:15.000, 1.312, 1.008
09/22/2015 14:14:29.000, 1.131, 0.770
09/22/2015 14:15:36.000, 1.418, 0.711
09/22/2015 14:16:41.000, 1.270, 0.630
09/22/2015 14:17:46.000, 1.391, 0.573
09/22/2015 14:18:50.000, 1.210, 0.506
09/22/2015 14:19:55.000, 1.141, 0.484
09/22/2015 14:20:58.000, 0.822, 0.439
09/22/2015 14:22:00.000, 0.888, 0.340

Count – the average number of people in the region in the past 10 seconds
Variance – variance of the estimate

Log File Example for Virtual Gate:


01/27/2016 01:05:55.000, -0.024, 0.001, -0.007, 0.002
01/27/2016 01:06:05.000, -0.085, 0.050, 0.045, 0.084
01/27/2016 01:06:15.000, 0.025, 0.007, 0.067, 0.011
01/27/2016 01:06:26.000, 0.289, 0.118, 0.311, 0.151
01/27/2016 01:06:36.000, 0.458, 0.255, -0.009, 0.442
01/27/2016 01:06:46.000, 0.416, 0.185, 0.266, 0.193
01/27/2016 01:06:56.000, 0.516, 0.324, -0.135, 0.720
01/27/2016 01:07:07.000, 1.393, 0.981, 0.208, 1.263

Count Forward – the number of people entering the gate in the past 10 seconds. The forward direction is defined as the direction that enters the building, lift, stairs, etc.
Variance Forward – the variance of the forward count
Count Backwards – the number of people exiting the gate in the past 10 seconds
Variance Backwards – the variance of the backwards count

A Splunk Universal Forwarder (see is installed and running on each VM, which watches for changes and additions to the data log files, and forwards any new data to a main Splunk instance for indexing and archiving. This data can then be accessed using the Splunk API, using the C# language. The SensingSEC platform has been developed in C# using the .NET WebAPI (, and this allows us to wrap the Splunk API calls in WebAPI Controller objects, which can then be queried via a web browser using a simple REST interface.

Example REST calls for accessing CCTV count and virtual gate data through the SensingSEC portal:

The data records logged in Splunk contain the IP address of each host machine performing the people counting and logging for each camera. A unique zone ID is also appended to the data which identifies each camera. In order to provide a nice, readable description of the camera location associated with each unique zone and host IP address, a JSON data structure was created defining the mapping of camera location (e.g. QUT GP P4 – Outside Kindler Theatre) to each zone. Other related information can also be stored in this structure. This JSON data is stored in a data collection stored within a MongoDB database, which can then be queried and retrieved over the network. Currently we use this information to populate a select box with camera locations for the user to select which camera they are interested in, and also to annotate visualisations produced using the data.

Example JSON record, mapping a zone ID and location to the actual VM host IP address:

  "zone" : "QUT-GP-P-Cube-MainEntrance",
  "location" : "QUT GP P4 - Cube main entrance",
  "info" : "Virtual gate. Main entrance, and the internal stairs to P level 5",
  "type" : "CCTV",
  "hosts" : [
      "host_ip" : "",
      "host_name" : ""

Splunk Configuration

The Splunk forwarder is a lightweight, dedicated version of Splunk that contains only the components required to forward data to a Splunk indexer instance. Each crowd counting VM has a forwarder installed which is configured to process the CSV data log format, in addition to specifying other information such as the timezone format of time stamps, and tagging records with an appropriate camera zone ID (which is then used as the key to access the additional data stored within the MongoDB collection). The primary Splunk forwarder configuration files used to achieve this are props.conf and transforms.conf.


FIELD_NAMES = _time,enter_count,total_enter_count,exit_count,total_exit_count
TRANSFORMS-zone1 = zone_transform

The TRANSFORMS entry in props.conf references a stanza (i.e. zone_transform) in the accompanying transforms.conf file, which appends the correct zone ID for the camera/VM in question. An extraction is then setup on the Splunk indexer, through the dashboard, to extract the zone as a field that can be referenced or filtered by directly in a search.


FORMAT=$1 zone:QUT-GP-P4-MainEntrance

To append additional data such as the zone ID to the data ingested by the forwarder, a regex entry matches the entire original record, then the FORMAT entry appends the zone ID and stores it back into the _raw field for extraction as a field accessible at search time.