将新人脸注册到人脸识别数据集(opencv,face_recognition)

时间:2021-06-02 06:58:42

标签: python

我有一个人脸识别代码(在最后给出了完整的代码),它与现有数据集完美配合。

但我希望它在要求用户输入框架中新人的姓名后,也将新面孔添加到数据集(注册)中[像这样:new_name = print(Who is this?)]。然后我可以通过输入的名称创建一个新文件夹,并将面部存储在框架内。这就是我所做的:

    new_name = input("Who is this?")
    path_2 = os.path.join('Images',new_name)
    os.mkdir(path_2)
    print("Directory '% s' created" % new_name)
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0,0,255),
        thickness = 2)
        cv2.putText(frame, new_name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
        0.75, (0, 255, 0), 2)
        sub_face = frame[y:y+h, x:x+w]
        FaceFileName = new_name + str(y+x) + ".jpg"
        cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
    cv2.imshow("Frame",frame)
    #if cv2.waitKey(1) & 0xFF == ord('q'):
    #    break

这对新人来说效果很好。但现在我不得不为认识的人无法识别的面孔做些事情。 在这种情况下,我们已经有了输入名称的文件夹。我们必须通过输入的名称将图像附加到现有文件夹中。 因此,为此我尝试了以下代码:(不起作用)

else: # To store the unknown new face with name
            new_name = input("Who is this?")
            # If the new_name entered already exists as a folder
            if os.path.isfile(new_name):
                print(new_name,"folder already exists")
                frame = imutils.resize(frame, width = 400)
                rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
                                              scaleFactor=1.1,
                                              minNeighbors=5,
                                              minSize=(30, 30))
                FaceFileName = new_name + str(y+x) + ".jpg"
                for (x, y, w, h) in rects:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                cv2.imshow("Frame",frame)
                key = cv2.waitKey(1) & 0xFF
                if key == ord("k"):
                    p = os.path.join([new_name,FaceFileName.format(str(total).zfill(5))])
                    # cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
                    cv2.imwrite(p, orig)
                    total += 1
                    print("Image saved")
                elif key == ord("q"):
                    break 
            # If the new_name does not exist as a folder new folder has to be created
            else: 
                path_2 = os.path.join('Images',new_name)
                os.mkdir(path_2)
                print("Directory '% s' created" % new_name)
                frame = imutils.resize(frame, width = 400)
                rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
                                                scaleFactor=1.1,
                                                minNeighbors=5,
                                                minSize=(30, 30))
                FaceFileName = new_name + str(y+x) + ".jpg"
                for (x, y, w, h) in rects:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                    cv2.imshow("Frame",frame)
                    key = cv2.waitKey(1) & 0xFF
                if key == ord("k"):
                    p = os.path.join([path_2,FaceFileName.format(str(total).zfill(5))])
                    # cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
                    cv2.imwrite(p, orig)
                    total += 1
                print("Image saved")

我收到错误:

Who is this?Vishwesh
Traceback (most recent call last):
  File "C:\Users\Vishw\databs.py", line 117, in <module>
    os.mkdir(path_2)
FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'Images\\Vishwesh'
[ WARN:0] global C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-sgoydvi3\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback

完整代码如下。让我知道代码有什么问题。请帮忙!

注意:我将上述代码包含在 #Face识别 on LIVE WEBCAM FEED 部分以及“if True inmatches:”的 else 语句中:

这是我的完整代码:

# Extracting features from face
from imutils import paths
import face_recognition
import pickle
import cv2
import os
 
#Get paths of each file in folder named Images
#Images here contains my data(folders of various persons)
imagePaths = list(paths.list_images('Images'))
knownEncodings = []
knownNames = []
# loop over the image paths
for (i, imagePath) in enumerate(imagePaths):
    # extract the person name from the image path
    name = imagePath.split(os.path.sep)[-2]
    # load the input image and convert it from BGR (OpenCV ordering)
    # to dlib ordering (RGB)
    image = cv2.imread(imagePath)
    rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    #Use Face_recognition to locate faces
    boxes = face_recognition.face_locations(rgb,model='hog')
    # compute the facial embedding for the face
    encodings = face_recognition.face_encodings(rgb, boxes)
    # loop over the encodings
    for encoding in encodings:
        knownEncodings.append(encoding)
        knownNames.append(name)
#save emcodings along with their names in dictionary data
data = {"encodings": knownEncodings, "names": knownNames}
#use pickle to save data into a file for later use
f = open("face_enc", "wb")
f.write(pickle.dumps(data))
f.close()
 
# Face recognition on LIVE WEBCAM FEED
import face_recognition
import pickle
import cv2
import os
#find path of xml file containing haarcascade file 
cascPathface = os.path.dirname(
 cv2.__file__) + "/data/haarcascade_frontalface_default.xml"
