【数据集处理】FFHQ如何进行人脸对齐,Aligned and cropped images at 1024×1024

news2025/2/24 22:17:38

什么是人脸对齐?

人脸对齐是一种图像处理技术,旨在将图像中的人脸部分对齐到一个标准位置或形状。在许多情况下,这通常涉及将眼睛、鼻子和嘴巴等关键点对齐到特定的位置。通过这种方式,所有的人脸图像可以有一个一致的方向和尺寸,从而方便后续的处理和分析。

人脸对齐用来做什么?

  1. 标准化: 通过对齐,可以使所有的人脸图像具有相同的方向、尺寸和比例,这有助于后续的分析任务,如人脸识别、表情识别等。

  2. 增强特征: 对齐可以使得图像中的人脸特征更加清晰和稳定,从而提高诸如特征提取、匹配和分类等任务的准确性。

  3. 减少噪声和变形: 对于来自不同来源或角度的人脸图像,通过对齐可以减少由于视角、光照和遮挡等因素引入的变形和噪声。

  4. 增强人脸识别的准确性: 在人脸识别任务中,对齐的人脸图像可以提供更加一致和可靠的特征,从而提高识别的准确性和鲁棒性。

一定需要人脸对齐吗?

不是所有的应用场景都需要人脸对齐。是否需要进行人脸对齐取决于具体的应用和需求:

  1. 任务需求: 在某些任务,如人脸识别、表情分析和人脸年龄识别等,对齐可以显著提高性能和准确性。

  2. 应用场景: 在某些应用场景,例如社交媒体应用或无需进行详细分析的应用,可能不需要进行人脸对齐。

  3. 性能要求: 如果在特定的应用中,准确性和一致性是关键指标,那么人脸对齐可能是必要的。但如果只是进行一些简单的图像展示或可视化,那么可能可以不进行对齐。

总之,是否需要进行人脸对齐取决于具体的应用和目标。在某些情况下,对齐可以提供显著的优势,但在其他情况下,它可能并不是必需的。

FFHQ数据集有7w张,其中黄种人约有1.3w张,为了进一步提升GAN效果,可能会自己新增数据,那么如何将原始数据进行aligned and cropped达到可以使用呢?

官网介绍写的:
The dataset consists of 70,000 high-quality PNG images at 1024×1024 resolution and contains considerable variation in terms of age, ethnicity and image background. It also has good coverage of accessories such as eyeglasses, sunglasses, hats, etc. The images were crawled from Flickr, thus inheriting all the biases of that website, and automatically aligned and cropped using dlib. Only images under permissive licenses were collected. Various automatic filters were used to prune the set, and finally Amazon Mechanical Turk was used to remove the occasional statues, paintings, or photos of photos.

所以直接用dlib库检测到5个关键点,然后Aligned and cropped images at 1024×1024。

代码

这里有个仓库干了这件事:https://github.com/chi0tzp/FFHQFaceAlignment/tree/master

人脸检测可以用一些轻量好安装的,比如InsightFace:

https://qq742971636.blog.csdn.net/article/details/134556830

人脸检测我这里就不贴代码了,下面看看效果。

stylegan2的仓库:https://github.com/NVlabs/stylegan2

stylegan2用了1024×1024的人脸,太高清了,一般512*512都很大了。

原图:
在这里插入图片描述

对齐后

在这里插入图片描述

代码:

import os
import os.path as osp
import argparse
from tqdm import tqdm
import numpy as np
import cv2
import PIL.Image
import PIL.ImageFile
from PIL import Image
import scipy.ndimage


# kpts 左眼,右眼,鼻子,左嘴角,右嘴角
# array([[267.35327   , 310.13452   ,   0.90008646, 381.736     ,
#         320.14508   ,   0.89044243, 312.23892   , 394.6481    ,
#           0.9141436 , 263.4799    , 438.52295   ,   0.90634793,
#         362.49573   , 446.24716   ,   0.89808387]], dtype=float32)
# landmarks=kpts[0]

