Object Tracking

This scripts allow to track a specific object on real time, we draw a circul on thata object and start to move following this object.

Enter into python virtual environment:

# workon cv

Now the first thing we need to detect and determine is the object that we want to be tracked. So for that we need to execute:

# python objectdata.py --filter HSV --webcam

This is going to bring us a 3 different windows. The firs windows show our camera, the second a black & white camera and the third one is a controller that we could adjust so we could leave the object that we want in white and the rest of the scenario on black.

Get Object Data script

Now we are going to explain the code.

We need to import the libraries that we are going to use.

import cv2
import argparse
from operator import xor

Then we define the controllers so we can edit and modificate the object that we want to track

def setup_trackbars(range_filter):
    cv2.namedWindow("Object detector data", 0)

    for i in ["MIN", "MAX"]:
        v = 0 if i == "MIN" else 255

        for j in range_filter:
            cv2.createTrackbar("%s_%s" % (j, i), "Object detector data", v, 255, callback)

On get_arguments function we define the arguments that we want that the user need to introduces, such as what filter want to use (RGB or HSV)

def get_arguments():
    ap = argparse.ArgumentParser()
    ap.add_argument('-f', '--filter', required=True,
                    help='Range filter. RGB or HSV')
    ap.add_argument('-w', '--webcam', required=False,
                    help='Use webcam', action='store_true')
    ap.add_argument('-p', '--preview', required=False,
                    help='Show a preview of the image after applying the mask',
                    action='store_true')
    args = vars(ap.parse_args())

    if not args['filter'].upper() in ['RGB', 'HSV']:
        ap.error("Please speciy a correct filter.")

    return args

Then at the main functions we :

  • Read the arguments

  • Get the filter that we are going to apply

  • Open the camera

  • Set up the sliders

  • Start a loop so the filters can be apply at the image of the webcam, converting our image to a new one with the filters apply.

    • We need to get that our object get in white and the rest on black.

while True:
        if args['webcam']:
            ret, image = camera.read()

            if not ret:
                break

            if range_filter == 'RGB':
                frame_to_thresh = image.copy()
            else:
                frame_to_thresh = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

        v1_min, v2_min, v3_min, v1_max, v2_max, v3_max = get_trackbar_values(range_filter)

        thresh = cv2.inRange(frame_to_thresh, (v1_min, v2_min, v3_min), (v1_max, v2_max, v3_max))

        if args['preview']:
            preview = cv2.bitwise_and(image, image, mask=thresh)
            cv2.imshow("Preview", preview)
        else:
            cv2.imshow("Original", image)
            cv2.imshow("Thresh", thresh)

Object Tracking script

As we mention this script allow that an image could be tracked.

Enter into python virtual enviroment:

# workon cv

To execute this code we need to run the next command:

# python object_movement.py

Explaining the code:

We need to import the libraries that we are going to use.

from collections import deque
import numpy as np
import argparse
import imutils
import cv2

We define the parameters that we want to user introduces at args

ap = argparse.ArgumentParser()
ap.add_argument("-b", "--buffer", type=int, default=32,
        help="max buffer size")
args = vars(ap.parse_args())

Define the RGB upper and lower data that we previously get from the first program.

objectLower = (h_min, s_min, v_min)
objectUpper = (h_max, s_max, v_max)

Initialize the list of tracked points, the frame counter and the coordinates deltas

pts = deque(maxlen=args["buffer"])
counter = 0
(dX, dY) = (0, 0)
direction = ""

Initialice the camera and start getting the frames

camera = cv2.VideoCapture(0)

while True:
        # Read each frame of the camera
        (grabbed, frame) = camera.read()

Resize the frame and convert it to HSV, then we constuct a mask for the object, a series of dilatations and erosions to remove any blobs left

frame = imutils.resize(frame, width=600)
hv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

mask = cv2.inRange(hsv, objectLower, objectUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)

Then we find the contours in the mask that we create.

 cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
 center = None

Validate if at least one contours exist, then get the larges contour in the mask and then use it to get minium enclosing circle.

if len(cnts) > 0:
                c = max(cnts, key=cv2.contourArea)
                ((x, y), radius) = cv2.minEnclosingCircle(c)
                M = cv2.moments(c)
                center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

                if radius > 10:
                        cv2.circle(frame, (int(x), int(y)), int(radius),
                                (0, 255, 255), 2)
                        cv2.circle(frame, center, 5, (0, 0, 255), -1)
                        pts.appendleft(center)

Loop over the set of tracked points, if either of the tracked points are none, ignore them, otherwise compute the thickness of the line and draw the connecting lines.

 for i in np.arange(1, len(pts)):
                if pts[i - 1] is None or pts[i] is None:
                        continue

                if counter >= 10 and i == 1 and pts[-10] is not None:
                        # compute the difference between the x and y
                        # coordinates and re-initialize the direction
                        # text variables
                        dX = pts[-10][0] - pts[i][0]
                        dY = pts[-10][1] - pts[i][1]

Last updated