一种人脸图像增强方式:人脸随机裁切+使用噪声和高斯模糊模拟低像素相机拍摄的图像

我常用的一种组合图像数据增强方式:随机裁剪+低像素相机模拟
在这里插入图片描述

在这里插入图片描述

说明

  1. 人脸检测和裁剪

    • 使用 get_face_landmarks 函数检测人脸关键点。
    • 使用 random_safe_crop 函数在安全区域内随机裁剪图像。
  2. 降低分辨率

    • 使用 simulate_low_res_image 函数对裁剪后的图像进行分辨率降低处理。
  3. 组合使用

    • 首先对输入图像进行人脸关键点检测和裁剪,然后对裁剪后的图像进行分辨率降低处理。
    • 最终显示裁剪后的图像和降低分辨率后的图像。

通过这种方式,你可以对人脸图像进行随机裁剪,同时保证裁剪后的图像大小不变且不切割到五官,然后模拟低分辨率相机的效果。这可以用于生成更丰富和多样的训练数据。

当无法成功检测到人脸时,我们可以按照您的要求,仅裁减掉图像周围一圈等宽的边缘。下面是修改后的代码示例:

代码示例

import cv2
import dlib
import numpy as np

# 加载人脸检测器和预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

def get_face_landmarks(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    faces = detector(gray)
    if len(faces) == 0:
        return None
    face = faces[0]
    landmarks = predictor(gray, face)
    points = []
    for i in range(68):
        point = (landmarks.part(i).x, landmarks.part(i).y)
        points.append(point)
    return points

def get_safe_crop_region(landmarks, image_shape, margin=30):
    x_coords = [p[0] for p in landmarks]
    y_coords = [p[1] for p in landmarks]
    min_x = max(min(x_coords) - margin, 0)
    max_x = min(max(x_coords) + margin, image_shape[1] - 1)
    min_y = max(min(y_coords) - margin, 0)
    max_y = min(max(y_coords) + margin, image_shape[0] - 1)
    return min_x, max_x, min_y, max_y

def random_safe_crop(image, landmarks, crop_size=224, margin=30):
    min_x, max_x, min_y, max_y = get_safe_crop_region(landmarks, image.shape, margin)

    if max_x - min_x < crop_size or max_y - min_y < crop_size:
        # 如果安全区域小于裁剪尺寸,使用图像中心裁剪
        start_x = max((image.shape[1] - crop_size) // 2, 0)
        start_y = max((image.shape[0] - crop_size) // 2, 0)
    else:
        start_x = np.random.randint(min_x, max_x - crop_size + 1)
        start_y = np.random.randint(min_y, max_y - crop_size + 1)
    
    cropped_image = image[start_y:start_y + crop_size, start_x:start_x + crop_size]
    return cropped_image

def simulate_low_res_image(image, scale_factor=0.5, blur_kernel_size=(5, 5), noise_level=10):
    """
    模拟低分辨率相机拍摄的图像
    :param image: 输入高清图像
    :param scale_factor: 缩放因子,用于下采样
    :param blur_kernel_size: 高斯模糊的核大小
    :param noise_level: 添加的噪声强度
    :return: 模拟低分辨率的图像
    """
    # 下采样
    low_res_image = cv2.resize(image, (0, 0), fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_LINEAR)
    
    # 上采样到原始尺寸
    low_res_image = cv2.resize(low_res_image, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST)
    
    # 高斯模糊
    low_res_image = cv2.GaussianBlur(low_res_image, blur_kernel_size, 0)
    
    # 添加噪声
    noise = np.random.normal(0, noise_level, low_res_image.shape).astype(np.uint8)
    noisy_image = cv2.add(low_res_image, noise)
    
    return noisy_image

def crop_border(image, border_size=20):
    """
    裁剪图像边缘
    :param image: 输入图像
    :param border_size: 要裁剪的边缘宽度
    :return: 裁剪后的图像
    """
    height, width = image.shape[:2]
    cropped_image = image[border_size:height-border_size, border_size:width-border_size]
    return cropped_image

# 示例使用
if __name__ == "__main__":
    image_path = "path_to_224x224_face_image.jpg"
    image = cv2.imread(image_path)
    
    # 获取人脸关键点
    landmarks = get_face_landmarks(image)
    if landmarks is not None:
        # 进行随机安全裁剪
        cropped_image = random_safe_crop(image, landmarks)
    else:
        # 未检测到人脸关键点,裁剪边缘
        cropped_image = crop_border(image, border_size=20)
    
    # 模拟低分辨率图像
    simulated_image = simulate_low_res_image(cropped_image, scale_factor=0.25, blur_kernel_size=(7, 7), noise_level=15)
    
    # 显示裁剪后和降低分辨率后的图像
    cv2.imshow('Cropped Image', cropped_image)
    cv2.imshow('Low Res Simulation', simulated_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

说明

  1. 裁剪图像边缘

    • 添加了 crop_border 函数,用于在未检测到人脸关键点时裁剪图像的边缘。可以调整 border_size 参数以改变裁剪的边缘宽度。
  2. 结合人脸裁剪和边缘裁剪

    • 在主程序中,首先尝试检测人脸关键点。如果检测到关键点,则进行随机安全裁剪;如果未检测到,则使用 crop_border 函数裁剪图像的边缘。
  3. 模拟低分辨率图像

    • 无论使用哪种裁剪方式,最终都会对裁剪后的图像进行分辨率降低处理,并显示结果。

通过这种方式,可以确保在无法检测到人脸时,仍然能够对图像进行裁剪和分辨率降低处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值