Face Detection with OpenCV 2

Finally done with my Senior project at college and wow, it was great! Will definitely post about it soon and hopefully will be a good apology for the tardiness of this post.

My project was on Facial Expression Recognition and for starters, I had to process images to detect a face(s) in the image. This is where OpenCV really came useful, since it has built-in capabilities of detecting faces, using something called a Haar Wavelet (which is basically a square wave that you use to apply some digital signal processing to your image) and Cascade Classifiers (a bunch of weighted machine learning classifiers used together).

Now, for its ease and convenience, as well as to maintain forward compatibility with future versions of OpenCV, I decided to ditch the OpenCV1.0 API in favour of the OpenCV2+ API, and moreover, I decided to do it in Python since the numpy library proves very powerful for linear algebra operations and rapid prototyping is easy with Python. But now here comes the big problem: OpenCV 1.0 was really popular (I guess it was because of the Kaehler-Bradski book) and almost all the links on the web show code in OpenCV 1.0 on how to detect faces (which is quite ugly compared to the 2.0 version), be it C or Python. So I jumped right into OpenCV2’s wonderful documentation, but alas, only code in C++. Not to fear, since I have good proficiency in both languages now, and it was just a matter of translating code (This is where iPython came really, really useful for its auto-complete functionality) .

So here I will show you how to detect faces in images with OpenCV2 and Python as succinctly as possible, due to the lack of more documentation, and hopefully you’ll come up with the next-big-thing!

from cv2 import *

# Locate face in image. Using cv2 functions
def detect_face(image):

    # Specify the trained cascade classifier
    face_cascade_name = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"

    # Create a cascade classifier
    face_cascade = cv2.CascadeClassifier()

    # Load the specified classifier
    face_cascade.load(face_cascade_name)

    #Preprocess the image
    grayimg = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
    grayimg = cv2.equalizeHist(grayimg)

    #Run the classifiers
    faces = face_cascade.detectMultiScale(grayimg, 1.1, 2, 0|cv2.cv.CV_HAAR_SCALE_IMAGE, (30, 30))

    print "Faces detected"

    if len(faces) != 0:            # If there are faces in the images
        for face in faces:         # For each face in the image

            # Get the origin co-ordinates and the length and width till where the face extends
            x, y, lx, ly = face[0], face[1], face[2], face[3]

            # Draw rectangles around all the faces
            cv2.rectangle(image, (x, y), (x + lx, y + ly), cv2.cv.RGB(155, 255, 25), 2)

    # Display the images with the faces marked
    cv2.imshow("Detected face", image)

    cv2.waitKey(0)

    return (x, y, lx, ly)


def main():

    # Specify the image to process and pass it to the function
    detect_face(imread('../sample.jpg'))


if __name__ == "__main__":
    main()

And there you go. In just a few dozen lines of code, you have a simple to understand and elegant face detector. It definitely works since I tested it out on plenty of datasets that I had obtained for my project as well as some personal images! So try it out and let me know about your thoughts in the comments.

Eviva!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s