Skip to content

Beginners Opencv · Tutorials

Optical Flow with Lucas-Kanade method – OpenCV 3.4 with python 3 Tutorial 31

Access community, courses and source codes
Logo

AI Vision Academy

Access the code of this tutorial, computer vision courses and an exclusive community on AI Vision Academy

  • Access to over 50+ source codes from Pysource.com/blog
  • Dedicated video courses about computer vision
  • Access to an exclusive community of professionals
  • Real-World AI Projects – Get hands-on experience building practical AI Computer Vision solutions with a structured path.
  • Monthly Coaching Calls – get support and any of your questions answered

Subscribe to our newsletter to learn more

How work Optical Flow?

Optical flow is the vector who describe the moviment of the object betweent two consecutive frames.

If I want to track an object what can I do? There is an algorithm called Lucas-Kanade, let’s take this toothbrush as an example, I indicate a point that I want to trace in a specific area. The algorithm checks the object in the previous area and if it does not find it it assumes that it has moved and then selects a new point.

For more details on how the function works, I suggest you read the official OpenCv guide: Optical Flow with Lucas-Kanade method

The Lucas-Kanade algorithm needs some conditions to work. For example, the object must move really close, no matter if it is fast because the algorithm analyzes frame by frame.

Optical flow with Lucas-Kanade example code

The first step is to call the usual OpenCV and Numpy in our code, then we have to write the code to retrieve the data frame by frame from the camera. I recommend you also read my article on the subject: Control webcam with servo motor and raspberry pi – Opencv with Python which could help you with your project.

Select the point

The first necessary step is to select a point. To do this you need a mouse callback function

# Mouse function
def select_point(event, x, y, flags, params):
    global point, point_selected, old_points
    if event == cv2.EVENT_LBUTTONDOWN:
        point = (x, y)
        point_selected = True
        old_points = np.array([[x, y]], dtype=np.float32)

cv2.namedWindow("Frame")
cv2.setMouseCallback("Frame", select_point)

point_selected = False
point = ()
old_points = np.array([[]])

We need to initialize the arrays and remember that to be used with OpenCV they must be converted to nparray.

calcOpticalFlowPyrLK() function

Now we can use the calcOpticalFlowPyrLK () tracking function. The first thing to do is to convert the frame to grayscale format.

    _, frame = cap.read()
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

We therefore consider the parameters to be used in the optical-flow function:

  • old_gray : old frame array
  • gray_frame : current frame
  • old_point : array with old point
  • None : empy param
  • **lk_params : some configuration about the function
# Lucas kanade params
lk_params = dict(winSize = (15, 15),
maxLevel = 4,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

...

        new_points, status, error = cv2.calcOpticalFlowPyrLK(old_gray, gray_frame, old_points, None, **lk_params)
        old_gray = gray_frame.copy()
        old_points = new_points

        x, y = new_points.ravel()

I have tried to make this as simple as possible and surely you can take more points as a reference and everything can be improved.

8 comments

  1. Hi there. Could help with an video analysis. I want to calculate velocity of diferent joints during an kick to a ball. Is it possible to change this codes and choose multiple points?

    1. Yes it’s possible to choose multiple points. Actually the code is done for that, I just choosed one point to make it easier for people to understand it.
      You should first track the points using corners detection and then apply the optical flow method for all the points.

  2. can we use the mouse callback function to track several points that I am interested in at the same time, except for using corners detection function

  3. Thanks for sharing the projects, I was wondering this approach can be used to find a movement of a downside camera whereas it is like an optic mouse can detect movement & direction
    Thanks

  4. This method of tracking is great!. Seems more reliable for tracking moving objects! This might be along shot but do you think you are able to do this using tkinter or some other gui other than using inshow as a form. The problem using imshow is that the video and the whole program pauses when you move the form not so good when tracking objects.

  5. Hello…
    Could you tell me how to find the outermost coordinates?
    That would be the lower left-hand corner and the upper right-hand corner.
    Best regards.

Join the discussion