Stream images from a connected camera over MQTT, view using Streamlit, record to file and sqlite

Overview

mqtt-camera-streamer

Summary: Publish frames from a connected camera or MJPEG/RTSP stream to an MQTT topic, and view the feed in a browser on another computer with Streamlit.

Long introduction: A typical task in IOT/science is that you have a camera connected to one computer and you want to view the camera feed on a second computer, and maybe preprocess the images before saving them to disk. I have always found this to be way more effort than expected. In particular, working with camera streams can get quite complicated and may lead you to experiment with tools like Gstreamer and ffmpeg that have a steep learning curve. In contrast, working with MQTT is very straightforward and is often familiar to anyone with an interest in IOT. This repo, mqtt-camera-streamer uses MQTT to send frames from a camera over a network at low frames-per-second (FPS). A viewer is provided for viewing the camera stream on any computer on the network. Frames can be saved to disk for further processing. Also it is possible to setup an image processing pipeline by linking MQTT topics together, using an on_message(topic) to do some processing and send the processed image downstream on another topic.

Note that this is not a high FPS solution, and in practice I achieve around 1 FPS which is practical for IOT experiments and tasks such as preprocessing (cropping, rotating) images prior to viewing them. This code is written for simplicity and ease of use, not high performance.

Installation

Install system wide on an RPi, or on other OS use a venv to isolate your environment, and install the required dependencies:

$ (base) python3 -m venv venv
$ (base) source venv/bin/activate
$ (venv) pip3 install -r requirements.txt

Listing cameras with OpenCV

The check-opencv-cameras.py script assists in discovering which cameras OpenCV can connect to on your computer (does not work with RPi camera). If your laptop has a built-in webcam this will generally be listed as VIDEO_SOURCE = 0. If you plug in an external USB webcam this takes precedence over the built-in webcam, with the external camera becoming VIDEO_SOURCE = 0 and the built-in webcam becoming VIDEO_SOURCE = 1.

To check which OpenCV cameras are detected run:

$ (venv) python3 scripts/check-opencv-cameras.py

Configuration using config.yml

Use the config.yml file in the config directory to configure your system. If your desired camera is listed as source 0 you will configure video_source: 0. Alternatively you can configure the video source as an MJPEG or RTSP stream. For example in config.yml you may configure something like video_source: "rtsp://admin:[email protected]:554/11" for a commercial RTSP camera. To configure a RPi camera running the web_streaming.py example you configure video_source: http://pi_ip:8000/stream.mjpg

Validate the config can be loaded by running:

$ (venv) python3 scripts/validate-config.py

Note that this script does not check the accuracy of any of the values in config.yml, just that the file path is correct and the file structure is OK.

By default scripts/opencv-camera.py will look for the config file at ./config/config.yml but an alternative path can be specified using the environment variable MQTT_CAMERA_CONFIG. You can set this using export MQTT_CAMERA_CONFIG=/home/pi/github/mqtt-camera-streamer/config/config.yml

Publish camera frames

To publish camera frames with OpenCV over MQTT:

$ (venv) python3 scripts/opencv-camera-publish.py

Camera display

To view the camera stream with Streamlit:

$ (venv) streamlit run scripts/viewer.py

Note: if Streamlit becomes unresponsive, ctrl-z to pause Streamlit then kill -9 %%. Also note that the viewer can be run on any machine on your network.

Save frames

To save frames to disk:

$ (venv) python3 scripts/save-captures.py

Save frames to db

As save-captures.py but in addition saving the frame thumbnail to a sqlite db:

$ (venv) python3 scripts/db-recorder.py

The images can be viewed using sqlite browser

If you wish to run a server with UI for browsing the images then datasette with the datasette-render-images plugin can be used.

$ (venv) pip install datasette
$ (venv) pip install datasette-render-images
$ (venv) datasette captures/records.db

Image processing pipeline

To process a camera stream (the example rotates the image):

$ (venv) python3 scripts/processing.py

Home Assistant

You can view the camera feed using Home Assistant and configuring an MQTT camera. Add to your configuration.yaml:

camera:
  - platform: mqtt
    topic: homie/mac_webcam/capture
    name: mqtt_camera
  - platform: mqtt
    topic: homie/mac_webcam/capture/rotated
    name: mqtt_camera_rotated
  - platform: mjpeg # the raw mjpeg feed if using picamera
    name: picamera
    mjpeg_url: http://192.168.1.134:8000/stream.mjpg

MQTT

Need an MQTT broker? If you have Docker installed I recommend eclipse-mosquitto. A basic broker can be run with:

