Skip to content

Commit

Permalink
Development (#6)
Browse files Browse the repository at this point in the history
* First prep-work for client AND server-side ImageDetectorPlugins

* Callback for image detector plugins added

* Callback logic now manages to correctly identify client and server

* Enabling Docker Support (#5)

* Initial dockerfile version

* Bugfixes around unit-testing for move to REQ/REP pattern and addtl logging

* Further bugfixes w/ detection threshold, new default warning files

* docker-compose

* Various Docker updates of unknown origins ¯\_(ツ)_/¯

* Audio plugin working w/ docker

* Changelog update
  • Loading branch information
chollinger93 authored Dec 14, 2020
1 parent d2d5df0 commit 9294828
Show file tree
Hide file tree
Showing 29 changed files with 408 additions and 108 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
ssd_inception*
resources/videos/*.mp3
resources/videos/*.mp4
resources/audio_files/*.mp3
.vscode/
blog_snapshots/*
sbin/debian-scripts/
Expand All @@ -13,6 +12,9 @@ notebooks/*test*.ipynb
*tmp*
conf/config.ini
conf/plugins.d/*.ini
releases/
test_conf/
resources/*.tar.gz

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
All changes to the project are documented here.

## [Unreleased]
- Switch to vidgear_async for better performance
- pyPI release
- Cleaning up model dependencies from path
- Motion detection code on client to cut down on network bandwidth

## [0.5] - 2020-12-14
* Support for easier `Docker` deployment out-of-the-box
* Changed subscriber model to `REQ/REP`
* Simplified path management using `Docker`
* Simplified logging
* Various bugfixes

## [0.4.2] - 2020-10-04
* Added support for client plugin callbacks

## [0.4.1] - 2020-08-07

Expand Down
41 changes: 41 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM python:3.8-buster


# Volumes
VOLUME /config
VOLUME /models
VOLUME /data

# ZMQ
EXPOSE 5454
# Audio
EXPOSE 5557

# Dir
WORKDIR /tmp

# Copy setup
COPY README.md ./
COPY setup.py ./
COPY sbin/ ./sbin/
COPY scarecrow_server/ ./scarecrow_server/
COPY scarecrow_client/ ./scarecrow_client/
COPY scarecrow_core/ ./scarecrow_core/
COPY models/ ./models/

# Install protoc
RUN apt-get update
RUN apt-get install -y protobuf-compiler alsa-utils

# Update pip
RUN pip install --upgrade pip
RUN pip install wheel

# Run setup
RUN pip install . --upgrade

# Install the models manually to ensure protobuf works
RUN bash ./sbin/install_tensorflow_models.sh

# Start
ENTRYPOINT ["/usr/local/bin/python3"]
9 changes: 9 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ pip3 install wheel
pip3 install . --upgrade
```

# Using Docker (recommended)

![Docker](./docs/horizontal-logo-monochromatic-white.png)

Using `Docker` is the preferred way of running `scarecrow`, as it handles dependencies internally and operates within a controllable environment.

**Please see [README.md](README.md) for details**


# Manual
If for some reason, the `setup.py` does not work, the steps below show the manual installation route.

Expand Down
97 changes: 75 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Based on the detection criteria, a **plugin model** allows to trigger downstream

*Based on my [blog](https://chollinger.com/blog/2019/12/tensorflow-on-edge-or-building-a-smart-security-camera-with-a-raspberry-pi/).*

## Architecture
# Architecture
![Architecture](./docs/architecture.png)

![Sample](./docs/cam_1.png)
Expand All @@ -16,58 +16,111 @@ Based on the detection criteria, a **plugin model** allows to trigger downstream

*You can change this behavior by relying on a local `tensorflor` instance and having the `ZMQ` communication run over `localhost`.*

## Updates
# Updates
Please see [CHANGELOG.md](./CHANGELOG.md) for details.

# Configuration and data

Copy `config/config.ini.sample` to `conf/config.ini` with the settings for your Raspberry and server.

For playing audio, please adjust `conf/plugins.d/audio.ini`.

```
[Audio]
Path=../audio_files
```
For an appropriate path.

If you want to change the `model`, please check the [Model Zoo](https://github.com/chollinger93/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md). The blog article used the outdated `ssd_mobilenet_v1_coco_2017_11_17`.

```
[Tensorflow]
ModelUrl=ssd_mobilenet_v3_large_coco_2019_08_14
LabelMapPath=./models/research/object_detection/data/mscoco_label_map.pbtxt
```

# Installing

## Requirements
This project requires:
* A Raspberry Pi + the camera module v2 (the `client`)
* Any Linux machine on the same network (the `server`)

![Pi](./docs/pi.jpg)

## Install
`scarecrow-cam` can be installed using pip:

## Using Docker (recommended)

![Docker](./docs/horizontal-logo-monochromatic-white.png)

Using `Docker` is the preferred way of running `scarecrow`, as it handles dependencies internally and operates within a controllable environment.

### Build Image
```
pip3 install . --upgrade
git submodule update --init --recursive && git submodule update --remote
docker build . -t scarecrow
```

Please see [INSTALL.md](./INSTALL.md) for details and troubleshooting.
### Run separately
Both `client` and `server` containers should be ran separately.

## Configuration and data

Copy `config/config.ini.sample` to `conf/config.ini` with the settings for your Raspberry and server.
#### Server
This runs `tensorflow` and opens the `zmq` listener.
```
docker run -it \
--name scarecrow_server \
-p 5455:5454 \
--ipc=host \
-v $(pwd)/conf:/config \
-v $(pwd)/models/research/object_detection/data:/models \
scarecrow \
/usr/local/bin/scarecrow_server --config /config
```

For playing audio, please adjust `conf/plugins.d/audio.ini`.
#### Client
*Check cameras in `/dev` with `ffplay /dev/video$x`*

```
[Audio]
Path=../audio_files
docker run -it \
--name scarecrow_client \
-p 5454:5454 \
-p 5558:5558 \
--ipc=host \
-v $(pwd)/conf:/config \
-v $(pwd)/resources/audio_files:/data \
--device /dev/snd:/dev/snd \
--device=/dev/video2:/dev/video0 \
scarecrow \
/usr/local/bin/scarecrow_client --config /config --input 0
```
For an appropriate path.

If you want to change the `model`, please check the [Model Zoo](https://github.com/chollinger93/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md). The blog article used the outdated `ssd_mobilenet_v1_coco_2017_11_17`.
### Docker Compose
**Experimental**
```
docker-compose up
```

## Manual install (advanced)
`scarecrow-cam` can be installed using pip:
```
[Tensorflow]
ModelUrl=ssd_mobilenet_v3_large_coco_2019_08_14
LabelMapPath=./models/research/object_detection/data/mscoco_label_map.pbtxt
pip3 install . --upgrade
```

## Run
Please see [INSTALL.md](./INSTALL.md) for details and troubleshooting.

### On the raspberry
### Run (RasPi)
```
scarecrow_client --config ./conf --input 0 # for picam
scarecrow_client --config ./conf --input ./resources/tests/walking_test_5s.mp4 # for local video
```

### On the server
### Run (Server)
```
scarecrow_server --config ./conf
```

## Plugins
# Plugins
A plugin model allows to trigger downstream actions. These actions are triggered based on the configuration.

Plugins can be enabled by setting the following in `config.ini`:
Expand All @@ -84,8 +137,8 @@ Currently, the following plugins are avaibale:
| `audio` | Plays audio files once a person is detected | Either `playsound`, `pygame`, or `omxplayer` | `conf/plugins.d/audio.ini` | `ZMQ` |
| `store_video` | Stores video files on the server, with a defined buffer or length | `Path` and `Encoding` settings | `conf/plugins.d/store_video.ini` | `ZServerMQ` |

## How to contribute
# How to contribute
This project is in an **early state of development**. Therefore, there are several open items that need to be covered. Please see [TODO](TODO.md) for details.

## License
# License
This project is licensed under the GNU GPLv3 License - see the [LICENSE](LICENSE) file for details.
23 changes: 15 additions & 8 deletions conf/config.ini.sample
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
# Overall configuration file

[Video]
FPS=20
FPS=15

[Detection]
min_detections=10
min_confidence=0.7
; If enabled, sets a threshold in seconds for how long the detection will pause after a detection; -1 = disabled
DetectionStopThresholdSeconds=20

# This is the receiver / subscriber
# The server uses this to receive messages
[ZmqCamera]
IP=127.0.0.1
# This is left blank, as it will always bind to `*`
IP=
Port=5454
Protocol=tcp
; 0=zmq.PAIR, 1=zmq.REQ/zmq.REP; 2=zmq.PUB,zmq.SUB
Pattern=1

# This is the publisher, i.e. the camera
[ZmqServer]
IP=127.0.0.1
Port=5454
# In other words, this is the IP of the camera, despite the name
# TODO: change that...
IP=192.xxx.x.xxx
Port=5455
Protocol=tcp
; 0=zmq.PAIR, 1=zmq.REQ/zmq.REP; 2=zmq.PUB,zmq.SUB
Pattern=1

[Tensorflow]
ModelUrl=ssdlite_mobilenet_v2_coco_2018_05_09
LabelMapPath=models/research/object_detection/data/mscoco_label_map.pbtxt # Should be an absolute path
# This setting assumes a run with Docker
LabelMapPath=/models/mscoco_complete_label_map.pbtxt

[Plugins]
UseSenderThread=False
Enabled=store_video,audio
Disabled=
UseSenderThread=True
Enabled=audio
Disabled=store_video,motion
2 changes: 1 addition & 1 deletion conf/logger.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ keys=color

[formatter_color]
class=colorlog.ColoredFormatter
format=%(asctime)s %(log_color)s%(levelname)-8s%(reset)s %(bg_blue)s[%(name)s]%(reset)s %(message)s
format=%(asctime)s %(log_color)s%(levelname)-8s%(reset)s %(filename)s:%(funcName)s():%(lineno)d %(bg_blue)s[%(name)s]%(reset)s %(message)s

[handlers]
keys=stream
Expand Down
11 changes: 6 additions & 5 deletions conf/plugins.d/audio.ini.sample
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[ZmqSender]
IP=127.0.0.1
Port=5557
IP=0.0.0.0
Port=5558

[ZmqReceiver]
IP=127.0.0.1
Port=5557
IP=0.0.0.0
Port=5558

[Audio]
Streamer=pygame
Path=../audio_files
# This setting assumes a run with Docker - needs a file called "warning.wav"
Path=/data
48 changes: 48 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
version: '3'
services:
scarecrow-server:
build: .
image: scarecrow
networks:
scarecrow-net:
ipv4_address: 10.1.0.100
ports:
- "5455:5454"
- "5557:5557"
volumes:
- ./conf:/config
- ./models/research/object_detection/data:/models
command: ["/usr/local/bin/scarecrow_server", "--config", "/config"]
deploy:
restart_policy:
condition: any


scarecrow-camera:
build: .
image: scarecrow
networks:
scarecrow-net:
ipv4_address: 10.1.0.101
ports:
- "5454:5454"
- "5558:5558"
volumes:
- ./conf:/config
- ./resources/audio_files:/data
devices:
- /dev/video2:/dev/video0
deploy:
restart_policy:
condition: any
command: ["/usr/local/bin/scarecrow_client", "--config", "/config", "--input", "0"]
depends_on:
- scarecrow-server

networks:
scarecrow-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.1.0.0/24
4 changes: 2 additions & 2 deletions docs/codecov.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/horizontal-logo-monochromatic-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Binary file added resources/audio_files/warning.mp3
Binary file not shown.
Binary file added resources/audio_files/warning.wav
Binary file not shown.
Loading

0 comments on commit 9294828

Please sign in to comment.