# load the harcaascade in the cascade classifier
faceCascade = cv2.CascadeClassifier(cascPathface)
# load the known faces and embeddings saved in last file
data = pickle.loads(open('face_enc', "rb").read())
print("Streaming started")
video_capture = cv2.VideoCapture(0)
# loop over frames from the video file stream
while True:
    # grab the frame from the threaded video stream
    ret, frame = video_capture.read()
    orig = frame.copy()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(gray,
                                         scaleFactor=1.05,
                                         minNeighbors=3,
                                         minSize=(60, 60),
                                         flags=cv2.CASCADE_SCALE_IMAGE)
 
    # convert the input frame from BGR to RGB 
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    # the facial embeddings for face in input
    encodings = face_recognition.face_encodings(rgb)
    names = []
    # loop over the facial embeddings incase
    # we have multiple embeddings for multiple fcaes
    for encoding in encodings:
       #Compare encodings with encodings in data["encodings"]
       #Matches contain array with boolean values and True for the embeddings it matches closely
       #and False for rest
        matches = face_recognition.compare_faces(data["encodings"],encoding)
        #set name =unknown if no encoding matches
        name = "Unknown"
        
        # check to see if we have found a match
        if True in matches:
            # Find positions at which we get True and store them
            matchedIdxs = [i for (i, b) in enumerate(matches) if b]
            counts = {}
            # loop over the matched indexes and maintain a count for
            # each recognized face face
            for i in matchedIdxs:
                #Check the names at respective indexes we stored in matchedIdxs
                name = data["names"][i]
                #increase count for the name we got
                counts[name] = counts.get(name, 0) + 1
            #set name which has highest count
            name = max(counts, key=counts.get)
        else: # To store the unknown new face with name
            new_name = input("Who is this?")
            # If the new_name entered already exists as a folder
            if os.path.isfile(new_name):
                print(new_name,"folder already exists")
                frame = imutils.resize(frame, width = 400)
                rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
                                              scaleFactor=1.1,
                                              minNeighbors=5,
                                              minSize=(30, 30))
                FaceFileName = new_name + str(y+x) + ".jpg"
                for (x, y, w, h) in rects:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                cv2.imshow("Frame",frame)
                key = cv2.waitKey(1) & 0xFF
                if key == ord("k"):
                    p = os.path.join([new_name,FaceFileName.format(str(total).zfill(5))])
                    # cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
                    cv2.imwrite(p, orig)
                    total += 1
                    print("Image saved")
                elif key == ord("q"):
                    break 
            # If the new_name does not exist as a folder new folder has to be created
            else: 
                path_2 = os.path.join('Images',new_name)
                os.mkdir(path_2)
                print("Directory '% s' created" % new_name)
                frame = imutils.resize(frame, width = 400)
                rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
                                                scaleFactor=1.1,
                                                minNeighbors=5,
                                                minSize=(30, 30))
                FaceFileName = new_name + str(y+x) + ".jpg"
                for (x, y, w, h) in rects:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                    cv2.imshow("Frame",frame)
                    key = cv2.waitKey(1) & 0xFF
                if key == ord("k"):
                    p = os.path.join([path_2,FaceFileName.format(str(total).zfill(5))])
                    # cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
                    cv2.imwrite(p, orig)
                    total += 1
                print("Image saved")
            
              
 
        # update the list of names
        names.append(name)
        # loop over the recognized faces
        for ((x, y, w, h), name) in zip(faces, names):
            # rescale the face coordinates
            # draw the predicted face name on the image
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
            cv2.putText(frame, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
             0.75, (0, 255, 0), 2)            
    cv2.imshow("Frame", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
video_capture.release()
cv2.destroyAllWindows()

2 个答案:

答案 0 :(得分:2)

因此,您的问题与文件操作有关,而与人脸识别有关... 在尝试创建文件夹之前尝试检查它是否已经存在:

path_2 = os.path.join('Images',new_name)
if not os.path.exists(path_2):
    os.mkdir(path_2)

答案 1 :(得分:0)

使用@Bohdan 给出的想法:

else: # To store the unknown new face with name
            new_name = input("Who is this?")
            path_2 = os.path.join('Images',new_name)
            for (x, y, w, h) in faces:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (0,0,255),
                    thickness = 2)
                    cv2.putText(frame, new_name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (0, 255, 0), 2)
                    sub_face = frame[y:y+h, x:x+w]
                    FaceFileName = new_name + str(y+x) + ".jpg"
            if not os.path.exists(path_2):
                os.mkdir(path_2)
                print("Directory '% s' created" % new_name)
                cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
            # To store unrecognised faces of known people
            else:
                cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)

代码运行良好!

相关问题