Previous, Last time Generate candidate images with the target face. I mentioned how to get it, but this time I will introduce how to extract the face area part from them and generate a face image.
To generate a face image, trim only the area where the face is reflected from the candidate images, and generate the trimmed area as a new image = face image. However, it takes a lot of time and effort to do this work manually, so we will use the following face recognition API (library) to solve it even a little.
If you use these APIs, it is possible to automatically extract only the face area from the candidate image, but this time we will explain the method using OpenCV and dlib. The specific flow of face image generation is basically the same, as follows.
The above process shall be defined by the face_detect method in the code below.
# -*- coding: utf-8 -*-
import glob
#Directory path containing candidate images
IMG_PATH = "/home/hoge/image/"
def face_detect(img_list):
#Define face image generation process with this method
return
if __name__ == '__main__':
#Get a candidate image from the specified directory and generate a face image using API etc.
images = glob.glob(IMG_PATH + '*.jpg')
face_detect(images)
dlib dlib is a library that summarizes image processing and machine learning functions developed for C ++, but it can also be used with python. (For how to install dlib in Mac environment, please refer to this article etc.)
dlib provides a get_frontal_face_detector
method for face detection, so use that.
In addition, if you use SVM-related methods, which are a type of non-linear classifier with high discrimination accuracy, more advanced detection is possible, but this time we will prioritize ease of use.
The face image generation code that actually uses the get_frontal_face_detector
method is as follows.
import dlib
import cv2
def face_detect(img_list):
#Identifyer call to detect face area
detector = dlib.get_frontal_face_detector()
#Get coordinate information by applying the candidate image to the classifier
for img_path in img_list:
#Candidate image for trimming (color mode)
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
#Reassemble the image array and input it to the classifier to acquire coordinate information that seems to be the face area.
cv_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
faces = detector(cv_img, 1)
#Face image generation if face area is detected
img_count = 1
for face in faces:
#Get candidate image size
height, width = img.shape[:2]
#Get the coordinate points of the face area
top = face.top()
bottom = face.bottom()
left = face.left()
right = face.right()
#Ignore irregular facial areas
if not top < 0 and left < 0 and bottom > height and right > width:
break
else:
#Face area trimming
dst_img = img[top:bottom, left:right]
#Face image size Normalized and saved
face_img = cv2.resize(dst_img, (64,64))
new_img_name = str(img_count) + '.jpg'
cv2.imwrite(new_img_name, face_img)
img_count += 1
OpenCV and dlib handle different pixel values of RGB (Red / Green / Blue), which is the color information of the image.
In OpenCV, RGB (Red / Green / Blue) pixel values are stored in the array in the order of BGR, but in dlib, they are stored in the order of RGB, so it is necessary to convert the array structure using the cvtColor
method. There is.
In addition, get_frontal_face_detector rarely returns the coordinate values outside the image area as the coordinate information of the face area. This is because the face is reflected at the edge of the image, so a part of the face is often missing, and it is difficult to use it as learning data as it is as a face image, so ignore it as an irregular face area. I have.
OpenCV
OpenCV is an image processing library that can be used in C ++, Python, etc., and is familiar in this article series, but here the CascadeClassifier
class provided as a cascade classifier class To use.
By using this class, it is possible to build a classifier corresponding to various objects depending on the contents of the xml file that stores the learning results to be read when building the classifier.
This time, by referring to haarcascade_frontalface_default.xml
(provided site) provided by OpenCV, as a face detector I will use it.
import cv2
#XML file path referenced by the HaarCascade classifier
XML_PATH = "./haarcascade_frontalface_default.xml"
def face_detect(img_list):
#Set face area classifier
classifier = cv2.CascadeClassifier(xml_path)
#Face image generation if face area is detected
img_count = 1
for img_path in img_list:
#Color image for trimming
org_img = cv2.imread(img_path, cv2.IMREAD_COLOR)
#Grayscale image for classifier input
gray_img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
#Input the candidate image (grayscale image) into the classifier and acquire the coordinate information that seems to be the face area.
face_points = classifier.detectMultiScale(gray_img, \
scaleFactor=1.2, minNeighbors=2, minSize=(1,1))
#A face image is generated by trimming a color image from the identification result (rectangular coordinate information).
for points in face_points:
#Get the coordinate points of the face area
x, y, width, height = points
#Face area trimming
dst_img = org_img[y:y+height, x:x+width]
#Face image size Normalized and saved
face_img = cv2.resize(dst_img, (64,64))
new_img_name = str(img_count) + '.jpg'
cv2.imwrite(new_img_name, face_img)
img_count += 1
In the method using OpenCV, two types of candidate images are prepared: a color image for trimming and a grayscale image for classifier input. This is because the detectMultiScale
method does not support input of color images.
The detectMultiScale
method takes the following parameter arguments.
Try object detection (detectMultiScale) with different parameters (minNeighbors) Try object detection (detectMultiScale) with different parameters (scaleFactor edition)
dlib
OpenCV
detectMultiScale
method.This is simple, but this time I explained how to generate a face image from a candidate image.
Recommended Posts