I made a program that detects faces from multiple image files in folders using openCV, cuts out the face part and saves the image, so this is an introduction. The following are other reference articles about openCV.
-Install OpenCV 3.3 and Python 3.6 on Windows 10 with Anaconda -[Explanation for beginners] openCV face detection mechanism and practice (detectMultiScale) -Specify parameters in openCV face detection to quickly improve detection accuracy -Tips for efficiently detecting a large number of images with openCV
The environmental summary is as follows.
Image file name, number of images, using the code explained in the article "Use parameters for face detection in openCV to quickly improve detection accuracy" The parameters of the trained model and detelcMultiScale can be specified at runtime. I was wondering which source file and output file could be identified from the output file name, but I stopped because it seemed to get in the way when learning with tensorFlow after this.
import cv2, os, argparse, shutil
#Directory to save the cropped image
SAVE_PATH = "./outputs/"
#Basic model parameters
FLAGS = None
#Types of trained models
CASCADE = ["default","alt","alt2","tree","profile","nose"]
#Pass if run directly(Imported and does not pass at runtime)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--cascade",
type=str,
default="alt",
choices=CASCADE,
help="cascade file."
)
parser.add_argument(
"--scale",
type=float,
default=1.3,
help="scaleFactor value of detectMultiScale."
)
parser.add_argument(
"--neighbors",
type=int,
default=2,
help="minNeighbors value of detectMultiScale."
)
parser.add_argument(
"--min",
type=int,
default=80,
help="minSize value of detectMultiScale."
)
parser.add_argument(
"--input_dir",
type=str,
default="./input/",
help="The path of input directory."
)
parser.add_argument(
"--move_dir",
type=str,
default="/done/",
help="The path of moving detected files."
)
#Parameter acquisition and execution
FLAGS, unparsed = parser.parse_known_args()
#Classifier directory(Obtained from)
# https://github.com/opencv/opencv/blob/master/data/haarcascades/
# https://github.com/opencv/opencv_contrib/blob/master/modules/face/data/cascades/
#Trained model file
if FLAGS.cascade == CASCADE[0]:#"default":
cascade_path = "./models/haarcascade_frontalface_default.xml"
elif FLAGS.cascade == CASCADE[1]:#"alt":
cascade_path = "./models/haarcascade_frontalface_alt.xml"
elif FLAGS.cascade == CASCADE[2]:#"alt2":
cascade_path = "./models/haarcascade_frontalface_alt2.xml"
elif FLAGS.cascade == CASCADE[3]:#"tree":
cascade_path = "./models/haarcascade_frontalface_alt_tree.xml"
elif FLAGS.cascade == CASCADE[4]:#"profile":
cascade_path = "./models/haarcascade_profileface.xml"
elif FLAGS.cascade == CASCADE[5]:#"nose":
cascade_path = "./models/haarcascade_mcs_nose.xml"
#Acquire the features of the cascade classifier
faceCascade = cv2.CascadeClassifier(cascade_path)
#Number of successful face detections(Specify 0 by default)
face_detect_count = 0
#Number of face detection failures(Specify 0 by default)
face_undetected_count = 0
#Store files in folders in variables(Also stores directories)
files = os.listdir(FLAGS.input_dir)
#If you haven't moved the success file, delete and recreate the output directory if it exists
if FLAGS.move_dir == "":
if os.path.exists(SAVE_PATH):
shutil.rmtree(SAVE_PATH)
os.mkdir(SAVE_PATH)
print(FLAGS)
#When a face is detected from the collected image data, cut it out and save it.
for file_name in files:
#For files(If not a directory)
if os.path.isfile(FLAGS.input_dir + file_name):
#Image file reading
img = cv2.imread(FLAGS.input_dir + file_name)
#Since there are files that rarely fail when there are a large number of images, log output and skip(Cause unknown)
if img is None:
print(file_name + ':Cannot read image file')
continue
#Convert from color to grayscale(Because face detection is not performed by color)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Face detection
face = faceCascade.detectMultiScale(gray, scaleFactor=FLAGS.scale, minNeighbors=FLAGS.neighbors, minSize=(FLAGS.min, FLAGS.min))
if len(face) > 0:
for rect in face:
#Crop image output
cv2.imwrite(SAVE_PATH + str(face_detect_count) + file_name, img[rect[1]:rect[1] + rect[3], rect[0]:rect[0] + rect[2]])
face_detect_count = face_detect_count + 1
#Move the detected file
if FLAGS.move_dir != "":
shutil.move(FLAGS.input_dir + file_name, FLAGS.input_dir + FLAGS.move_dir)
else:
print(file_name + ':No Face')
face_undetected_count = face_undetected_count + 1
print('Undetected Image Files:%d' % face_undetected_count)
Before executing, create the inputs and outputs folders directly under it, and put the images in the inputs folder. Run it on the command line. Since the initial value is given, you do not need to specify any parameters.
python openCVCutAndSave01_20170804.py
Of course, you can also give parameters and execute.
python openCVCutAndSave01_20170804.py --cascade "alt" --image_file "cut_source" --image_count 4 --scale 1.1 --neigbors 3 --min 50
The image in the inputs folder is cut out and output to the outputs folder, and the image with face detection is moved to the done folder. Since it is convenient to divide folders according to the presence or absence of detection when processing a large amount of images, we have made this specification. For details, I wrote it down in the article "Tips for efficiently detecting faces with large numbers of images with openCV".
Recommended Posts