Detecting pedestrians in a larger image

What's left to do is to connect the SVM classification procedure with the process of detection. The way to do this is to repeat our classification for every possible patch in the image. This is similar to what we did earlier when we visualized decision boundaries; we created a fine grid and classified every point on that grid. The same idea applies here. We divide the image into patches and classify every patch as either containing a pedestrian or not.

By following these steps, you will be able to detect a pedestrian in an image:

  1. We first have to loop over all possible patches in an image as follows, each time shifting our region of interest by a small number of stride pixels:
In [23]: stride = 16
... found = []
... for ystart in np.arange(0, img_test.shape[0], stride):
... for xstart in np.arange(0, img_test.shape[1], stride):
  1. We want to make sure that we do not go beyond the image boundaries:
...              if ystart + hroi > img_test.shape[0]:
... continue
... if xstart + wroi > img_test.shape[1]:
... continue
  1. Then we cut out the ROI, preprocess it, and classify it:
...              roi = img_test[ystart:ystart + hroi,
... xstart:xstart + wroi, :]
... feat = np.array([hog.compute(roi, (64, 64))])
... _, ypred = svm.predict(feat)
  1. If that particular patch happens to be classified as a pedestrian, we add it to the list of successes:
...              if np.allclose(ypred, 1):
... found.append((ystart, xstart, hroi, wroi))
  1. Because pedestrians could appear not just at various locations but also in various sizes, we would have to rescale the image and repeat the whole process. Thankfully, OpenCV has a convenience function for this multi-scale detection task in the form of the detectMultiScale function. This is a bit of a hack, but we can pass all SVM parameters to the hog object:
In [24]: rho, _, _ = svm.getDecisionFunction(0)
... sv = svm.getSupportVectors()
... hog.setSVMDetector(np.append(sv.ravel(), rho))
  1. Then it's possible to call the detection function:
In [25]: found = hog.detectMultiScale(img_test)

The function will return a list of bounding boxes that contain detected pedestrians.

This seems to work only for linear SVM classifiers. The OpenCV documentation is terribly inconsistent across versions in this regard, so I'm not sure at which version this started or stopped working. Be careful!
  1. In practice, when people are faced with a standard task such as pedestrian detection, they often rely on pre-scanned SVM classifiers that are built into OpenCV. This is the method that I hinted at in the very beginning of this chapter. By loading either cv2.HOGDescriptor_getDaimlerPeopleDetector() or cv2.HOGDescriptor_getDefaultPeopleDetector(), we can get started with only a few lines of code:
In [26]: hogdef = cv2.HOGDescriptor()
... pdetect = cv2.HOGDescriptor_getDefaultPeopleDetector()
In [27]: hogdef.setSVMDetector(pdetect)
In [28]: found, _ = hogdef.detectMultiScale(img_test)
  1. It's easy to plot the test image with matplotlib as shown here:
In [29]: from matplotlib import patches
... fig = plt.figure()
... ax = fig.add_subplot(111)
... ax.imshow(cv2.cvtColor(img_test, cv2.COLOR_BGR2RGB))
  1. Then we can mark the detected pedestrians in the image by looping over the bounding boxes in found:
...      for f in found:
... ax.add_patch(patches.Rectangle((f[0], f[1]), f[2], f[3],
... color='y', linewidth=3,
... fill=False))

The result looks like this:

The preceding screenshot shows detected pedestrians in a test image.

..................Content has been hidden....................

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