最近做LoRA模型训练时需要对一批图片进行人脸识别,并进行裁剪,然后设置特定的分辨率。
首先要导入cv库import cv2
如果没有opencv库的话要用pip先安装一个pip install opencv-python
1、识别出图片面部,并截取原图片靠近面部的最大正方形部位,同时将截取的图片分辨率改为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!')
可以看到a1(7)这张图片,模型无法识别,大家做的时候根据实际情况,调整这个位置的参数,以提高识别的准确度。
faces = face_detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30))
scaleFactor:表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%。可以根据图像的像素值来设置此参数,像素大缩小的速度就可以快一点,通常在1~1.5之间。
minNeighbors:表示构成检测目标的相邻矩形的最小个数(默认为3个)。是在人脸附近进行指定次数的检测,获取最准确的范围,设置越高,误检率越低,但是对于迷糊图片,设置越高,越不易检测出来,要适当降低。
2、以面部为中心,截取的最大正方形
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!')
3、只截取人脸部分文章来源:https://www.toymoban.com/news/detail-519302.html
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!')
文章来源地址https://www.toymoban.com/news/detail-519302.html
到了这里,关于使用opencv批量人脸识别+裁图+设置分辨率(Python代码分享)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!