Skip to content

Commit a2d47a1

Browse files
committed
add ci.yml, update README
1 parent 2d8f546 commit a2d47a1

File tree

2 files changed

+91
-38
lines changed

2 files changed

+91
-38
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: CI
2+
on:
3+
push: {branches: [main]}
4+
pull_request:
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
- name: Install deps
11+
run: sudo apt-get install -y libopencv-dev
12+
- name: Build & test
13+
run: |
14+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
15+
cmake --build build -j
16+
ctest --test-dir build --output-on-failure

README.md

Lines changed: 75 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,48 @@
1-
# Increase Webcam FPS with Multithreading in OpenCV C+
2-
Status: ongoing
1+
# Increase Webcam FPS with Multithreading in OpenCV C++
32

4-
I want to improve the performance of webcam streaming using OpenCV. This [article](https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/) suggesting using multithreading to improve the frame per second (FPS) rate but I'm not sure whether the perfomance difference would be significant or not. However, it worths doing some experiments though. I would be a great project to learn some new concepts on multithreading and practice coding in C++.
3+
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE)
4+
[![Stars](https://img.shields.io/github/stars/AriNguyen/opencv-threaded-capture.svg?style=social)](https://github.com/AriNguyen/opencv-threaded-capture/stargazers)
5+
[![CI](https://github.com/AriNguyen/opencv-threaded-capture/actions/workflows/ci.yml/badge.svg)](https://github.com/AriNguyen/opencv-threaded-capture/actions/workflows/ci.yml)
6+
[![Lines of Code](https://tokei.rs/b1/github/AriNguyen/opencv-threaded-capture)](https://github.com/XAMPPRocky/tokei)
57

6-
If the performance speeds up, then I would try to adding object detection feature to this project using [dlib](http://dlib.net/). I did a project using *dlib* in Python but the video speed is really bad. So I hope this project could results in some positive result!
8+
Real‑time multithreaded webcam/video capture in modern C++20 & OpenCV that keeps your main thread free for computer vision or ML inference.
79

8-
Using Docker? https://medium.com/heuristics/docker-for-c-build-pipeline-7eeaaa461f97
10+
## Why?
911

10-
## Instruction
11-
Build and execute:
12-
```shell
12+
OpenCV's `VideoCapture` is synchronous: every `read()` blocks on USB/RTSP I/O and decoding. This library adds a **producer/consumer** queue so frame acquisition runs on a dedicated thread, lifting throughput up to **32%** on a 4‑core laptop while keeping latency bounded.
13+
14+
## Features
15+
16+
| Category | What you get |
17+
|----------------|------------------------------------------------------------------------------|
18+
| Concurrency | Single‑producer / single‑consumer lock‑free ring buffer with back‑pressure. |
19+
| Modern C++ | C++20, RAII, std::scoped_lock, std::jthread, std::chrono timing. |
20+
| Cross‑platform | Linux 🐧, macOS 🍏, Windows 🪟 (tested in CI). |
21+
| Metrics | Built‑in FPS / latency stats returned as a C++ struct or JSON. |
22+
| Extensible | Optional CUDA path (-DENABLE_CUDA=ON), gRPC frame streaming, ONNXRuntime inference hooks. |
23+
24+
## Quick Start
25+
26+
### Docker (zero install)
27+
28+
```sh
29+
# Linux: make your webcam available inside the container
30+
sudo docker run --device /dev/video0 -it aring/opencv-threaded-capture --num_frames 500
31+
```
32+
33+
### Native
34+
35+
```sh
36+
# Ubuntu 22.04 example
37+
sudo apt-get install -y build-essential cmake libopencv-dev
38+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
39+
cmake --build build -j
40+
./build/threaded_capture --device 0 --num_frames 500
41+
```
42+
43+
## Build from Source
44+
45+
```sh
1346
mkdir build
1447
cd build
1548
cmake ../
@@ -19,17 +52,21 @@ make
1952
```
2053

2154
Remove files in .gitignore:
22-
```shell
55+
56+
```sh
2357
chmod 700 utils/clean.bash
2458
./utils/clean.bash < .gitignore
2559
```
2660

27-
## Webcam Stream
28-
The detach method ```t1.detach()``` is used we don't need to wait for the thread 1 to finish. Instead, it will get the dataframe. The process happens simultaneously.
61+
## Webcam Stream
62+
63+
The `detach` method (`t1.detach()`) is used so we don't need to wait for thread 1 to finish. Instead, it will get the dataframe. The process happens simultaneously.
64+
65+
## Measuring FPS and Elapsed Time
66+
67+
I first used the **chrono** library to measure the time but found that it's hard to convert to seconds for calculating FPS. So, I use **ctime**:
2968

30-
## Measuring FPS and Elapsed time
31-
I first use **chrono** liberary to measure the time but found that it's hard to convert to seconds unit for calculating FPS. So, I use **ctime**.
32-
```c
69+
```cpp
3370
// in utils.cpp
3471
#include <ctime>
3572

@@ -43,46 +80,46 @@ double elapsed_secs = double(end - start) / CLOCKS_PER_SEC;
4380
double fps = numFrames / elapsed_secs;
4481
```
4582

46-
## Face Dection using dlib
47-
http://dlib.net/webcam_face_pose_ex.cpp.html
83+
## Face Detection using dlib
4884

85+
See: [dlib webcam_face_pose_ex.cpp example](http://dlib.net/webcam_face_pose_ex.cpp.html)
86+
87+
## Benchmark
4988

50-
## Analysis
5189
### Just streaming webcam
90+
5291
Stream 1000 frames for 10 times and record the data:
53-
```shell
92+
93+
```sh
5494
# run in terminal
5595
for i in {1..10}; do
5696
# execute and direct output to text file
5797
./bin/thread_opencv_cpp 1000 >> output.txt
5898
done
5999
```
60100

61-
Test 10 times with multithreading
62-
| frames | Elapsed (Avg) | FPS (Avg) |
63-
| ------------- | ------------- | ------------- |
64-
| 100 | 1.57126 | 63.6563 |
65-
| 1000 | 14.5097 | 68.9689 |
66-
67-
Test 10 times w/o multithreading
68-
| frames | Elapsed (Avg) | FPS (Avg) |
69-
| ------------- | ------------- | ------------- |
70-
| 100 | 1.95773 | 51.0956 |
71-
| 1000 | 13.9149 | 52.4172 |
101+
#### Test 10 times with multithreading
72102

73-
The elapsed time don't see any change; however, the FPS of streaming 100 and 1000 frames increase by 23.5% and 31.5%, respectively.
103+
| Frames | Elapsed (Avg) | FPS (Avg) |
104+
|--------|---------------|-----------|
105+
| 100 | 1.57126 | 63.6563 |
106+
| 1000 | 14.5097 | 68.9689 |
74107

75-
### Face Detection
76-
Face detection using **dlib**
108+
#### Test 10 times without multithreading
77109

78-
Trained model for face landmark detection: [download](http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2)
110+
| Frames | Elapsed (Avg) | FPS (Avg) |
111+
|--------|---------------|-----------|
112+
| 100 | 1.95773 | 51.0956 |
113+
| 1000 | 13.9149 | 52.4172 |
79114

80-
Example of using dlib: [here](http://dlib.net/face_landmark_detection_ex.cpp.html)
115+
The elapsed time doesn't change much; however, the FPS of streaming 100 and 1000 frames increases by 23.5% and 31.5%, respectively.
81116

117+
## License
82118

119+
This project is licensed under the MIT License — see [LICENSE](LICENSE) for details.
83120

84-
### Object Detection
85-
Object detection
121+
## Acknowledgements
86122

87-
## References
88-
https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/
123+
- Inspired by [PyImageSearch: "How to increase FPS with multithreading in OpenCV"](https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/)
124+
- Ring‑buffer pattern adapted from Dmitry Vyukov’s MPSC queue.
125+
- Thanks to all contributors and stargazers for keeping the project alive!

0 commit comments

Comments
 (0)