|
发表于 2025-1-22 21:22:34
|
显示全部楼层
建议导入DFLIMG类进行人脸区域确定。
使用 face_mask = LandmarksProcessor.get_image_hull_mask(image.shape, landmarks)获得遮罩,通过这个遮罩计算 x, y, w, h 到face_img。
在对face_img进行方差计算,避免产生意外的方差值,和排除面部外的区域。如下所示:
import cv2
from pathlib import Path
from facelib import LandmarksProcessor
from DFLIMG import DFLIMG
class FaceMaskDisplay:
def __init__(self, input_dir):
self.input_dir = input_dir
self.image_paths = self.load_image_paths()
self.images = []
self.dflimgs = []
self.landmarks_list = []
self.face_masks = []
self.variances = []
def load_image_paths(self):
input_dir = Path(self.input_dir)
image_paths = list(input_dir.glob("*.jpg")) + list(input_dir.glob("*.png"))
return image_paths
def load_images_and_dflimgs(self):
for image_path in self.image_paths:
image = cv2.imread(str(image_path))
self.images.append(image)
dflimg = DFLIMG.load(image_path)
if dflimg is None or not dflimg.has_data():
print(f"{image_path} 不符合DFL规范")
self.dflimgs.append(None)
else:
self.dflimgs.append(dflimg)
def get_facial_areas(self):
for i, dflimg in enumerate(self.dflimgs):
if dflimg is None:
self.landmarks_list.append(None)
self.face_masks.append(None)
continue
landmarks = dflimg.get_landmarks()
self.landmarks_list.append(landmarks)
image = self.images[i]
face_mask = LandmarksProcessor.get_image_hull_mask(image.shape, landmarks)
self.face_masks.append(face_mask)
def variance_of_laplacian(self, image):
"""计算图像的拉普拉斯方差"""
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return cv2.Laplacian(gray, cv2.CV_64F).var()
def compute_variances_and_display(self):
for i, (image_path, face_mask) in enumerate(zip(self.image_paths, self.face_masks)):
if face_mask is None:
self.variances.append(None)
continue
# 计算人脸区域的矩形框坐标 (x, y, w, h)
x, y, w, h = cv2.boundingRect(self.landmarks_list[i].astype(int))
# 提取人脸区域内容
face_img = self.images[i][y:y+h, x:x+w]
variance = self.variance_of_laplacian(face_img)
self.variances.append(variance)
# 显示图像的面部区域
cv2.imshow('Face Image', face_img)
print(f"图像 {image_path.name} 的拉普拉斯方差为: {variance}")
# 等待用户关闭窗口
key = cv2.waitKey(0)
cv2.destroyAllWindows()
# 当用户按下任意键后进行分类和保存
if key != -1:
self.classify_and_save_image(image_path, variance)
def classify_and_save_image(self, image_path, variance):
idx = int(variance / 10) * 10 # 根据方差值确定输出目录索引
if idx >= 100:
idx = 100
output_dir = Path(self.input_dir) / f"variance_{idx}-{idx+9}"
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / image_path.name
cv2.imwrite(str(output_path), cv2.imread(str(image_path)))
# 示例用法
if __name__ == "__main__":
input_dir = r"C:\Users\adnain\Desktop\temp3"
face_mask_display = FaceMaskDisplay(input_dir)
face_mask_display.load_images_and_dflimgs()
face_mask_display.get_facial_areas()
face_mask_display.compute_variances_and_display()
|
|