def align_crop_image(image, landmarks, transform_size=256):
    eye_left = landmarks[0:2]
    eye_right = landmarks[3:5]
    eye_avg = (eye_left + eye_right) * 0.5
    eye_to_eye = eye_right - eye_left
    mouth_left = landmarks[9:11]
    mouth_right = landmarks[12:14]
    mouth_avg = (mouth_left + mouth_right) * 0.5
    eye_to_mouth = mouth_avg - eye_avg

    # Choose oriented crop rectangle
    x = eye_to_eye - np.flipud(eye_to_mouth) * [-1, 1]
    x /= np.hypot(*x)
    x *= max(np.hypot(*eye_to_eye) * 2.0, np.hypot(*eye_to_mouth) * 1.8)
    y = np.flipud(x) * [-1, 1]
    c = eye_avg + eye_to_mouth * 0.1
    quad = np.stack([c - x - y, c - x + y, c + x + y, c + x - y])
    qsize = np.hypot(*x) * 2

    img = Image.fromarray(image)
    shrink = int(np.floor(qsize / transform_size * 0.5))
    if shrink > 1:
        rsize = (int(np.rint(float(img.size[0]) / shrink)), int(np.rint(float(img.size[1]) / shrink)))
        img = img.resize(rsize, Image.Resampling.LANCZOS)
        quad /= shrink
        qsize /= shrink

    # Crop
    border = max(int(np.rint(qsize * 0.1)), 3)
    crop = (int(np.floor(min(quad[:, 0]))), int(np.floor(min(quad[:, 1]))), int(np.ceil(max(quad[:, 0]))),
            int(np.ceil(max(quad[:, 1]))))
    crop = (max(crop[0] - border, 0), max(crop[1] - border, 0), min(crop[2] + border, img.size[0]),
            min(crop[3] + border, img.size[1]))
    if crop[2] - crop[0] < img.size[0] or crop[3] - crop[1] < img.size[1]:
        img = img.crop(crop)
        quad -= crop[0:2]

    # Pad
    pad = (int(np.floor(min(quad[:, 0]))), int(np.floor(min(quad[:, 1]))), int(np.ceil(max(quad[:, 0]))),
           int(np.ceil(max(quad[:, 1]))))
    pad = (max(-pad[0] + border, 0), max(-pad[1] + border, 0), max(pad[2] - img.size[0] + border, 0),
           max(pad[3] - img.size[1] + border, 0))
    enable_padding = True
    if enable_padding and max(pad) > border - 4:
        pad = np.maximum(pad, int(np.rint(qsize * 0.3)))
        img = np.pad(np.float32(img), ((pad[1], pad[3]), (pad[0], pad[2]), (0, 0)), 'reflect')
        h, w, _ = img.shape
        y, x, _ = np.ogrid[:h, :w, :1]
        # mask = np.maximum(1.0 - np.minimum(np.float32(x) / pad[0], np.float32(w - 1 - x) / pad[2]),
        #                   1.0 - np.minimum(np.float32(y) / pad[1], np.float32(h - 1 - y) / pad[3]))
        mask = np.maximum(1.0 - np.minimum(np.float32(x) / (pad[0] + 1e-12), np.float32(w - 1 - x) / (pad[2] + 1e-12)),
                          1.0 - np.minimum(np.float32(y) / (pad[1] + 1e-12), np.float32(h - 1 - y) / (pad[3] + 1e-12)))

        blur = qsize * 0.01
        img += (scipy.ndimage.gaussian_filter(img, [blur, blur, 0]) - img) * np.clip(mask * 3.0 + 1.0, 0.0, 1.0)
        img += (np.median(img, axis=(0, 1)) - img) * np.clip(mask, 0.0, 1.0)
        img = PIL.Image.fromarray(np.uint8(np.clip(np.rint(img), 0, 255)), 'RGB')

        quad += pad[:2]

    # Transform
    img = img.transform((transform_size, transform_size), Image.Transform.QUAD, (quad + 0.5).flatten(),
                        Image.Resampling.BILINEAR)

    return np.array(img)


