How to properly Multithread in OpenCV in 2019?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
OpenCV already parallelizes many internal operations, so "multithreading OpenCV" usually does not mean sprinkling threads around random function calls. The real question is how to structure your pipeline so capture, preprocessing, inference, and display do not block one another, while avoiding unsafe sharing of cv::Mat data.
Start With OpenCV's Built-In Parallelism
Many OpenCV operations can already use multiple cores through backend libraries such as TBB, OpenMP, or platform-specific threading backends. Before writing your own threads, measure whether the default library behavior is already good enough.
For custom per-pixel or per-row work, OpenCV provides cv::parallel_for_.
This is usually safer than manually creating a thread per row or per tile.
Pipeline Parallelism Is Often Better Than Function-Level Threads
For video applications, a common pattern is:
- one thread captures frames
- one worker thread processes frames
- one thread or the main loop displays results
That reduces blocking between stages.
For example, VideoCapture.read() can block on camera or file I/O. If capture and processing happen on the same thread, throughput can drop badly.
Be Careful With cv::Mat Sharing
cv::Mat uses reference counting, which makes copies cheap, but that does not mean arbitrary concurrent mutation is safe.
Safe rule of thumb:
- multiple threads may read the same immutable
Mat - if one thread writes, give it its own independent copy or its own output buffer
Use clone() or copyTo() when you need ownership of a writable image independent of another thread.
Avoid Oversubscription
A common performance failure is combining:
- your own thread pool
- OpenCV internal threading
- other threaded libraries such as DNN backends
This can create more runnable threads than the CPU can handle efficiently.
Sometimes fewer threads are faster because there is less scheduling overhead and cache contention.
A Producer-Consumer Sketch
The important detail is frame.clone(). Without it, the queued Mat may alias reused capture memory.
GUI Calls Usually Belong on One Thread
Functions such as imshow and event-loop handling often behave best when kept on the main thread. Even when processing happens elsewhere, do not assume every UI-related OpenCV call is happy inside arbitrary worker threads.
Measure Before and After
A proper multithreading strategy depends on workload:
- CPU-bound image transforms
- camera I/O
- DNN inference
- disk decoding
Profile the pipeline. Do not assume manual threading helps just because the machine has many cores.
Common Pitfalls
A common mistake is writing to the same cv::Mat from multiple threads without partitioning the memory or isolating outputs.
Another mistake is manually adding threads around code that OpenCV already parallelizes internally, which can reduce performance instead of improving it.
Developers also often forget that camera capture and GUI display have different threading constraints from pure image math.
Summary
- OpenCV already parallelizes many operations, so measure before adding manual threads.
- Use
cv::parallel_for_for custom data-parallel loops. - For video, pipeline threading is often more useful than random function-level threading.
- Treat writable
cv::Matdata as thread-owned unless you explicitly coordinate access. - Avoid oversubscription by balancing your own threads with OpenCV's internal parallelism.

