Tracking multiple objects with OpenCV

Inside today’s tutorial, you will learn how to track multiple objects using OpenCV and Python.

This post was inspired by a question I received from PyImageSearch reader, Ariel.

Ariel writes:

Hi Adrian, thanks for last week’s blog post on object tracking.

I have a situation where I need to track multiple objects but the code last week didn’t seem to handle that use case. I’m a bit stumped on how I can modify the code to track multiple objects.

What should I do?

Great question, Ariel — as we’ll find out, tracking multiple objects is fairly similar to tracking single objects, with only one or two caveats that we need to keep in mind.

To learn how to track multiple objects with OpenCV, just keep reading!

Looking for the source code to this post?
Jump right to the downloads section.

Tracking multiple objects with OpenCV

In the remainder of this tutorial, you will utilize OpenCV and Python to track multiple objects in videos.

I will be assuming you are using OpenCV 3.2 (or greater) for this tutorial.

If you are using OpenCV 3.1 or below you should use my OpenCV install tutorials to install an updated version.

From there, let’s get started implementing OpenCV’s multi-object tracker.

Project structure

Today’s code + video files can be obtained via the “Downloads” section of this blog post. Once you’ve downloaded the zip to your computer, you can use the following 3 commands to inspect the project structure:

The output of tree  shows our project structure.

  • We’ll be discussing one Python script — .
  • I’ve supplied 4 example videos for you to experiment with. Credits for these videos are given later in this blog post.

Implementing the OpenCV multi-object tracker

Let’s get started coding our multi-object tracker.

Create a new file named  and insert the following code:

To begin, we import our required packages. You’ll need OpenCV and imutils installed in your environment.

To install imutils , simply use pip:

From there we’ll parse command line arguments:

Our two command line arguments consist of:

  • --video : The path to our input video file.
  • --tracker : The OpenCV object tracker to use. There are 7 trackers listed in the next code block to choose from and by default kcf  is used.

From there we’ll initialize our multi-object tracker:

Please refer to the previous post on OpenCV Object Trackers for the full explanation of the 7 available tracker algorithms defined on Lines 18-26.

I recommend the following three algorithms:

  • KCF: Fast and accurate
  • CSRT: More accurate than KCF but slower
  • MOSSE: Extremely fast but not as accurate as either KCF or CSRT

On Line 29 we initialize the multi-object tracker via the cv2.MultiTracker_create  method. The class allows us to:

  1. Add new object trackers to the MultiTracker
  2. Update all object trackers inside the MultiTracker  with a single function call

Let’s move on to initializing our video stream:

Lines 32-35 handle creating a video stream object for a webcam. Otherwise, a video path must have been supplied, so we’ll create a video capture object which will read frames from a video file on disk (Lines 38 and 39).

It’s now time to loop over frames and start multi-object tracking!

Lines 45-50 handle grabbing a frame  from the stream. We’ll break out of the loop if no more frames are available. Frames won’t be available at the end of a video file or if there is a problem with the webcam connection.

Then we resize  the frame to a known dimension on Line 53 — a smaller video frame yields faster FPS as there is less data to process.

From there, let’s update  our trackers  and draw bounding boxes around the objects:

Here we are updating all single object trackers inside trackers  thereby obtaining multi-object tracking (Line 57).

For each tracked object there is an associated bounding box. The box is drawn on the frame via the cv2.rectangle  drawing function on Lines 60-62.

Next, we’ll display the frame  as well as select our objects to track:

The frame  is shown on the screen via Line 65.

A keypress is also captured on Line 66.

If the key pressed is an “s” for “select”, we’ll manually select bounding box of object to track using our mouse pointer via the cv2.selectROI  function (Lines 73 and 74). If you’re unhappy with your selection you can press “ESCAPE” to reset the selection, otherwise hit “SPACE” or “ENTER” to begin the object tracking.

Once the selection has been made we add the tracker  object to trackers  (Lines 78 and 79).

Important: You’ll need to press “s” key and select each object we want to track individually.

This is of course just an example. If you were building a truly autonomous system, you would not select objects with your mouse. Instead, you would use an object detector (Haar Cascade, HOG + SVM, Faster R-CNN, MobileNet, YOLO, etc.). I’ll be demonstrating how to do this process starting next week, so stay tuned!

Let’s handle when the “q” key (“quit”) has been pressed (or if we’ve broken out of the loop due to reaching the end of our video file):

When the “q” key is pressed, we break out of the loop and perform cleanup. Cleanup involves releasing pointers and closing GUI windows.

