Navigating the Future with Dynamic Face Detection
Welcome to the forefront of dynamic vision! In this guide, we’ll embark on a captivating journey into the realm of precision face tracking using OpenCV with Python and pan/tilt servos. Imagine the possibilities as your projects gain the ability to autonomously follow and engage with faces in real-time. From the intricacies of face detection to the dynamic control of servos, this tutorial is your gateway to creating responsive, intelligent systems. Let’s delve into the art of guiding vision with unparalleled accuracy and finesse.
What’s Covered:
- The Face Tracking Program.
- Breaking Down the Code.
The Face Tracking Program
We are going to jump straight into this, below is the full code for the program. Open a new file in Visual Studio then copy and paste the code below:
Python Code:
from adafruit_servokit import ServoKit
import cv2
import time
width=640
height=480
kit=ServoKit(channels=16)
pan=0
tilt=135
#Servo [0]=Left & Right
#Servo [1]=Up & Down
kit.servo[0].angle=pan
kit.servo[1].angle=tilt
camera=cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH,width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT,height)
face_cascade=cv2.CascadeClassifier('/home/meganano/Desktop/Python-AI/haarcascades/haarcascade_frontalface_default.xml')
while True:
ret, frame=camera.read()
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces=face_cascade.detectMultiScale(gray,1.3,5)
#Tracking
for (x,y,w,h) in faces:
#Put Box Around Face
cv2.rectangle(frame,(x,y),(x+w,y+h),(100,255,100),2)
Xcent=x+w/2
Ycent=y+h/2
errorPan=Xcent-width/2
errorTilt=Ycent-height/2
if abs(errorPan)>15:
pan=pan-errorPan/30
if abs(errorTilt)>15:
tilt=tilt+errorTilt/30
#Print Servo Positions
print(pan)
print(tilt)
#Pan Range Limit
if pan>180:
pan=180
print('Pan out of range')
if pan<0: pan=0 print('Pan out of range') #Tilt Range Limit if tilt>180:
tilt=180
print('Tilt out of range')
if tilt<0:
tilt=0
print('Tilt out of range')
kit.servo[0].angle=pan
kit.servo[1].angle=tilt
roi_gray=gray[y:y+h, x:x+w]
roi_color=frame[y:y+h, x:x+w]
#Show Frame
cv2.imshow('Face Tracker',frame)
cv2.moveWindow('Face Tracker',0,0)
if cv2.waitKey(1)==ord('q'):
break
camera.release()
cv2.destroyAllWindows()
#Reset Camera Position
kit.servo[0].angle=0
kit.servo[1].angle=135
print('Program Terminated')Breaking Down the Code
Import the Libraries
from adafruit_servokit import ServoKit import cv2 import time
Create the ServoKit Object.
kit=ServoKit(channels=16)
Create Pan and Tilt Objects and Apply Them to the ServoKit Object.
pan=0 tilt=135 kit.servo[0].angle=pan kit.servo[1].angle=tilt
Load the Face Cascade Classifier:
OpenCV provides pre-trained cascade classifiers for detecting faces. You can download the XML file for the face cascade classifier from the OpenCV GitHub repository. Once downloaded, load the classifier using the cv2.CascadeClassifier function.
face_cascade = cv2.CascadeClassifier('path_to_xml_file/haarcascade_frontalface_default.xml')Initialize the Video Capture:
Use the cv2.VideoCapture function to initialize the video capture. You can pass the argument 0 to capture video from the default camera or specify the path to a video file.
cap = cv2.VideoCapture(0)Read and Process Frames:
Continuously read frames from the video capture and process them for face tracking. Convert the frames to grayscale for better face detection performance.
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)Detect Faces in the Frame:
Use the detectMultiScale function of the face cascade classifier to detect faces in the grayscale frame.
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
Adding Bounding Box to Faces:
Iterate over the detected faces and draw rectangles around them on the frame.
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)Track the Faces:
Create conditions using mathematical operations to calculate the Pan and Tilt servo positions.
Xcent=x+w/2
Ycent=y+h/2
errorPan=Xcent-width/2
errorTilt=Ycent-height/2
if abs(errorPan)>15:
pan=pan-errorPan/30
if abs(errorTilt)>15:
tilt=tilt+errorTilt/30Add Error Correction:
By adding range limitations, we can fix out of range errors.
if pan>180:
pan=180
print('Pan out of range')
if pan<0: pan=0
print('Pan out of range')
if tilt>180:
tilt=180
print('Tilt out of range')
if tilt<0:
tilt=0
print('Tilt out of range')Control servo positions:
By applying the updated Pan and Tilt positions each time through the loop.
kit.servo[0].angle=pan kit.servo[1].angle=tilt roi_gray=gray[y:y+h, x:x+w] roi_color=frame[y:y+h, x:x+w]
Display the Frame:
Show the processed frame with the tracked faces using the cv2.imshow function.
cv2.imshow('Face Tracking', frame)Exit the Program:
Add a condition to exit the loop and release the video capture when a specific key (e.g., ‘q’) is pressed.
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()Conclusion
Congratulations, visionary! You’ve successfully navigated the intricacies of tracking faces with pan/tilt servos using OpenCV. By mastering the art of dynamic face detection, you’ve opened the door to a world of interactive, intelligent projects. As you reflect on the journey, remember that this is just the beginning. The skills you’ve acquired here will serve as a solid foundation for more advanced computer vision endeavors.
Stay tuned for upcoming posts where we’ll continue to explore the frontiers of dynamic vision. From object recognition to color tracking, the possibilities are endless. Your projects are now equipped to engage with the world in a whole new way.
In the next installment of our OpenCV for Beginners guide we will be Detecting and Tracking Colors
That’s All Folks!
You can find all of our OpenCV guides here: OpenCV for Beginners