docker run -p 1883:1883 -d eclipse-mosquitto

Note that I have structured the MQTT topics following the homie MQTT convention, linked in the references. This is not necessary but is best practice IMO.

OpenCV & streamlit on RPi

OpenCV is used to read the images from a connected camera or MJPEG/RTSP stream. On a Raspberry pi (RPi) installing OpenCV can be troublesome, and I found it necessary to first sudo apt-get install libatlas-base-dev libjasper-dev libqtgui4 python3-pyqt5 libqt4-test libilmbase-dev libopenexr-dev libgstreamer1.0-dev libavcodec58 libavformat58 libswscale5 before installing opencv using the instructions below. Likewise Streamlit can be challenging to install on an RPi, and if you dont need it then remove it from requirements.txt. If you do wish to install Streamlit on the RPi see this thread for latest guidance. On 24/3/2021 I was able to install opencv-python==4.5.1.48 but not streamlit on an RPi4 32bit.

RPi camera

Use an official RPi camera and ensure picamera is installed with pip3 install picamera. If you use the RPi in desktop mode you can check the camera feed using raspistill -o image.jpg. Use the official web_streaming example which creates an mjpeg stream on http://pi_ip:8000/stream.mjpg. This mjpeg stream can be configured as a source with mqtt-camera-streamer to translate the mjepg stream to an mqtt stream.

RPi service

You can run any of the scripts as a service, which means they will automatically start on RPi boot, and can be easily started & stopped. Create the service file in the appropriate location on the RPi using:

sudo nano /etc/systemd/system/my_script.service

Entering the following (adapted for your script.py file location and args, assumes you are using system python3):

[Unit]
Description=Service for mqtt-camera-publish
After=network.target

[Service]
ExecStart=/usr/bin/python3 -u opencv-camera-publish.py
WorkingDirectory=/home/pi/github/mqtt-camera-streamer/scripts
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

Once this file has been created you can to start the service using: sudo systemctl start my_script.service

View the status and logs with: sudo systemctl status my_script.service

Stop the service with: sudo systemctl stop my_script.service

Restart the service with: sudo systemctl restart my_script.service

You can have the service auto-start on rpi boot by using: sudo systemctl enable my_script.service

You can disable auto-start using: sudo systemctl disable my_script.service

References

