1

I am working on a human detection program using OpenCV using Python. I saw this very good example and I ran it on the samples it had. It can detect people regardless where they are facing and has decent overlap detection as well as blurred motion as well.

However, when I was running it on some images I had (mostly knee up, waist up, and chest up photos of people), I found out that the software doesn't quite detect people.

You can get the photos from this link. This is the code I am using:

    # import the necessary packages
    from __future__ import print_function
    from imutils.object_detection import non_max_suppression
    from imutils import paths
    import numpy as np
    import argparse
    import imutils
    import cv2

    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--images", required=True, help="path to images directory")
    args = vars(ap.parse_args())

    # initialize the HOG descriptor/person detector
    hog = cv2.HOGDescriptor()
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

    # loop over the image paths
    imagePaths = list(paths.list_images(args["images"]))
    for imagePath in imagePaths:
            # load the image and resize it to (1) reduce detection time
            # and (2) improve detection accuracy
            image = cv2.imread(imagePath)
            image = imutils.resize(image, width=min(400, image.shape[1]))
            orig = image.copy()

            # detect people in the image
            (rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
                    padding=(8, 8), scale=1.05)

            # draw the original bounding boxes
            for (x, y, w, h) in rects:
                    cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)

            # apply non-maxima suppression to the bounding boxes using a
            # fairly large overlap threshold to try to maintain overlapping
            # boxes that are still people
            rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
            pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)

            # draw the final bounding boxes
            for (xA, yA, xB, yB) in pick:
                    cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)

            # show some information on the number of bounding boxes
            filename = imagePath[imagePath.rfind("/") + 1:]
            print("[INFO] {}: {} original boxes, {} after suppression".format(
                    filename, len(rects), len(pick)))

            # show the output images
            cv2.imshow("Before NMS", orig)
            cv2.imshow("After NMS", image)
            cv2.waitKey(0)

It is pretty straightforward. It goes through the images, finds the people in it, then draws bounding rectangles. If rectangles overlap, they are joined together to prevent false positives and detecting more than 1 person in a single person.

However, as I mentioned above, the code fails to recognize people if parts of their feet aren't present.

Is there a way to make OpenCV recognize people who may only have partial of their body (knee up, waist up, chest up) present in a video? In my use case scenarios, I don't think it will be critical to look for arms and legs, as long as the torso and head is present, I should be able to see it.

halfer
  • 19,824
  • 17
  • 99
  • 186
Razgriz
  • 7,179
  • 17
  • 78
  • 150
  • You can use Haar cascades, which have already been trained for upper-body detection. See [here](http://stackoverflow.com/a/31834603/5008845) and its links – Miki Mar 29 '17 at 17:36
  • @Miki it seems that Haar Cascades that were trained for upper-body detection can only detect the upper body if the whole body is seen? I may be looking a different haar cascade xml file. – Razgriz Mar 31 '17 at 15:12
  • That doesn't make much sense to me... But I never used them, so I can't tell for sure – Miki Mar 31 '17 at 15:14
  • I saw this link http://answers.opencv.org/question/95834/opencv-31-upper-body-detection-not-working-in-any-example/ which made me doubt it, but I think there's another haar cascade xml file available. I'll go try it and update this thread if I get a good result. – Razgriz Mar 31 '17 at 15:24

1 Answers1

0

I found the haar upper body cascade. Though it may not work always (I'll post a new question regarding this), it's a good start.

Here's the code:

import numpy as np
import cv2

img = cv2.imread('path/to/img.jpg',0)

upperBody_cascade = cv2.CascadeClassifier('../path/to/haarcascade_upperbody.xml')    

arrUpperBody = upperBody_cascade.detectMultiScale(img)
if arrUpperBody != ():
        for (x,y,w,h) in arrUpperBody:
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        print 'body found'

cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

But it's not as refined as the solution I lifted off of pyimagesearch.

Razgriz
  • 7,179
  • 17
  • 78
  • 150