[PYTHON] Face detection from multiple image files with openCV, cut out and save

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. 00.ArchitectureopenCV.JPG

Python code

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. 10.openCVResult.JPG For details, I wrote it down in the article "Tips for efficiently detecting faces with large numbers of images with openCV".

Recommended Posts

Face detection from multiple image files with openCV, cut out and save
I want to cut out only the face from a person image with Python and save it ~ Face detection and trimming with face_recognition ~
Cut out face with Python + OpenCV
Face detection with Python + OpenCV
Anime face detection with OpenCV
Cut out frames from video by 1 second with Python + OpenCV
Cut out an image with python
Save and retrieve files with Pepper
Let's cut the face from the image
Face detection with Python + OpenCV (rotation invariant)
Hello World and face detection with opencv-python 4.2
Edit and save read-only files with vim
Image acquisition from camera with Python + OpenCV
Cut out and connect images with ImageMagick
Resize, mosaic, face detection with OpenCV, sometimes Zojirushi
A memo that detects and returns an image acquired from a webcam with Django's OpenCV
Image capture / OpenCV speed comparison with and without GPU
[Ubuntu] [Python] Face detection comparison between dlib and OpenCV
Face detection from images taken with Raspberry Pi camera
Remove headings from multiple format CSV files with python
[Python] Send gmail with python: Send one by one with multiple image files attached
Improve detection accuracy quickly by specifying parameters with openCV face detection
Similar face image detection using face recognition and PCA and K-means clustering
[Python] Easy reading of serial number image files with OpenCV
Face recognition with Python's OpenCV
Image editing with python OpenCV
Face detection with Python + dlib
Sorting image files with Python (2)
Sorting image files with Python (3)
Real-time edge detection with OpenCV
Sorting image files with Python
Get image features with OpenCV
Face recognition / cutting with OpenCV
Face detection with Haar Cascades
Image recognition with Keras + OpenCV
Automatic image interpolation with OpenCV and Python (Fast Marching Method, Navier-Stokes)
[AWS] Search and acquire necessary data from S3 files with S3 Select
[Image processing] Edge detection using Python and OpenCV makes Poo naked!
Draw a watercolor illusion with edge detection in Python3 and openCV3
I tried to cut out a still image from the video
Replace your face with Twitter icon with openCV face recognition and do ZOOM
Get OCTA simulation conditions from a file and save with pandas
Operate Firefox with Selenium from python and save the screen capture
[Explanation for beginners] OpenCV face detection mechanism and practice (detect MultiScale)
[Python] Try to recognize characters from images with OpenCV and pyocr
How to put OpenCV in Raspberry Pi and easily collect images of face detection results with Python