Python 3 OpenCV Detect Face Tilt in Degrees From Live Webcam

Face Tilt Detection in degrees from live webcam using Python 3 OpenCV script. The output will be displayed inside a GUI Desktop App.

This code is pretty useful for face angle detection or rotated face detection using Python programming language.

Download Pre-trained XML Classifiers

To detect the face and eyes of the user, we need 2 pre-trained XML classifiers. You can download these classifiers from the links given below.


pip install opencv-python
pip install numpy

code.py

import cv2 as cv
import numpy as np


# 0 for webcam feed ; add "path to file"
# for detection in video file
capture = cv.VideoCapture(0)
face_cascade = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier("haarcascade_eye.xml")

while True:
	ret, frame = capture.read()
	gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
	faces = face_cascade.detectMultiScale(gray, 1.1, 5)
	x, y, w, h = 0, 0, 0, 0
	for (x, y, w, h) in faces:
		cv.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
		cv.circle(frame, (x + int(w * 0.5), y +
						int(h * 0.5)), 4, (0, 255, 0), -1)
	eyes = eye_cascade.detectMultiScale(gray[y:(y + h), x:(x + w)], 1.1, 4)
	index = 0
	eye_1 = [None, None, None, None]
	eye_2 = [None, None, None, None]
	for (ex, ey, ew, eh) in eyes:
		if index == 0:
			eye_1 = [ex, ey, ew, eh]
		elif index == 1:
			eye_2 = [ex, ey, ew, eh]
		cv.rectangle(frame[y:(y + h), x:(x + w)], (ex, ey),
					(ex + ew, ey + eh), (0, 0, 255), 2)
		index = index + 1
	if (eye_1[0] is not None) and (eye_2[0] is not None):
		if eye_1[0] < eye_2[0]:
			left_eye = eye_1
			right_eye = eye_2
		else:
			left_eye = eye_2
			right_eye = eye_1
		left_eye_center = (
			int(left_eye[0] + (left_eye[2] / 2)),
		int(left_eye[1] + (left_eye[3] / 2)))
		
		right_eye_center = (
			int(right_eye[0] + (right_eye[2] / 2)),
		int(right_eye[1] + (right_eye[3] / 2)))
		
		left_eye_x = left_eye_center[0]
		left_eye_y = left_eye_center[1]
		right_eye_x = right_eye_center[0]
		right_eye_y = right_eye_center[1]

		delta_x = right_eye_x - left_eye_x
		delta_y = right_eye_y - left_eye_y
		
		# Slope of line formula
		angle = np.arctan(delta_y / delta_x)
		
		# Converting radians to degrees
		angle = (angle * 180) / np.pi

		# Provided a margin of error of 10 degrees
		# (i.e, if the face tilts more than 10 degrees
		# on either side the program will classify as right or left tilt)
		if angle > 10:
			cv.putText(frame, 'RIGHT TILT :' + str(int(angle))+' degrees',
					(20, 30), cv.FONT_HERSHEY_SIMPLEX, 1,
					(0, 255, 0), 2, cv.LINE_4)
		elif angle < -10:
			cv.putText(frame, 'LEFT TILT :' + str(int(angle))+' degrees',
					(20, 30), cv.FONT_HERSHEY_SIMPLEX, 1,
					(0, 255, 0), 2, cv.LINE_4)
		else:
			cv.putText(frame, 'STRAIGHT :', (20, 30),
					cv.FONT_HERSHEY_SIMPLEX, 1,
					(0, 255, 0), 2, cv.LINE_4)

	cv.imshow('Frame', frame)

	if cv.waitKey(1) & 0xFF == 27:
		break
capture.release()
cv.destroyAllWindows()

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.