This article is for people who want to recognize faces with Python's OpenCV. In this article, I will explain how to detect faces from images, camera images, mp4 files, and how to cut and save only faces from images.
macOS Catalina 10.15.4 Python 3.7.5 opencv-python 4.2.0.34 numpy 1.18.2
$ pip install opencv-python
.
├── cascades
│ └── haarcascade_frontalface_default.xml
├── image_detect.py
├── images
│ └── 001.jpg
├── trimmed
└── venv
The directory structure is like this. The face detector in the cascades folder is located in lib / python3.7 / site-packages / cv2 / data in the directory where Python is installed or in the virtual environment directory.
import cv2
cascade_path = "./cascades/haarcascade_frontalface_default.xml"
img_path = "./images/001.jpg "
color = (255, 255, 255) #The color of the rectangle that surrounds the detected face
src = cv2.imread(img_path,0)
gray = cv2.cvtColor(src,cv2.cv2.COLOR_BAYER_BG2GRAY)
cascade = cv2.CascadeClassifier(cascade_path)
rect = cascade.detectMultiScale(gray)
if len(rect) > 0:
for x, y, w, h in rect:
cv2.rectangle(src, (x, y), (x+w, y+h), color)
cv2.imshow('detected', src)
cv2.waitKey(0)
cv2.destroyAllWindows()
x, y, w, h correspond to the x coordinate of the upper left of the face, the y coordinate of the upper left of the face, the width of the face, and the height of the face. Also, although not limited to OpenCV, the origin of the xy coordinates is the upper left of the image.
import cv2
cascade_path = "./cascades/haarcascade_frontalface_default.xml"
cascade = cv2.CascadeClassifier(cascade_path)
color = (255, 255, 255) #The color of the rectangle that surrounds the detected face
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rect = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30))
if len(rect) > 0:
for x, y, w, h in rect:
cv2.rectangle(frame, (x, y), (x+w, y+h), color)
cv2.imshow('detected', frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
You can get the camera image by setting the argument of cv2.VideoCapture () to the device number of the camera, but you can also handle the video file by entering the path to the mp4 file.
import cv2
cascade_path = "./cascades/haarcascade_frontalface_default.xml"
img_path = "./images/001.jpg "
out_path = "./trimmed/"
src = cv2.imread(img_path,0)
gray = cv2.cvtColor(src,cv2.cv2.COLOR_BAYER_BG2GRAY)
cascade = cv2.CascadeClassifier(cascade_path)
rect = cascade.detectMultiScale(gray)
if len(rect) > 0:
for i,[x, y, w, h] in enumerate(rect):
img_trimmed = src[y:y + h, x:x + w]
file_name = "{}.jpg ".format(i)
file_path = out_path + file_name
cv2.imwrite(file_path, img_trimmed)
You can get the loop count and the contents of rect at the same time by using enumerate in the for statement. When trimming, take out with slices.
import cv2
import os
cascade_path = "./cascades/haarcascade_frontalface_default.xml"
img_path = "./images/"
out_path = "./trimmed/"
files = os.listdir(img_path)
cascade = cv2.CascadeClassifier(cascade_path)
for file in files:
src = cv2.imread(img_path+file,0)
gray = cv2.cvtColor(src,cv2.cv2.COLOR_BAYER_BG2GRAY)
rect = cascade.detectMultiScale(gray)
if len(rect) > 0:
for i,[x, y, w, h] in enumerate(rect):
img_trimmed = src[y:y + h, x:x + w]
file_name = "{}_{}".format(i,file)
file_path = out_path + file_name
cv2.imwrite(file_path, img_trimmed)
If you put the image you want to crop in the images folder and execute it, it will be saved in the trimmed folder in the format of "{face index number} _ {original file name}".
OpenCV is convenient
Recommended Posts