Face Alignment with OpenCV and Python (original) (raw)

import os

import cv2

import math

import matplotlib.pyplot as pl

import pandas as pd

from PIL import Image

import numpy as np

def face_detection(img):

`` faces = face_detector.detectMultiScale(img, 1.1 , 4 )

`` if ( len (faces) < = 0 ):

`` img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

`` return img, img_gray

`` else :

`` X, Y, W, H = faces[ 0 ]

`` img = img[ int (Y): int (Y + H), int (X): int (X + W)]

`` return img, cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)

def trignometry_for_distance(a, b):

`` return math.sqrt(((b[ 0 ] - a[ 0 ]) * (b[ 0 ] - a[ 0 ])) + \

`` ((b[ 1 ] - a[ 1 ]) * (b[ 1 ] - a[ 1 ])))

def Face_Alignment(img_path):

`` pl.imshow(cv2.imread(img_path)[:, :, :: - 1 ])

`` pl.show()

`` img_raw = cv2.imread(img_path).copy()

`` img, gray_img = face_detection(cv2.imread(img_path))

`` eyes = eye_detector.detectMultiScale(gray_img)

`` if len (eyes) > = 2 :

`` eye = eyes[:, 2 ]

`` container1 = []

`` for i in range ( 0 , len (eye)):

`` container = (eye[i], i)

`` container1.append(container)

`` df = pd.DataFrame(container1, columns = [

`` "length" , "idx" ]).sort_values(by = [ 'length' ])

`` eyes = eyes[df.idx.values[ 0 : 2 ]]

`` eye_1 = eyes[ 0 ]

`` eye_2 = eyes[ 1 ]

`` if eye_1[ 0 ] > eye_2[ 0 ]:

`` left_eye = eye_2

`` right_eye = eye_1

`` else :

`` left_eye = eye_1

`` right_eye = eye_2

`` right_eye_center = (

`` int (right_eye[ 0 ] + (right_eye[ 2 ] / 2 )),

`` int (right_eye[ 1 ] + (right_eye[ 3 ] / 2 )))

`` right_eye_x = right_eye_center[ 0 ]

`` right_eye_y = right_eye_center[ 1 ]

`` cv2.circle(img, right_eye_center, 2 , ( 255 , 0 , 0 ), 3 )

`` left_eye_center = (

`` int (left_eye[ 0 ] + (left_eye[ 2 ] / 2 )),

`` int (left_eye[ 1 ] + (left_eye[ 3 ] / 2 )))

`` left_eye_x = left_eye_center[ 0 ]

`` left_eye_y = left_eye_center[ 1 ]

`` cv2.circle(img, left_eye_center, 2 , ( 255 , 0 , 0 ), 3 )

`` if left_eye_y > right_eye_y:

`` print ( "Rotate image to clock direction" )

`` point_3rd = (right_eye_x, left_eye_y)

`` direction = - 1

`` else :

`` print ( "Rotate to inverse clock direction" )

`` point_3rd = (left_eye_x, right_eye_y)

`` direction = 1

`` cv2.circle(img, point_3rd, 2 , ( 255 , 0 , 0 ), 2 )

`` a = trignometry_for_distance(left_eye_center,

`` point_3rd)

`` b = trignometry_for_distance(right_eye_center,

`` point_3rd)

`` c = trignometry_for_distance(right_eye_center,

`` left_eye_center)

`` cos_a = (b * b + c * c - a * a) / ( 2 * b * c)

`` angle = (np.arccos(cos_a) * 180 ) / math.pi

`` if direction = = - 1 :

`` angle = 90 - angle

`` else :

`` angle = - ( 90 - angle)

`` new_img = Image.fromarray(img_raw)

`` new_img = np.array(new_img.rotate(direction * angle))

`` return new_img

opencv_home = cv2.__file__

folders = opencv_home.split(os.path.sep)[ 0 : - 1 ]

path = folders[ 0 ]

for folder in folders[ 1 :]:

`` path = path + "/" + folder

path_for_face = path + "/data/haarcascade_frontalface_default.xml"

path_for_eyes = path + "/data/haarcascade_eye.xml"

path_for_nose = path + "/data/haarcascade_mcs_nose.xml"

if os.path.isfile(path_for_face) ! = True :

`` raise ValueError(

`` "opencv is not installed pls install using pip install opencv " ,

`` detector_path, " violated." )

face_detector = cv2.CascadeClassifier(path_for_face)

eye_detector = cv2.CascadeClassifier(path_for_eyes)

nose_detector = cv2.CascadeClassifier(path_for_nose)

test_set = [ "pic.png" ]

for i in test_set:

`` alignedFace = Face_Alignment(i)

`` pl.imshow(alignedFace[:, :, :: - 1 ])

`` pl.show()

`` img, gray_img = face_detection(alignedFace)

`` pl.imshow(img[:, :, :: - 1 ])

`` pl.show()