Chapter 8. Creating Your Own Motion Detection and Tracking System

In the previous chapter, we studied the basics of the OpenCV library. We set up our Pi for OpenCV programming with Python and implemented a simple project to track an object based on the color in OpenCV with a live webcam feed. In this chapter, we will learn about some more advanced concepts and implement one more project based on OpenCV. In this chapter, we will learn about the following topics:

  • Thresholding
  • Noise reduction
  • Morphological operations on images
  • Contours in OpenCV
  • Real-time motion detection and tracking

Thresholding images

Thresholding is a way to segment images. Although thresholding methods and algorithms are available for colored images, it works best on grayscale images. Thresholding usually (but not always) converts grayscale images into binary images (in a binary image, each pixel can have only one of the two possible values: white or black). Thresholding the image is usually the first step in many image processing applications.

The way thresholding works is very simple. We define a threshold value. For a pixel in a grayscale image, if the value of grayscale intensity is greater than the threshold, then we assign a value to the pixel (for example, white); otherwise, we assign a black value to the pixel. This is the simplest form of thresholding. Also, there are many other variations of this method, which we will look at now.

In OpenCV, the cv2.threshold() function is used to threshold images. Its input includes grayscale image, threshold values, maxVal, and threshold methods as parameters and returns the thresholded image as the output. maxVal is the value assigned to the pixel if the pixel intensity is greater (or lesser in some methods) than the threshold. There are many threshold methods available in OpenCV; in the beginning, the simplest form of thresholding we saw was cv2.THRESH_BINARY. Let's look at the mathematical representation of some of the threshold methods.

Say (x,y) is the input pixel; then, operations for threshold methods will be as follows:

  • cv2.THRESH_BINARY

    If intensity(x,y)> threshold, then set intensity(x,y)=maxVal; else, set intensity(x,y) = 0

  • cv2.THRESH_BINARY_INV

    If intensity(x,y)> threshold, then set intensity(x,y)=0; else, set intensity(x,y) = maxVal

  • cv2.THRESH_TRUNC

    If intensity(x,y)> threshold, then set intensity(x,y)=threshold; else, leave intensity(x,y) as it is

  • cv2.THRESH_TOZERO

    If intensity(x,y)> threshold, then leave intensity(x,y) as it is; else, set intensity(x,y) = 0

  • cv2.THRESH_TOZERO_INV

    If intensity(x,y)> threshold, then set intensity(x,y)=0; else, leave intensity(x,y) as it is

The demonstration of the threshold functionality usually works best on grayscale images with a gradually increasing gradient. In the following example, we are setting the value of the threshold as 127, so the image is segmened in two sets of pixels depending on the value of their intensity:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('gray21.512.tiff',0)
th=127
max_val=255
ret,o1 = cv2.threshold(img,th,max_val,cv2.THRESH_BINARY)
ret,o2 = cv2.threshold(img,th,max_val,cv2.THRESH_BINARY_INV)
ret,o3 = cv2.threshold(img,th,max_val,cv2.THRESH_TOZERO)
ret,o4 = cv2.threshold(img,th,max_val,cv2.THRESH_TOZERO_INV)
ret,o5 = cv2.threshold(img,th,max_val,cv2.THRESH_TRUNC)

titles = ['Input Image','BINARY','BINARY_INV','TOZERO','TOZERO_INV','TRUNC']
output = [img, o1, o2, o3, o4, o5]

for i in xrange(6):
    plt.subplot(2,3,i+1),plt.imshow(output[i],cmap='gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()

The output of the preceding code will be as follows:

Thresholding images

Otsu's method

Otsu's method for thresholding automatically determines the value of the threshold for images that have two peaks in their histogram (bimodal histograms). The following is a bimodal histogram:

Otsu's method

This usually means that the image has background and foreground pixels and Otsu's method is the best way to separate these two sets of pixels automatically without specifying a threshold value.

Otsu's method is not the best way for those images that are not in the background and foreground model and may provide improper output if applied.

This method is applied in addition to other methods, and the threshold is passed as 0. Try out the following code:

ret,output=cv2.threshold(image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

The output of this will be as follows. This is a screenshot of a tank in a desert:

Otsu's method
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset