如何在充满图像的子目录中循环,并分别为每个图像分配一个函数



我正在开发一个人脸识别系统。我有一个文件夹,里面装满了子目录,里面有图像。我想循环浏览这些子目录中的图像,并应用负责人脸裁剪和对齐的face_align函数(我已经创建(,并将对齐和裁剪的图像保存在另一个文件夹中,该文件夹与之前具有相同的架构

例如:如果我有:包含原始原始图片的名为"Thor"、"Loki"one_answers"Odin"的子目录,我想循环浏览这些子目录,并应用face_align函数,然后自动创建另一个名为aligned face的文件夹,该文件夹将具有相同的子目录"Thor’、"Loki"one_answers"Odin"。但是具有对齐和裁剪的面。

到目前为止,我已经尝试过:

#Now that we have defined the face alignmet and cropping, we walk through each subfolder and use the align function
for root, dirs, files in os.walk('<path to subdirectories that has face pictures>'):
for fname in files:
fpath = os.path.join(root, fname)
with open(fpath, 'rb') as f, open('<path to new folder>', 'w') as newfile:
data = f.read()
new_data = align_face(data) #Implementing align_face function 
newfile.write(new_data)

然而,它似乎不起作用。它似乎很容易运行align_face功能,但它并没有将这些对齐的图像复制到新文件夹中。感谢您的帮助。非常感谢。

这是对齐面功能

def align_face(imagePath):
image = face_recognition.load_image_file(imagePath)
face_locations = face_recognition.face_locations(image)
face_landmarks = face_recognition.face_landmarks(image)
if len(face_locations) == 0:
print("Couldn't detect face for pid {} in path {}".format(Id,imagePath))
return []
if len(face_locations) > 1:
return []
else:
(top, right, bottom, left) = face_locations[0]
desiredWidth = (right - left)
desiredHeight = (bottom - top)
leftEyePts = face_landmarks[0]['left_eye']
rightEyePts = face_landmarks[0]['right_eye']
if len(leftEyePts) == 0 or len(rightEyePts) == 0:
print("Couldn't detect both eyes for pid {} in path {}".format(Id,imagePath))
return []

else:
leftEyeCenter = np.array(leftEyePts).mean(axis=0).astype("int")
rightEyeCenter = np.array(rightEyePts).mean(axis=0).astype("int")
leftEyeCenter = (leftEyeCenter[0],leftEyeCenter[1])
rightEyeCenter = (rightEyeCenter[0],rightEyeCenter[1])
dY = rightEyeCenter[1] - leftEyeCenter[1]
dX = rightEyeCenter[0] - leftEyeCenter[0]

angle = np.degrees(np.arctan2(dY, dX))
desiredLeftEye=(0.35, 0.35)
desiredFaceWidth = desiredWidth
desiredFaceHeight = desiredHeight
desiredRightEyeX = 1.0 - desiredLeftEye[0]
dist = np.sqrt((dX ** 2) + (dY ** 2))
desiredDist = (desiredRightEyeX - desiredLeftEye[0])

desiredDist *= desiredFaceWidth
scale = desiredDist / dist

eyesCenter = ((leftEyeCenter[0] + rightEyeCenter[0]) // 2,
(leftEyeCenter[1] + rightEyeCenter[1]) // 2)
M = cv2.getRotationMatrix2D(eyesCenter, angle, scale)

tX = desiredFaceWidth * 0.5
tY = desiredFaceHeight * desiredLeftEye[1]
M[0, 2] += (tX - eyesCenter[0])
M[1, 2] += (tY - eyesCenter[1])

(w, h) = (desiredFaceWidth, desiredFaceHeight)
output = cv2.warpAffine(image, M, (w, h),flags=cv2.INTER_CUBIC)
output = cv2.cvtColor(output, cv2.COLOR_BGR2RGB)
print("images aligned")

return output
import os
from PIL import Image
import numpy as np
your_dir_path = '...' # String. The path of your directory containing all your subdirectories
new_dir_path = '...' # The path of your new directory with the same architecture as the previous one, but with cropped and aligned faces
for subfolder in next(os.walk(your_dir_path))[1] : # Gives the list of all subdirectories inside the parent directory
os.makedirs(os.path.join(new_dir_path, subfolder)) # Creates the new subdirectory. Note that it will also create new_dir_path, so there's no need to add a line os.makedirs(new_dir_path)
for file in os.listdir(os.path.join(your_dir_path, subfolder)) : # Gives the list of all files inside the 'subfolder' directory

img = Image.open(os.path.join(your_dir_path, subfolder, file))
#img = np.asarray(img) # If your align_face function works with numpy arrays
new_img = align_face(img)
#new_img = Image.fromarray(np.uint8(new_img)) # If your align_face function returns a numpy array
new_img.save(os.path.join(new_dir_path, subfolder, file)) 

如果文件夹已经存在,os.makedirs(os.path.join(new_dir_path, subfolder))将抛出一个错误。在这种情况下,您可以删除此行(如果您已经创建了具有所有体系结构的new_dir_path文件夹(,也可以在重新创建之前删除现有文件夹:

from shutil import rmtree # deletes a folder

并在上一个代码中插入这一行:

if os.path.isdir(os.path.join(new_dir_path, subfolder)) :
rmtree(os.path.join(new_dir_path, subfolder))
os.makedirs(os.path.join(new_dir_path, subfolder))
...

您可以尝试使用glob。在使用glob和regex的情况下,您可以找到所有图像(假设根目录是当前活动目录(,遍历它们,并将新创建的图像存储在目标文件夹中

import glob, os
from pathlib import Path
destination_dir_path = "bawfaw"
image_paths = glob.glob("*/*/*.jpg") #in case those are jpg images
for image_path in image_paths:
destination_image_path = Path(os.path.join(destination_dir_path, image_path))
destination_image_folder = destination_image_path.parent
if os.path.exists(destination_image_folder) is False:
destination_image_folder.mkdir(parents=True, exist_ok=True)
with open(image_path, "rb") as image_file:
# process the image as you want and store it at destination_image_path

代码没有经过测试,但我认为它给出了大致的想法。

最新更新