Verwenden von opencv zur Batch-Gesichtserkennung + Zuschneiden + Festlegen der Auflösung (Python-Codefreigabe)

Als ich kürzlich das LoRA-Modell trainierte, musste ich eine Gesichtserkennung für eine Reihe von Bildern durchführen, diese zuschneiden und dann eine bestimmte Auflösung festlegen.
Importieren Sie zunächst die CV-Bibliothek. import cv2
Wenn keine OpenCV-Bibliothek vorhanden ist, installieren Sie sie zuerst mit PIP. pip install opencv-python
1. Erkennen Sie das Gesicht des Bildes, fangen Sie den größten quadratischen Teil des Originalbilds in der Nähe des Gesichts ab und ändern Sie die Auflösung abgefangenes Bild auf 512*512.

import numpy as np
import cv2
import os

def crop_face(input_folder_path, output_folder_path):
    # 加载面部识别模型
    face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    images = os.listdir(input_folder_path)
    for image in images:
        image_path = os.path.join(input_folder_path, image)
        img = cv2.imread(image_path)
        height, width, channels = img.shape
        # 将图像转换为灰度图像
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 检测面部
        faces = face_detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30))

        
        # 无法识别面部的图片
        if len(faces)==0:
            print(f"No face found in {
      
      image_path}")
            return
    
        if len(faces) > 0:
            # 取第一个脸部位置,这里假设一张图片只有一个脸部特征
            # x、y 为人脸的像素位置,w、h 为人脸的宽度和高度。
            x, y, w, h = faces[0]
            # 确定最大正方形的位置
            # 原图片竖方向长,截取正方形长度为原图横方向长,square_size截取正方形的长度
            if height>width:
                square_size = width
                x1=0
                x2=square_size
                # 原图面部靠上
                if y<square_size/2:
                    y1=0
                    y2 =square_size
                # 原图面部靠下
                else:
                    y1=int(square_size/2)
                    y2 =height
           # 原图片是横方向长,截取正方形长度为原图竖方向长度      
            else:
                square_size =  height
                y1=0
                y2=square_size
                # 原图面部靠右
                if x<square_size/2:
                    x1=0
                    x2 =square_size
                # 原图面部靠左
                else:
                    x1=int(square_size/2)
                    x2 =square_size
                
                
            # 根据最大正方形位置裁剪图片并保存
            cropped_img = img[y1:y2, x1:x2] 
            # 调整图像大小为512x512
            resized = cv2.resize(cropped_img, (512, 512), interpolation=cv2.INTER_AREA)
            output_path = os.path.join(output_folder_path,image)
            cv2.imwrite(output_path, resized)


if __name__ == "__main__":
    input_folder = r"输入图片所在文件夹路径" 
    output_folder = r"输出图片所在文件夹路径"  
    # 创建输出目录
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    crop_face(input_folder, output_folder)
    print('Done!')

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

Sie können sehen, dass das Bild von a1 (7) vom Modell nicht erkannt werden kann. Wenn Sie dies tun, passen Sie die Parameter dieser Position entsprechend der tatsächlichen Situation an, um die Erkennungsgenauigkeit zu verbessern.

faces = face_detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30))

ScaleFactor: Gibt den Skalierungskoeffizienten des Suchfensters in zwei aufeinanderfolgenden Scans an. Der Standardwert ist 1.1, was bedeutet, dass das Suchfenster jedes Mal um 10 % erweitert wird. Dieser Parameter kann entsprechend dem Pixelwert des Bildes eingestellt werden. Je größer die Pixel, desto schneller ist die Verkleinerungsgeschwindigkeit, normalerweise zwischen 1 und 1,5.

minNeighbors: Gibt die Mindestanzahl benachbarter Rechtecke an, die das Erkennungsziel bilden (Standard ist 3). Es führt eine bestimmte Anzahl von Erkennungen in der Nähe des Gesichts durch, um den genauesten Bereich zu erhalten. Je höher die Einstellung, desto geringer ist die Falscherkennungsrate. Bei verwirrenden Bildern gilt jedoch: Je höher die Einstellung, desto schwieriger ist die Erkennung, was auch der Fall sein sollte angemessen reduziert werden.

2. Nehmen Sie das Gesicht als Mittelpunkt und fangen Sie das größte Quadrat ab

import numpy as np
import cv2
import os


def crop_face(input_folder_path, output_folder_path):
    face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    images = os.listdir(input_folder_path)
    for image in images:
        image_path = os.path.join(input_folder_path, image)
        img = cv2.imread(image_path)
        height, width, channels = img.shape
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30))
        
        # 无法识别面部的图片
        if len(faces)==0:
            print(f"No face found in {
      
      image_path}")
            return
        
        if len(faces) > 0:
            # 取第一个脸部位置,这里假设一张图片只有一个脸部特征
            x, y, w, h = faces[0]
            # 确定最大正方形的位置
            square_size=min(width-x,x,y,height-y)
           
                
            # 根据最大正方形位置裁剪图片并保存
            cropped_img = img[y-square_size:y+h+square_size, x-square_size:x+w+square_size] #img[y1:y2, x1:x2]
            # 调整图像大小为512x512
            resized = cv2.resize(cropped_img, (512, 512), interpolation=cv2.INTER_AREA)
            output_path = os.path.join(output_folder_path, image)
            cv2.imwrite(output_path, resized)


if __name__ == "__main__":
    input_folder = r"输入图片所在文件夹路径"  
    output_folder = r"输出图片所在文件夹路径" 
    # 创建输出目录
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    crop_face(input_folder, output_folder)
    print('Done!')

Fügen Sie hier eine Bildbeschreibung ein
3. Erfassen Sie nur einen Teil des Gesichts

import numpy as np
import cv2
import os


def crop_face(input_folder_path, output_folder_path):
    face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    images = os.listdir(input_folder_path)
    for image in images:
        image_path = os.path.join(input_folder_path, image)
        img = cv2.imread(image_path)
        height, width, channels = img.shape
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=7, minSize=(30, 30))
        
        # 无法识别面部的图片
        if len(faces)==0:
            print(f"No face found in {
      
      image_path}")
            return
        
        for (x,y,w,h) in faces:
            cropped_img = img[y:y+h, x:x+w]  
            # 调整图像大小为512x512
            resized = cv2.resize(cropped_img, (512, 512), interpolation=cv2.INTER_AREA)
            # 将图像保存到输出目录
            output_path = os.path.join(output_folder_path, image)
            cv2.imwrite(output_path, resized)
            
if __name__ == "__main__":
    input_folder = r"输入图片所在文件夹路径"  
    output_folder = r"输出图片所在文件夹路径"  
    # 创建输出目录
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    crop_face(input_folder, output_folder)
    print('Done!')

Fügen Sie hier eine Bildbeschreibung ein

Acho que você gosta

Origin blog.csdn.net/qq_45694768/article/details/129305840
Recomendado
Clasificación