Home>

I wanted to try trimming and saving the face part of the image, and I tried to use the code that was published by someone else, but I got an error and I can't execute it. Is something wrong?
I am sorry if this is a rudimentary question, but please give me a lecture.

Error message
C: \ Users \ kiara \ PycharmProjects \ openCV \ venv \ Scripts \ python.exe C: /Users/kiara/PycharmProjects/openCV/img_cuts.py
Namespace (cascade = 'alt', input_dir = './Input /', min = 80, move_dir = '/ done /', neighbors = 2, scale = 1.3)
Traceback (most recent call last):
  File "C: \ Users \ kiara \ Anaconda3 \ lib \ shutil.py", line 544, in move
    os.rename (src, real_dst)
FileExistsError: [WinError 183] Cannot create a file that already exists. : './input/00000001.jpg'->'./input//done/'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "C: /Users/kiara/PycharmProjects/openCV/img_cuts.py", line 124, in<module>
    shutil.move (FLAGS.input_dir + file_name, FLAGS.input_dir + FLAGS.move_dir)
  File "C: \ Users \ kiara \ Anaconda3 \ lib \ shutil.py", line 558, in move
    copy_function (src, real_dst)
  File "C: \ Users \ kiara \ Anaconda3 \ lib \ shutil.py", line 257, in copy2
    copyfile (src, dst, follow_symlinks = follow_symlinks)
  File "C: \ Users \ kiara \ Anaconda3 \ lib \ shutil.py", line 121, in copyfile
    with open (dst, 'wb') as fdst:
OSError: [Errno 22] Invalid argument: './input//done/'
Process finished with exit code 1
Applicable source code
import cv2, os, argparse, shutil
# Directory for cropped images
SAVE_PATH = "./outputs/"
# Basic model parameters
FLAGS = None
# Types of trained models
CASCADE = ["default", "alt", "alt2", "tree", "profile", "nose"]
# Pass if executed directly (imported but not executed)
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."
    )
# Get and execute parameters
FLAGS, unparsed = parser.parse_known_args ()
# Classifier directory (obtained from below)
# 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 = "C: /Users/kiara/Desktop/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml"
elif FLAGS.cascade == CASCADE [1]: # "alt":
    cascade_path = "C: /Users/kiara/Desktop/opencv-master/data/haarcascades/haarcascade_frontalface_alt.xml"
elif FLAGS.cascade == CASCADE [2]: # "alt2":
    cascade_path = "C: /Users/kiara/Desktop/opencv-master/data/haarcascades/haarcascade_frontalface_alt2.xml"
elif FLAGS.cascade == CASCADE [3]: # "tree":
    cascade_path = "C: /Users/kiara/Desktop/opencv-master/data/haarcascades/haarcascade_frontalface_alt_tree.xml"
elif FLAGS.cascade == CASCADE [4]: ​​# "profile":
    cascade_path = "C: /Users/kiara/Desktop/opencv-master/data/haarcascades/haarcascade_profileface.xml"
elif FLAGS.cascade == CASCADE [5]: # "nose":
    cascade_path = "C: /Users/kiara/Desktop/opencv_contrib-master/modules/face/data/cascades/haarcascade_mcs_nose.xml"
# Get the features of cascade classifier
faceCascade = cv2.CascadeClassifier (cascade_path)
# Number of successful face detection (default 0)
face_detect_count = 0
# Number of face detection failures (0 by default)
face_undetected_count = 0
# Store the files in the folder in a variable (also stores the directory)
files = os.listdir (FLAGS.input_dir)
# If i have not moved the success file, delete and recreate it if the output directory exists
if FLAGS.move_dir == "":
    if os.path.exists (SAVE_PATH):
        shutil.rmtree (SAVE_PATH)
    os.mkdir (SAVE_PATH)
print (FLAGS)
# If a face is detected from the collected image data, cut and save it.
for file_name in files:
    # For files (not directories)
    if os.path.isfile (FLAGS.input_dir + file_name):
        # Read image file
        img = cv2.imread (FLAGS.input_dir + file_name)
        # Since there is a file that rarely fails when there are a lot 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 is not detected in 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:
                # Cut 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 detected files
            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)
  • Answer # 1

      

    You cannot create a file that already exists.

    The problem is that the fileinput/done/00000001.jpgexists at the destination.
    *) The reason why this event occurs will be described later.

    Is it better to use Path # replace as a countermeasure?
    Below is the untested code.

    from pathlib import Path
    # Foreword
    # If you have not moved the success file, delete and recreate it if the output directory exists
    if FLAGS.move_dir == "":
        if os.path.exists (SAVE_PATH):
            shutil.rmtree (SAVE_PATH)
        os.mkdir (SAVE_PATH)
    else: # add this line
        move_dir = Path (FLAGS.input_dir, FLAGS.move_dir)
        # create input/done directory
        move_dir.mkdir (parents = True, exist_ok = True)
    # Abbreviation
    # If a face is detected from the collected image data, cut and save it.
    for file_name in files:
        src_file = Path (FLAGS.input_dir, file_name)
        # For files (not directories)
        if src_file.is_file ():
            # Read image file
            img = cv2.imread (str (src_file))
            # Abbreviation
                # Move detected files
                if FLAGS.move_dir! = "":
                    src_file.replace (move_dir/file_name)

    ※ Description
    On Windows,shutil.move ()internally callsos.rename ()when another file is renamed./Linux) and operation is different.

      

    File"C: \ Users \ kiara \ Anaconda3 \ lib \ shutil.py" ;, line 544, in move
          os.rename (src, real_dst)

    It is speculation, but the person who wrote the sample code performs an operation test onMacOSorlinux, and the questioner works onWindowsI wonder if this happened because of this.
    Useos.replaceorPath # replaceto perform rename processing in a cross-platform environment in the Python language.

    ◆ Reference information

    Os.rename Bold characters are quoted

      

    On Unix, if dst existsand the file isimplicitly replaced as long as the user has permission.This operation may fail on some Unix-like systems if src and dst are on different file systems. If the rename is successful, it is an atomic operation (this is a POSIX requirement).On Windows, if dst already exists,OSErroris raised, even for files.

    pathlib