Multi-object tracking results

Head over the “Downloads” section at the bottom of this post to grab the source code + video files.

From there, open up a terminal and execute the following command:

Your webcam will be used by default since the --video  switch was not listed. You may also leave off the --tracker  argument and kcf  will be used.

Would you like to use one of the four supplied video files or a video file of your own?

No problem. Just supply the  --video  command line argument along with a path to a video file. Provided OpenCV can decode the video file, you can begin tracking multiple objects:

You may also supply your desired tracking algorithm via the --tracker  command line argument (as shown).

Notice how we are able to:

  • Track multiple soccer players across the pitch
  • Track multiple race cars in a race
  • And track multiple vehicles as they are driving in a freeway

Be sure to give the code a try when you need to track multiple objects with OpenCV!

Problems and limitations

There are two limitations that we can run into when performing multiple object tracking with OpenCV.

As my results from the previous section demonstrated, the first (and biggest) issue we ran into was that the more trackers we created, the slower our pipeline ran.

Keep in mind that we need to instantiate a brand new OpenCV object tracker for each object we want to track — we cannot use the same object tracker instance to track multiple objects.

For example, suppose we have 10 objects in a video that we would like to track, implying that:

  1. We need to create 10 object tracker instances
  2. And therefore, we’ll see the frames per second throughput of our pipeline decrease by a factor of 10.

Object trackers are not “magic” and computationally “free” to apply — each and every one of these object trackers requires computation to track an object, there is no way to get around that.

…or is there?

If you open up your activity monitor on your system you’ll notice that when running today’s script that only one processor core is being utilized.

Is there a way to distribute each of the object trackers to a separate process, thereby allowing us to utilize all cores of the processor for faster object tracking?

The answer is yes, we can — and I’ll show you how to obtain faster multi-object tracking later in this series.

Video and Audio credits

To create the examples for this tutorial I needed to use clips from a number of different videos. A big thank you and credit to Ben Sound, Dash Cam Tours, NASCAR, and FIFATV.


In today’s tutorial, we learned how to perform multiple object tracking using OpenCV and Python.

To accomplish our multi-object tracking task, we leveraged OpenCV’s cv2.MultiTracker_Create  function.

This method allows us to instantiate single object trackers (just like we did in last week’s blog post) and then add them to a class that updates the locations of objects for us.

Keep in mind though, the cv2.MultiTracker  class is a convenience function — while it allows us to easily add and update objects locations, it’s not necessarily going to improve (or even maintain) the speed of our object tracking pipeline.

To obtain faster, more efficient object tracking we’ll need to leverage multiple processes and spread the computation burden across multiple cores of our processor — I’ll be showing you how to accomplish this task in a future post in this series.

To download the source code to this post, and be notified when the next object tracking tutorial is published, be sure to enter your email address in the form below!


If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL! Sound good? If so, enter your email address and I’ll send you the code immediately!


