rotated face detection

与世无争的帅哥 提交于 2019-11-30 01:34:45

Here's a simple one I wrote with Python cv2

It's not the most efficient thing, and it uses the naive way suggested by etarion, but it works fairly well for just normal head tilting (It detect anything from -40 to 40 head tilt, which is roughly as much as you can tilt your head staying upright.

import cv2
from math import sin, cos, radians

camera =  cv2.VideoCapture(0)
face = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")

settings = {
    'scaleFactor': 1.3, 
    'minNeighbors': 3, 
    'minSize': (50, 50), 
    'flags': cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT|cv2.cv.CV_HAAR_DO_ROUGH_SEARCH
}

def rotate_image(image, angle):
    if angle == 0: return image
    height, width = image.shape[:2]
    rot_mat = cv2.getRotationMatrix2D((width/2, height/2), angle, 0.9)
    result = cv2.warpAffine(image, rot_mat, (width, height), flags=cv2.INTER_LINEAR)
    return result

def rotate_point(pos, img, angle):
    if angle == 0: return pos
    x = pos[0] - img.shape[1]*0.4
    y = pos[1] - img.shape[0]*0.4
    newx = x*cos(radians(angle)) + y*sin(radians(angle)) + img.shape[1]*0.4
    newy = -x*sin(radians(angle)) + y*cos(radians(angle)) + img.shape[0]*0.4
    return int(newx), int(newy), pos[2], pos[3]

while True:
    ret, img = camera.read()

    for angle in [0, -25, 25]:
        rimg = rotate_image(img, angle)
        detected = face.detectMultiScale(rimg, **settings)
        if len(detected):
            detected = [rotate_point(detected[-1], img, -angle)]
            break

    # Make a copy as we don't want to draw on the original image:
    for x, y, w, h in detected[-1:]:
        cv2.rectangle(img, (x, y), (x+w, y+h), (255,0,0), 2)

    cv2.imshow('facedetect', img)

    if cv2.waitKey(5) != -1:
        break

cv2.destroyWindow("facedetect")
Tushar Aggarwal

Personally, I don't know of a library. But, what I can say is, use an eye detection Haar Cascade, and draw a line between the eyes. Then, you can use the atan function and find the angle by which the head is rotated. (Assuming that the person has both eyes on the same horizontal level when head is not rotated)

deg = atan( (leftEye.y - rightEye.y) / (leftEye.x - rightEye.x) )

Once you get this angle, rotate the image you have by negative deg degrees and you should have a face which can be detected using the Haar Cascades.

Naive way:

  • Generate list of angles (for example, from -170 to 180 in 10 degree steps)
  • For each angle n in the list:
    • Rotate image by n degrees
    • Run face detector on rotated image
    • Compute the position of the detected faces in the original image (undo the rotation)
  • Perform non-maximum suppression on the joined result from all angles (you will likely get multiple detections from neighbouring angles)

Methods for face detection based on color histogram are independent of face orientation.

I had been dealing with the same problem of face detection for non-frontal images. Try using Multi Task CNN. It's the best solution for face detection and alignment. It is able to deal with problems like various poses, lighting, occlusion.

The paper is available at Link. The code is available on GitHub at Link. I used the python implementation and the results are outstanding. Although the code is a little slow if the image has a lot of faces.

Although if you want to stick to OpenCV, then a new deep learning model for face detection has been added to OpenCV. The results are not as good as Multi Task CNN. There's an implementation of OpenCV Deep Learning Model for Face Detection at pyimagesearch Link

you can use bag of words/bag of features method with constrains AAM,ASM methods. but they also can give not optimal solution converges not to global maximum.

also haar-like-features are just collection of features and you can use rotation invariant features and put it then in adaboost classifer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!