Comments
  • ImportError: libjasper.so.1: cannot open shared object file: No such file or directory on RPi

    ImportError: libjasper.so.1: cannot open shared object file: No such file or directory on RPi

    Getting error on RPi: ImportError: libjasper.so.1: cannot open shared object file: No such file or directory. Try:

    sudo apt-get install libatlas-base-dev
    sudo apt-get install libjasper-dev
    sudo apt-get install libqtgui4
    sudo apt-get install python3-pyqt5
    sudo apt-get install libqt4-test
    

    Still getting the error. Run sudo apt update --fix-missing and restart pi. STILL getting this error, clearly a cv2 issue

    opened by robmarkcole 8
  • opencv install on rpi4 32bit -

    opencv install on rpi4 32bit -

    pip3 install opencv-python>=4.4.0.46

    Error ImportError: libwebp.so.6: cannot open shared object file: No such file or directory

    That was fixed with sudo apt-get install libwebp-dev

    opened by robmarkcole 3
  • Add display

    Add display

    using flask

    Requires a fair amount of code

    • https://github.com/robsmall/flask-raspi-video-streamer/blob/master/simple-mjpeg-server.py
    • https://github.com/blakeblackshear/frigate/blob/master/detect_objects.py
    • https://blog.miguelgrinberg.com/post/video-streaming-with-flask

    use HTTPServer

    Much less code

    • https://github.com/robmarkcole/simple_mjpeg_streamer_http_server
    opened by robmarkcole 2
  • Mqtt and streamlit in docker

    Mqtt and streamlit in docker

    Hello,

    I am working on a project which requires to publish the results of some of the programs through mqtt onto the streamlit. However, I have to perform this in docker and I think it's not straight-forward to access webcam through docker. I am getting the following error when I run the camera.py code in docker: Traceback (most recent call last): File "camero.py", line 50, in <module> main() File "camero.py", line 28, in main client.connect(MQTT_BROKER, port=MQTT_PORT) File "/usr/local/lib/python3.6/dist-packages/paho/mqtt/client.py", line 937, in connect return self.reconnect() File "/usr/local/lib/python3.6/dist-packages/paho/mqtt/client.py", line 1071, in reconnect sock = self._create_socket_connection() File "/usr/local/lib/python3.6/dist-packages/paho/mqtt/client.py", line 3522, in _create_socket_connection return socket.create_connection(addr, source_address=source, timeout=self._keepalive) File "/usr/lib/python3.6/socket.py", line 724, in create_connection raise err File "/usr/lib/python3.6/socket.py", line 713, in create_connection sock.connect(sa) ConnectionRefusedError: [Errno 111] Connection refused

    Can you please help me resolve this? Thank you.

    opened by MauryaShraddha 1
  • python3-opencv disappeared?

    python3-opencv disappeared?

    ~/mqtt-camera-streamer $ sudo apt install python3-opencv
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    E: Unable to locate package python3-opencv
    
    opened by robmarkcole 1
  • Raspberry pi error: No matching distribution found for opencv-python

    Raspberry pi error: No matching distribution found for opencv-python

    On a pi:

      Could not find a version that satisfies the requirement opencv-python (from -r requirements.txt (line 3)) (from versions: )
    No matching distribution found for opencv-python (from -r requirements.txt (line 3))
    

    Solution -> sudo apt install python3-opencv and don't use venv

    opened by robmarkcole 1
  • Add script to log thumbnails to sqlite db

    Add script to log thumbnails to sqlite db

    As title for rudimentary recording/reviewing system, to allow review of captures if files stored on server. Add streamlit ui with date time picker. Show datasette usage

    opened by robmarkcole 0
  • Bump streamlit from 0.79.0 to 1.11.1

    Bump streamlit from 0.79.0 to 1.11.1

    Bumps streamlit from 0.79.0 to 1.11.1.

    Release notes

    Sourced from streamlit's releases.

    1.11.1

    No release notes provided.

    1.11.0

    No release notes provided.

    1.10.0

    No release notes provided.

    1.9.2

    No release notes provided.

    1.9.1

    No release notes provided.

    1.9.0

    No release notes provided.

    1.8.1

    No release notes provided.

    1.8.0

    No release notes provided.

    1.7.0

    • ❄️ Add st.snow()!

    1.6.0

    • 🗜 WebSocket compression is now disabled by default, which will improve CPU and latency performance for large dataframes. You can use the server.enableWebsocketCompression  configuration option to re-enable it if you find the increased network traffic more impactful.
    • ☑️ 🔘 Radio and checkboxes improve focus on Keyboard navigation (#4308)

    1.5.1

    No release notes provided.

    1.5.0

    Release date: Jan 27, 2022

    Notable Changes

    • 🌟 Favicon defaults to a PNG to allow for transparency (#4272).
    • 🚦 Select Slider Widget now has the disabled parameter that removes interactivity (completing all of our widgets) (#4314).

    Other Changes

    • 🔤 Improvements to our markdown library to provide better support for HTML (specifically nested HTML) (#4221).
    • 📖 Expanders maintain their expanded state better when multiple expanders are present (#4290).
    • 🗳 Improved file uploader and camera input to call its on_change handler only when necessary (#4270).

    1.4.0

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • How to transmit with sound

    How to transmit with sound

    Hi, I tried this program and it runs 12~14 FPS in my environment 360p and 480p also smoothly, which is surprising. But found that it is splitting the video into images for delivery and then combined for display, so its sound is lost. If I need to keep the sound, how should I do it.

    opened by Visoar 0
Releases(0.8)
Owner
Robin Cole
Physics PhD, python, data science, deep learning & space
Robin Cole
Half Instance Normalization Network for Image Restoration

HINet Half Instance Normalization Network for Image Restoration, based on https://github.com/megvii-model/HINet. Dependencies NumPy PyTorch, preferabl

Holy Wu 4 Jun 06, 2022
Rename Images with Auto Generated Neural Image Captions

Recaption Images with Generated Neural Image Caption Example Usage: Commandline: Recaption all images from folder /home/feng/Downloads/images to folde

feng wang 3 May 01, 2022
From this paper "SESNet: A Semantically Enhanced Siamese Network for Remote Sensing Change Detection"

SESNet for remote sensing image change detection It is the implementation of the paper: "SESNet: A Semantically Enhanced Siamese Network for Remote Se

1 May 24, 2022
Unsupervised clustering of high content screen samples

Microscopium Unsupervised clustering and dataset exploration for high content screens. See microscopium in action Public dataset BBBC021 from the Broa

60 Dec 05, 2022
exponential adaptive pooling for PyTorch

AdaPool: Exponential Adaptive Pooling for Information-Retaining Downsampling Abstract Pooling layers are essential building blocks of Convolutional Ne

Alexandros Stergiou 55 Jan 04, 2023
Code for our TKDE paper "Understanding WeChat User Preferences and “Wow” Diffusion"

wechat-wow-analysis Understanding WeChat User Preferences and “Wow” Diffusion. Fanjin Zhang, Jie Tang, Xueyi Liu, Zhenyu Hou, Yuxiao Dong, Jing Zhang,

18 Sep 16, 2022
Code implementation of Data Efficient Stagewise Knowledge Distillation paper.

Data Efficient Stagewise Knowledge Distillation Table of Contents Data Efficient Stagewise Knowledge Distillation Table of Contents Requirements Image

IvLabs 112 Dec 02, 2022
Cache Requests in Deta Bases and Echo them with Deta Micros

Deta Echo Cache Leverage the awesome Deta Micros and Deta Base to cache requests and echo them as needed. Stop worrying about slow public APIs or agre

Gingerbreadfork 8 Dec 07, 2021
Neural Cellular Automata + CLIP

🧠 Text-2-Cellular Automata Using Neural Cellular Automata + OpenAI CLIP (Work in progress) Examples Text Prompt: Cthulu is watching cthulu_is_watchin

Mainak Deb 21 Dec 19, 2022
Yolov5-opencv-cpp-python - Example of using ultralytics YOLO V5 with OpenCV 4.5.4, C++ and Python

yolov5-opencv-cpp-python Example of performing inference with ultralytics YOLO V

183 Jan 09, 2023
Repo for Photon-Starved Scene Inference using Single Photon Cameras, ICCV 2021

Photon-Starved Scene Inference using Single Photon Cameras ICCV 2021 Arxiv Project Video Bhavya Goyal, Mohit Gupta University of Wisconsin-Madison Abs

Bhavya Goyal 5 Nov 15, 2022
[CVPR'21] Projecting Your View Attentively: Monocular Road Scene Layout Estimation via Cross-view Transformation

Projecting Your View Attentively: Monocular Road Scene Layout Estimation via Cross-view Transformation Weixiang Yang, Qi Li, Wenxi Liu, Yuanlong Yu, Y

118 Dec 26, 2022
Official implementation of "One-Shot Voice Conversion with Weight Adaptive Instance Normalization".

One-Shot Voice Conversion with Weight Adaptive Instance Normalization By Shengjie Huang, Yanyan Xu*, Dengfeng Ke*, Mingjie Chen, Thomas Hain. This rep

31 Dec 07, 2022
HGCAE Pytorch implementation. CVPR2021 accepted.

Hyperbolic Graph Convolutional Auto-Encoders Accepted to CVPR2021 🎉 Official PyTorch code of Unsupervised Hyperbolic Representation Learning via Mess

Junho Cho 37 Nov 13, 2022
A PyTorch implementation of the WaveGlow: A Flow-based Generative Network for Speech Synthesis

WaveGlow A PyTorch implementation of the WaveGlow: A Flow-based Generative Network for Speech Synthesis Quick Start: Install requirements: pip install

Yuchao Zhang 204 Jul 14, 2022
Source code and dataset for ACL2021 paper: "ERICA: Improving Entity and Relation Understanding for Pre-trained Language Models via Contrastive Learning".

ERICA Source code and dataset for ACL2021 paper: "ERICA: Improving Entity and Relation Understanding for Pre-trained Language Models via Contrastive L

THUNLP 75 Nov 02, 2022
PyGCL: A PyTorch Library for Graph Contrastive Learning

PyGCL is a PyTorch-based open-source Graph Contrastive Learning (GCL) library, which features modularized GCL components from published papers, standa

PyGCL 588 Dec 31, 2022
Adversarial Adaptation with Distillation for BERT Unsupervised Domain Adaptation

Knowledge Distillation for BERT Unsupervised Domain Adaptation Official PyTorch implementation | Paper Abstract A pre-trained language model, BERT, ha

Minho Ryu 29 Nov 30, 2022
Data and code for the paper "Importance of Kernel Bandwidth in Quantum Machine Learning"

Reproducibility materials for "Importance of Kernel Bandwidth in Quantum Machine Learning" Repo structure: code contains Python scripts used to genera

Ruslan Shaydulin 3 Oct 23, 2022
Second-Order Neural ODE Optimizer, NeurIPS 2021 spotlight

Second-order Neural ODE Optimizer (NeurIPS 2021 Spotlight) [arXiv] ✔️ faster convergence in wall-clock time | ✔️ O(1) memory cost | ✔️ better test-tim

Guan-Horng Liu 39 Oct 22, 2022