123 Responses to Tracking multiple objects with OpenCV

  1. Lu Mao August 6, 2018 at 11:38 am #

    Thanks Adrian!

    • Adrian Rosebrock August 6, 2018 at 12:27 pm #

      I’m glad you liked it, Lu Mao! 🙂

  2. Cagdas August 6, 2018 at 11:58 am #


    Thanks for the post firstly. I’m currently using KCF tracker (reason explained below) to track people (detection made by Tensorflow Object Detection API with a model)

    Since its more accurate, I actually want to use CSRT. Low FPS rate is not problem for me

    However, on my tests, CSRT never handle the failure even if target is lost while KCF does this well (thats why im currently using it)

    Do you know any trick to improve CSRT (or any tracker doesnt report failure well) on failure reports?

    • Adrian Rosebrock August 6, 2018 at 12:29 pm #

      The term “accurate” her is really based on the context of your object tracking application. CSRT does tend to perform better than KCF in most general applications; however, there are situations when another tracker could perform better. If KCF is getting you better accuracy for your application then I would suggest sticking with KCF. Unfortunately without knowing more about your specific project it’s pretty challenging to provide any other suggestions. I hope that helps point you in the right direction though!

    • Tom August 6, 2018 at 2:03 pm #

      Hi Cagdas,
      If your objective is to maintain object ID’s, I suggest you try tracking-by-detecting. I’m using SORT algorithm to do it. You do detection on every frame (or every nth frame, as long as there’s a good overlap between object’s location in consecutive nth frames), pass your detected bounding boxes to SORT, which returns ‘adjusted’ bounding boxes and their ID’s. You can fix with the level of ‘adjustment’ SORT does by fiddling with it’s parameters.
      I haven’t found another satisfactory enough way to do it, but I’m hoping for Adrian to show us something better.

      • Adrian Rosebrock August 6, 2018 at 4:13 pm #

        It’s also important to note that SORT is using Kalman filters as well. It’s more than just running detection on every frame.

        • Austin February 21, 2019 at 11:50 pm #

          I think I read in the deepsort paper that the velocity components of the filters played no meaningful role in tracking performance – in your experience, what are the most effective techniques for multi-object tracking with regard only to accuracy (ignoring speed)? Do you use deep-sort or something else? Great article, thank you!

  3. Alex August 6, 2018 at 12:59 pm #

    Thanks a lot Adrian! Next week be a good boy and come faster ASAP , please 😉

    • Alex August 7, 2018 at 12:20 pm #

      I apologize in connection with the ridiculous misunderstanding, was in a hurry and did not reread. was meant the desire for the soonest coming of the next week

  4. ata August 6, 2018 at 1:20 pm #

    i like your website and info

    • Adrian Rosebrock August 6, 2018 at 4:10 pm #

      Thank you, I’m glad you liked the post 🙂

  5. Izak August 6, 2018 at 1:32 pm #

    Hello, thanks simplifying the process of learning Open CV.

    I wanted to know how can I detect tracking failure for a single object in the multi track so that I can remove it from the list of objects that are being tracked and perhaps re-initiate detection to add new objects ?

    • Adrian Rosebrock August 6, 2018 at 4:11 pm #

      Unfortunately, I believe this is a bug in the current “cv2.MultiTracker” functionality. The “success” boolean is always “True”, not an array of boolean values, one for each tracker.

    • Tehseen Akhtar November 29, 2018 at 11:07 am #

      well i have a some logic to share. I used failure detection by tracking an object for some frames say 30 frames in the forward direction and then from the 30th frame tracking all the objects back to the first frame. Good tracks will come back to their original positions and failures will not come back to their start point so we can remove them from the list and only keep the remaining one. Hope this helps. I would like Adrian to include this in the next release as well.

  6. Marco August 6, 2018 at 3:13 pm #

    hello Adrian, congratulations for your lessons more and more ‘beautiful, is more than a week that I try to be able to run my Raspberry with Python + OpenCv unfortunately without success, I also congratulate all those who have succeeded! Unfortunately to me launching any Python application then follow various errors, in this case this is what appears to me launching multi_ subject_tracking:
    $ python –tracker csrt
    Traceback (most recent call last):
       File “”, line 22, in
         “csrt”: cv2.TrackerCSRT_create,
    AttributeError: ‘module’ object has no attribute ‘TrackerCSRT_create’

    do you think you can help me solve the problem?

    • Adrian Rosebrock August 6, 2018 at 4:15 pm #

      In order to utilize the CSRT tracker you need OpenCV 3.4 or greater. My guess is that you are not using OpenCV 3.4. If you comment out Line 19 the code should work just fine for you.

      • Phil August 6, 2018 at 7:23 pm #

        Is this solution suitable for Python / OpenCV on RPi? (Assuming we omit next week’s steps of object detection with a classifier).

        • Adrian Rosebrock August 7, 2018 at 6:35 am #

          If you’re using a Raspberry Pi I would suggest you:

          1. Use the MOSSE tracker as its the fastest
          2. Use a faster object detector. The deep learning SSD used here is too slow on the Pi (~1 FPS). Haar cascades, while less accurate, will be the fastest.

    • lionel August 7, 2018 at 8:37 am #

      Hi Marco,

      Same than you on my Debian Stretch (seems even to be a ). So I will have to build an OpenCV 3.4 for it 🙁

    • Dheeraj August 9, 2018 at 3:28 am #

      pip install opencv-contrib-python

      will solve the problem

      • vinod August 14, 2019 at 6:46 am #

        Thanks a ton <3

  7. Rohit Thakur August 6, 2018 at 9:51 pm #

    Hello Adrian, Wonderful post. I am eagerly waiting for the post showing object detection and tracking simultaneously.

    • Adrian Rosebrock August 7, 2018 at 6:34 am #

      I’ll have such a post this coming Monday, Rohit 🙂

      • Trinity August 31, 2018 at 12:46 pm #

        Hi Adrian,
        Thanks for the post.

        When will you post about object detection and tracking simultaneously?!

        • Adrian Rosebrock September 5, 2018 at 9:20 am #

          I’ve already posted about it. Make sure you jon the PyImageSearch newsletter so you’re notified when new blog posts are published 🙂

  8. Luke August 6, 2018 at 10:23 pm #

    Let me guess… Python threading?

    • Adrian Rosebrock August 7, 2018 at 6:33 am #

      I’m not sure what you mean by “guessing” — the post covers the exact method. OpenCV’s provides the cv2.MultiTracker function as a convenience method to accept multiple object trackers — it does not natively cover creating multiple processes to distribute to multiple cores (I will be covering that in a future blog post).

      Secondly, you wouldn’t use threading for computationally heavy tasks — you were use multi-processing there.

  9. Marco August 7, 2018 at 3:05 am #

    Hi Adrian, I actually use OpenCV 3.3, commenting on line 19 “csrt”: cv2.TrackerCSRT_create “as you suggest, I get another error:
         “moves”: cv2.TrackerMOSSE_create
    Do you have any other suggestions to give me?
    Thank you

    • Adrian Rosebrock August 7, 2018 at 6:27 am #

      It’s the same solution, Marco. Comment out the MOSSE line.

  10. wildan August 7, 2018 at 5:36 am #

    can i apply this tutorial for real-time ? and how to save object that have been bounded with this square bounding ?

    i’m sorry my english is so bad ?

    • Adrian Rosebrock August 7, 2018 at 6:26 am #

      Yes, the code does work in real-time. The code also saves an output video of the results. Be sure to give the code a look, it shows you how to accomplish both of your goals.

  11. Mark C August 7, 2018 at 6:51 am #

    Loved the aricle object tracked correctly.

    • Adrian Rosebrock August 7, 2018 at 7:48 am #

      Thank you for the kind words Mark, I’m glad the post worked for you 🙂

  12. Gal August 7, 2018 at 7:20 am #

    Awesome – works pretty well with all trackers.

    I get “AttributeError: module ‘cv2.cv2’ has no attribute ‘TrackerCSRT_create'” when I try to run with –tracker csrt.
    I’m working inside a virtualenv, and when I “python” “import cv2” and “cv2.__version__” I get “3.4.0” so I’m pretty sure I’m using OpenCV 3.4.

    Your solution of commenting out the “csrt” line works and the results are really impressive. Thanks for another awesome tutorial!

    • Adrian Rosebrock August 7, 2018 at 7:47 am #

      You are using OpenCV 3.4, but you don’t have the opencv_contrib module installed. Take a look at the other comments on this post for the solution.

  13. Zoe August 8, 2018 at 2:50 am #

    Hi Adrian, as a postgraduate student, I have studied tracking for just a few months. Firstly,thanks a lot for your sharing and I will appreciate it that if you could tell me something about data association in each tracker to realize ID matching.

    • Adrian Rosebrock August 9, 2018 at 2:58 pm #

      You can combine the methods from this post and my previous post to obtain ID matching. An example of such a combined solution can be found in next week’s blog post on people counting.

  14. Marco August 8, 2018 at 1:58 pm #

    Hi Adrian, I have to correct myself, removing the lines you suggested works, only that the video is very slow and therefore also the traking of the object, is there a way to speed up? I have to go to OpenCV 3.4, can you tell me the shortest way to do it? if you can do I can keep Python 2.7 or do I have to go to version 3 too?
    Thank you

    • Adrian Rosebrock August 9, 2018 at 2:51 pm #

      Hey Marco — how many objects are you tracking? Are you using one of my example videos or your own? And additionally, which tracker are you using?

  15. asıf August 9, 2018 at 4:33 am #

    hi, consider the scene that has one moving object but camera is non stationary. In that case how can I do detection and tracking automatically without selecting ROI?

    • Adrian Rosebrock August 9, 2018 at 2:44 pm #

      This method will still work even if the camera is non-stationary and is moving around. Next week’s blog post will show you how to (1) automatically detect the object and (2) track the object as it moves around. Make sure you join the PyImageSearch newsletter to be notified when the post goes live!

  16. marco August 10, 2018 at 3:41 am #

    hi Adrian, I use “trackin multiple object” but I select only one object as it is very slow, the images come from my Web Cam usb

    • Adrian Rosebrock August 10, 2018 at 6:06 am #

      Hey Marco, can you clarify what “slow” in this context means? What tracker are you using? How many objects are you tracking? Are you using the input videos I supplied or your own custom videos?

      • Marco August 10, 2018 at 7:41 am #

        Adrian, I summarize what I do, on my raspberry a web cam usb and the Pi camera, when I start “$ python” opens a video window, the images I see come from the Web Cam usb, the video is not fluid If, for example, my face is framed and I move to one side the video image takes a few seconds to reach me, the same thing happens with the tracking, I have to move a lot, very slowly because the trakcing follows me. I hope I was clear.
        Thanks for your patience

        • Adrian Rosebrock August 10, 2018 at 7:57 am #

          If you are using the Raspberry Pi you should be using the MOSSE tracker. The KCF and CSRT trackers are too computationally intensive for the Pi.

          • Marco August 10, 2018 at 8:41 am #

            Hi Adrian, you advised me this “It’s the same solution, comment out the MOSSE line.” to solve my problem: “MOSSE”: cv2.TrackerMOSSE_create
            AttributeError: ‘module’ object has no attribute ‘TrackerMOSSE_create’ “I would like to understand why it does not work” MOSSE “…..

          • Adrian Rosebrock August 10, 2018 at 8:50 am #

            Which version of OpenCV are you using?

  17. Apoorva Vinod August 10, 2018 at 12:15 pm #

    Hey Adrian,
    Just wanted to let you know that I worked on something similar a few months ago, Multiple object tracking with detection as well. I didn’t want to manually select bounding boxes so I passed the frames through an object detection model. I have YOLOv2 and MobilenetSSD for the detection part. After getting the bounding boxes from the detection I pass them into the trackers. Btw, IMO the multitracker is poorly implemented in python opencv since it doesn’t handle tracking failure well. So I opted to maintain my own dictionary of trackers and added/deleted trackers from them as and when objects were newly detected or failed to track. I experimented with the following trackers : BOOSTING, MIL, KCF, TLD, MEDIANFLOW and GOTURN. I found KCF to be decent in most use-cases like dashcam videos and such. I will try out CSRT and MOSSE soon. Let me know what you guys think, your input is highly appreciated! 🙂

    Here’s the github repo:

    • Adrian Rosebrock August 15, 2018 at 9:18 am #

      Thanks for sharing, Apoorva! If you would like to compare your implementation to mine, make sure you take a look at this post where I demonstrated how to combine object trackers with object detection.

  18. Marco August 10, 2018 at 12:16 pm #

    OpenCv 3.3.0 end Python 2.7.13

    • Adrian Rosebrock August 15, 2018 at 9:18 am #

      You need OpenCV 3.4 or greater for the CSRT tracker. You can either comment out Line 19 or install OpenCV 3.4 on your system.

    • Prasanna August 29, 2018 at 4:32 am #

      Hi Marco, you need to install opencv-contrib-python package instead of opencv-python as the former consists of all OpenCV modules and the latter is only a subset and contains only main modules for release.

      The Tracker modules are moved to contrib package and you need to install it seperately.

      Please use this below link for installation reference:

      Below link gives the actual difference in the packages:


  19. Lionel August 11, 2018 at 2:32 am #

    Hi Adrian,

    Something surprises me a little bit. I can select several players. Good, so I selected 3: 2 I know they always stay on the screen and another one who will disappear. The code starts to track them correctly but when the 3rd one disappears I was thinking/hopping the code will stop to track it. But actually it just decide to track another player who has no relation with the 3rd one. Why? How to avoid that?

    • Adrian Rosebrock August 15, 2018 at 9:14 am #

      Your question is the crux of all object tracking research — how to determine if an object is lost/out of view. Object tracking is an open area of research and far from solved. I would suggest reading the first post in the series for more context, but keep in mind object tracking is far from solved.

  20. Markus August 15, 2018 at 3:54 am #

    dear Adrian
    i want to ask you that how to save the video of result to display to others.

    • Adrian Rosebrock August 15, 2018 at 8:16 am #

      You can use the cv2.VideoWriter function. An example of which can be found here.

  21. Drew August 22, 2018 at 9:51 am #

    Hey Adrian,

    Great writeup! Only question I had was is there any way to remove one / all of the trackers or ROI’s?

    • Adrian Rosebrock August 22, 2018 at 10:18 am #

      Unfortunately no, not really. The cv2.MultiTracker is really just a convenience function. If you want access to the success booleans and be manually update or remove them you’ll need to manually manage each individual object tracker.

      • Drew August 22, 2018 at 10:30 am #

        So I couldnt do anything with the success Boolean in this setup?

        (success, boxes) = trackers.update(frame)

        I’d be happy if I could just reset everything back to default like no ROI’s were selected and the camera had just come online.

        • Adrian Rosebrock August 24, 2018 at 8:57 am #

          Unfortunately, no, the “success” boolean (at the time being) is not helpful for cv2.MultiTracker.

          If you want to reset everything back to the default just reinitialize the object:

          trackers = cv2.MultiTracker_create()

  22. lxc August 24, 2018 at 6:48 am #

    Hello, great God.
    Why do I choose only one area after I press “s”? When choosing second, the first one will disappear.

    • Adrian Rosebrock August 24, 2018 at 8:28 am #

      The first object should still be tracked. If it “disappears” it simply means that the object tracker you used won’t be able to track the object.

  23. Lukas August 28, 2018 at 12:19 am #

    Hello Adrian,
    first of all, thank you for providing these awesome ressources on OpenCV and computer vision on your blog. I am a huge fan of your articels and they already helped me out very often.
    I have a question regarding the multi-processing, you were talking of. Since, I am implementing my own detection and tracking framework for multiple targets, I want to run the trackers’ update() method in a parallel pool. I am creating and initialising the trackers (CSRT) every 15 frames and want to pass them to a parallel pool via map() for calling their update methods. In theory, this should work, but the OpenCV trackers are not pickable, which is why they can’t be sent to the pool workers.
    This is, why I was wondering, how you have planned to do the multi-processing implementation of your above code.


    • Adrian Rosebrock August 28, 2018 at 3:13 pm #

      Hey Lukas — you’re absolutely right, OpenCV tracker objects are not pickable. I’m actually writing a blog post that discusses this very topic, including how to distribute the object trackers across multiple processes. Stay tuned!

      • Lukas August 30, 2018 at 3:35 am #

        Hey Adrian,
        thanks for your answer! That is great to hear and I am really looking forward to see your solution, since I broke my head about this problem and tried a lot of approaches, which became very complex and did not really work well.

      • Eugene July 30, 2019 at 11:21 am #

        I’d like to find out whether you wrote a post about the problem discussed above?

        • Adrian Rosebrock August 7, 2019 at 12:52 pm #

          Yes. You can find it here.

  24. Mohammad September 4, 2018 at 3:18 am #

    Hello Adrian,
    Thank you for sharing your knowledge.

    Is there any implementation of MHT(Multiple Hypothesis Tracking) for python? I have heard that’s much faster than opencv implementations of tracking like “CSRT” or so.

  25. Nurettin September 24, 2018 at 1:33 pm #

    Hello Adrian, how can I implement HOG feature to KCF tracker?

    • Adrian Rosebrock October 8, 2018 at 12:48 pm #

      You mean detect an object via HOG + Linear SVM and then track it?

      • Nurettin October 9, 2018 at 4:22 pm #

        Yes, couldn’t do that.
        By the way, I want to detect every person comes home and take their face one by one, to detect person which implementation do you suggest?

  26. hayu October 15, 2018 at 11:53 pm #

    Hello Adrian.. i will question.. how to measure the diameter of objects detected?

  27. Sean Ng October 18, 2018 at 1:15 am #

    You tutorials are amazing!
    The KCF tracker serves the accuracy needed for my assignment but when they are 3 or more person in the room walking around, the fps dropped to below 8fps, I’m looking forward to your next tutorial on using multiprocessors to run the trackers.
    Thank you so much for these tutorials!!

    • Adrian Rosebrock October 20, 2018 at 7:47 am #

      Thanks Sean! The multiprocessing tutorial for object tracking will publish the end of this month (October). Keep an eye on the PyImageSearch blog for it!

  28. Waqar Nawab October 18, 2018 at 2:51 am #

    Hy Adrian, Can you please suggest me on how can I replace custom image over tracked object? Any ideas

    • Adrian Rosebrock October 20, 2018 at 7:47 am #

      There are a few ways to do this but it really depends on how “realistic” you want the effect to look, and therefore, how complicated the algorithm will be. Could you share some more details on what you’re trying to accomplish?

  29. Pankaj October 20, 2018 at 2:49 am #

    Hi Adrian,
    Thanks for the awesome tutorial.
    After I run the code using command line argument : python –video videos/soccer_01.mp4 –tracker csrt

    The video appears for about 3-4 seconds and disappears .Also,I can’t make a bounding box on a person using mouse . Can you please guide me how to resolve this issue?

    Thanks in advance.


    • Adrian Rosebrock October 20, 2018 at 7:22 am #

      Hey there, Pankaj, what version of OpenCV and Python are you using and which OS? I haven’t ran into that specific problem before.

      • Lucas December 31, 2018 at 7:09 am #

        Hi Adrian,

        Thanks for your tutorial. I also have the same situation. The video play just like a fast forward mode. While I play the video using vlc player, it’s speed shows normally. And I try to run it in real-time, it also appears normally.

        My system:
        Ubuntu 18.04
        i7 8700 / 8G RAM / 240SSD / GT 1050Ti w/4G RAM

        Thanks a lot!



        • Adrian Rosebrock January 2, 2019 at 9:18 am #

          Are the objects in your video successfully tracked?

          Keep in mind that OpenCV doesn’t care what the FPS of the video is. The goal of OpenCV is to process video frames as fast as it possibly can. The faster OpenCV can process frames, the faster it can process your video. That’s a feature not a bug.

  30. Ashkan October 22, 2018 at 12:11 pm #

    Hi Adrian,

    By any chance do you have any tutorial or project in stereo calibration and 3d tracking?


    • Adrian Rosebrock October 22, 2018 at 12:58 pm #

      Sorry, I do not.

  31. Sarwat November 24, 2018 at 7:34 am #

    Thanks for your tutorial
    how i can detect multiple object in stream video but without selecting them by mouse, i want these objected to be defined and it search for them .
    like here in car race, the script will check the cars automatic and track them

    • Adrian Rosebrock November 25, 2018 at 9:01 am #

      Take a look at this tutorial where I provide an example of what you’re looking for.

  32. Fanuel November 25, 2018 at 4:23 am #

    hi adrian, I was wondering if I could track each object individually and store their real-world position or coordinates in a txt or csv file every half a second…

  33. Kirill November 29, 2018 at 8:33 am #

    Hi Adrian, when will the article about tracking objects using several processes and the distribution of the load on the calculations in several cores of our processor?

  34. Mark November 29, 2018 at 12:20 pm #

    Adrian Hi,

    Can this code be implemented of RPi 3 as is?
    Or some problems should be accounted for?

    • Adrian Rosebrock November 30, 2018 at 8:54 am #

      Tracking multiple objects on a Raspberry Pi using these methods is going to be far too slow. You cannot easily use a Raspberry Pi with these tracking algorithms.

  35. Anesh Muthiah January 18, 2019 at 9:44 am #

    I loved your tutorial. Can you tell me how to remove history of bounding boxes in multi object tracker?

    • Adrian Rosebrock January 22, 2019 at 9:39 am #

      You need to re-instantiate the object, unfortunately.

  36. Elena January 22, 2019 at 11:13 pm #

    Hello Adrian,
    Thank you for your tutorial.
    I want to add tracking to YOLOv3. I’m a bit puzzled on how I can modify the code to track multiple objects with YOLOv3. I want to include the class of object with its confidence level while tracking the object. What should I do?

    • Adrian Rosebrock January 25, 2019 at 7:33 am #

      See this tutorial where I cover the exact answer to your question (only using a SSD).

  37. Miranda February 16, 2019 at 11:08 pm #

    Hi Adrian, Thank you for the great tutorial! In this code, we need to press ‘s’ key each time we want to select a bounding box, this way we initialize trackers in different frames. Is it possible to select multiple bounding boxes at the same frame instead? Thanks!

  38. Miranda February 21, 2019 at 8:06 pm #

    I figured out how to do this. The user can substitute cv2.selectROI with cv2.selectROIs and be able to choose multiple bounding boxes at once.

    • Adrian Rosebrock February 22, 2019 at 6:21 am #

      Thank you for sharing, Miranda! That is helpful to know 🙂

  39. Kedar February 24, 2019 at 2:22 am #

    Sir Thank You So Much For Your Best Help..!! 🙂

    my questions is : ” can we select ROI automatically? According to shape or colour of perticular object like ‘ball’ ? “

    • Adrian Rosebrock February 27, 2019 at 6:07 am #

      Yes, absolutely. I cover that very question in this tutorial.

  40. mido March 1, 2019 at 9:56 am #

    i am a beginner in pyhton , i cant put the video directory , how should i put it ? ap.add_argument(“-v”, “–video”, type=str,

  41. Aditi March 20, 2019 at 10:28 am #

    Can u please tell me how to save the videos after tracking in this code

    • Adrian Rosebrock March 22, 2019 at 8:56 am #

      Sure, all you need is the “cv2.VideoWriter” function. See this tutorial for a good example.

  42. Abhinna Pradhan March 26, 2019 at 9:39 pm #

    Hi.. Adrian……After running the code I am getting output without any tracking i.e. same as input video….Plz tell me what I am doing wrong.

  43. Azad April 12, 2019 at 1:02 am #

    Hi, adrian i gone through your this code I found it cool.. But what I want it to detect automatically any object without clicking… Please help if you can

    • Adrian Rosebrock April 12, 2019 at 11:20 am #

      See this tutorial where I do exactly that.

  44. khiro June 21, 2019 at 4:33 pm #

    hello adrian , thx
    how i can to create/destroy for example 10 trackers ??
    if i track an object to an target , how i can destroy this thacker and re us after for new object ?

    • Adrian Rosebrock June 26, 2019 at 1:43 pm #

      You can use the “del” Python statement to delete the object and have Python’s garbage collector reclaim resources.

  45. Andy Woods June 25, 2019 at 2:38 am #

    Just wondering if it would help to specify package versions somewhere

  46. Bharath J July 16, 2019 at 6:37 am #


    Great work.
    Is this possible to integrate pre-trained model and custom model in a single python script.

  47. Raj July 31, 2019 at 4:48 pm #

    Hi, I am trying to use the KCF tracker from your code and after initialising the bounding box it never updates in future frames. I am on opencv 3.3.1 and running this on an ubuntu machine. do you have any debugging tips or ideas on why it might not be working?

    • Adrian Rosebrock August 7, 2019 at 12:43 pm #

      OpenCV 3.3 is pretty old at this point. Try upgrading your OpenCV install.

  48. Priyansh August 10, 2019 at 9:59 am #

    Hey thanks for this awesome blog.
    Just one question can we use opencv tracker with model like mobilenet, yolo.
    I tried using it but the tracker update gives worng co-ordinate

    • Adrian Rosebrock August 16, 2019 at 5:53 am #

      Yes, you can. See this tutorial for an example.

  49. LDag August 21, 2019 at 5:20 am #

    Thanks for the tutorial!
    I had to add a sleep(0.8) on line 87, in the while loop, because the video was to fast.

  50. swa sweety September 7, 2019 at 2:26 am #

    Hi Sir…
    I have some doubts…Is it possible to track all the medical equipment’s usages using OpenCV python and raspberry pi 3…inorder to prevent the spread of infectious diseases towards other patients?

  51. kadir September 17, 2019 at 8:38 am #

    Hey thanks for this all tutorials.
    I’m working on your all detection project. I just wondering. How can select and use different detections. For example: we detected 2 different object(or more) same time like in this video. And i want to define or fallow this detects. The player who has goal will has a goal value in database. I need some advise about that Adrian.

    • Adrian Rosebrock September 19, 2019 at 9:59 am #

      If I’m understanding your question correctly, I think you need something like this tutorial.

  52. Anup Swarnkar September 25, 2019 at 3:49 am #

    Hi Ardrian,
    Can I pass contours as input instead of manually drawing the bounding boxes? Also how to handle a situation when an object is out of the frame and comes back?

    • Adrian Rosebrock September 25, 2019 at 10:31 am #

      Yes, just compute the bounding box of the contour and use that to seed the tracker.

Before you leave a comment...

Hey, Adrian here, author of the PyImageSearch blog. I'd love to hear from you, but before you submit a comment, please follow these guidelines:

  1. If you have a question, read the comments first. You should also search this page (i.e., ctrl + f) for keywords related to your question. It's likely that I have already addressed your question in the comments.
  2. If you are copying and pasting code/terminal output, please don't. Reviewing another programmers’ code is a very time consuming and tedious task, and due to the volume of emails and contact requests I receive, I simply cannot do it.
  3. Be respectful of the space. I put a lot of my own personal time into creating these free weekly tutorials. On average, each tutorial takes me 15-20 hours to put together. I love offering these guides to you and I take pride in the content I create. Therefore, I will not approve comments that include large code blocks/terminal output as it destroys the formatting of the page. Kindly be respectful of this space.
  4. Be patient. I receive 200+ comments and emails per day. Due to spam, and my desire to personally answer as many questions as I can, I hand moderate all new comments (typically once per week). I try to answer as many questions as I can, but I'm only one person. Please don't be offended if I cannot get to your question
  5. Do you need priority support? Consider purchasing one of my books and courses. I place customer questions and emails in a separate, special priority queue and answer them first. If you are a customer of mine you will receive a guaranteed response from me. If there's any time left over, I focus on the community at large and attempt to answer as many of those questions as I possibly can.

Thank you for keeping these guidelines in mind before submitting your comment.

Leave a Reply