if __name__ == "__main__":
    src = "1.jpg"
    img_src = cv2.imread(src, cv2.IMREAD_COLOR)
    landmarks = np.asarray([[267.35327, 310.13452, 0.90008646, 381.736,
                             320.14508, 0.89044243, 312.23892, 394.6481,
                             0.9141436, 263.4799, 438.52295, 0.90634793,
                             362.49573, 446.24716, 0.89808387]])[0]
    img = align_crop_image(img_src, landmarks, transform_size=512)
    cv2.imwrite("1_out.jpg", img)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1380325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

josef约瑟 中间继电器 HJDZ-E440额定电压:AC220V 卡轨安装

HJDZ-静态中间继电器 系列型号&#xff1a; HJDZ-A200静态中间继电器&#xff1b;HJDZ-A110静态中间继电器&#xff1b; HJDZ-A002静态中间继电器&#xff1b;HJDZ-A004静态中间继电器&#xff1b; HJDZ-E112静态中间继电器&#xff1b;HJDZ-E112L静态中间继电器&#xff1…

opencv(C++)基础用法

文章目录 前言一、opencv (C)图片基本操作1.1 读取图片并显示1.2 颜色转换1.3 图像filtering1.4 形状调整1.5 绘制 二、读取视频文件并显示三、RTSP 视频流四. 人脸检测总结 前言 学习笔记 一、opencv (C)图片基本操作 1.1 读取图片并显示 #include "opencv2/opencv.hp…

操作系统-操作系统的概念和功能

文章目录 大家熟悉的操作系统总览操作系统的概念&#xff08;定义&#xff09;操作系统的功能和目标-作为系统资源的管理者操作系统的功能和目标-向上层提供方便易用的服务图形化用户接口联机命令接口脱机命令接口程序接口小结 操作系统的功能和目标-作为最解决硬件的层次小结 …

Go-安装与基础语法

TOC 1. Go 安装与环境变量 1.1 下载 需要从Go语言的官方网站下载适合你操作系统的Go语言安装包。Go语言支持多种操作系统&#xff0c;包括Windows、Linux和Mac OS。 对于Windows用户&#xff0c;下载.msi文件&#xff0c;然后双击该文件&#xff0c;按照提示进行安装即可。…

【电路电子学】7天速通攻略+笔记

7天是 看视频记笔记刷题的总时长&#xff0c;时间紧迫的同学可以看情况进行缩减。个人认为做题&#xff0c;尤其是解析齐全的题最重要&#xff01; 我校所用教材 《电路与电子学基础》唐胜安 复习总流程 所用材料&#xff08;都可自行找到免费资源&#xff09; 视频知识点讲…

如何用Python虚拟环境virtualenv轻松管理多个项目?你想要的都在这里!

目录 Python 虚拟环境安装 Python 虚拟环境能够实现多环境隔离。 虚拟环境的应用场景 例如&#xff0c;在一台电脑上开发涉及多种技术栈的项目时&#xff0c;不同技术底层依赖可能存在冲突。这种情况下&#xff0c;解决了某个项目的问题可能会影响到其他项目的运行&#xff0c…

数据洞察力,驱动企业财务变革

我们不得不面对一个现实&#xff0c;就是数据量的剧增。加上大部分企业并不愿意删除历史数据&#xff0c;以防未来预测分析时需要&#xff0c;这造成数据就像一个雪球&#xff0c;越滚越大。然而&#xff0c;过多的数据和数据不足一样会成为企业发展和理解分析的障碍。从海量数…

动态规划part04 416. 分割等和子集

01背包问题 二维 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili 01背包问题 一维 代码随想录 视频讲解&#xff1a;带…

08、Kafka ------ 消息存储相关的配置-->消息过期时间设置、查看主题下的消息存活时间等配置

目录 消息存储相关的配置★ 消息的存储介绍★ 消息过期时间及处理方式演示&#xff1a;log.cleanup.policy 属性配置 ★ 修改指定主题的消息保存时间演示&#xff1a;将 test2 主题下的消息的保存时间设为10个小时1、先查看test2主题下的配置2、然后设置消息的保存时间3、然后再…

2024/1/14周报

文章目录 摘要Abstract文献阅读题目问题与创新方法A.CEMDAN方法B.LSTM网络C. CEEMDAN-LSTM模型 实验过程数据集与数据预处理参数设置评价指标和参数 实验结果 深度学习GRUGRU前向传播GRU的训练过程 总结 摘要 本周阅读了一篇基于CEEMDAN-LSTM的金融时间序列预测模型的文章&…

Spark---RDD(Key-Value类型转换算子)

文章目录 1.RDD Key-Value类型1.1 partitionBy1.2 reduceByKey1.3 groupByKeyreduceByKey和groupByKey的区别分区间和分区内 1.4 aggregateByKey获取相同key的value的平均值 1.5 foldByKey1.6 combineByKey1.7 sortByKey1.8 join1.9 leftOuterJoin1.10 cogroup 1.RDD Key-Value…

通过代理连接sftp

通过nginx代理连接sftp 1.问题描述2.代码实现3.nginx配置3.1 创建sftp.stream文件3.2 修改nginx配置 4.重启nginx生效 1.问题描述 问题是这样的。我们现在需要在微服务所在内网的A机器连接到外网的sftp&#xff0c;但是网络又不能直接到达。然后A机器到B机器是通过的&#xff…

设计模式之策略模式【行为型模式】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某…

新手入门:软件在测试过程中可能出现哪些问题?走,去看看~

对于很多测试新手来说&#xff0c;想要把自己的测试技术练得更精进&#xff0c;扎实自己的理论知识是必不可少的一门功课。下面&#xff0c;我们就一起来复习一下&#xff0c;那些让我们一知半解或者记不全的理论知识吧。 01 什么是软件测试&#xff1f; 最老套&#xff0c;但…

不要再搞混标准化与归一化啦,数据标准化与数据归一化的区别!!

数据标准化与归一化 1. 数据的标准化&#xff08;Standardization&#xff09;&#xff1a;2. 数据的归一化&#xff08;Normalization&#xff09;&#xff1a;总结&#xff08;数据标准化和数据归一化的不同之处和相同之处&#xff09; 1. 数据的标准化&#xff08;Standardi…

【数据结构】二叉树问题总结

目录 1.二叉树前序遍历&#xff0c;中序遍历和后序的实现 2.层序遍历 3.求二叉树中的节点个数 4.求二叉树中的叶子节点个数 5.求二叉树的高度 6.求二叉树第k层节点个数 7.二叉树查找值为x的节点 8.单值二叉树 9.二叉树最大深度 10.翻转二叉树 11. 检查两颗树是否相同…

【Linux实用篇】Linux常用命令(2)

目录 1.3 拷贝移动命令 1.3.1 cp 1.3.2 mv 1.4 打包压缩命令 1.5 文本编辑命令 1.5.1 vi&vim介绍 1.5.2 vim安装 1.5.3 vim使用 1.6 查找命令 1.6.1 find 1.6.2 grep 1.3 拷贝移动命令 1.3.1 cp 作用: 用于复制文件或目录 语法: cp [-r] source dest ​ 说明: …

数据分析概述2(详细介绍机器学习

目录 1.名词解释&#xff1a;1.1算法和模型1.2参数和超参数 2.基础算法&#xff1a;3.高级算法&#xff1a;4.数据准备5.常用python包小结&#xff1a; 1.名词解释&#xff1a; 1.1算法和模型 算法&#xff1a;用于训练模型的方法&#xff0c;分为有监督学习、无监督学习、半…

Centos7安装K8S

Centos7安装K8S 安装过程中没有出现的错误可以往下 根据以前一些博主写的博客&#xff0c;在小阳翻了不下几十篇博客之后&#xff0c;我果断是放弃了&#xff0c;于是找到了官网地址&#xff0c;然后也有坑 1. 关闭防火墙 systemctl stop firewalld systemctl disable firew…

算法通关村番外篇-LeetCode编程从0到1系列四

大家好我是苏麟 , 今天带来算法通关村番外篇-LeetCode编程从0到1系列四 . 矩阵 1672. 最富有客户的资产总量 描述 : 给你一个 m x n 的整数网格 accounts &#xff0c;其中 accounts[i][j] 是第 i​​​​​ 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产…