常见的人脸对齐方法 python

article/2025/9/23 15:59:51

人脸对齐

1. 通过Dlib库

1.1.环境需求:

opencv-python
dlib

下载dlib库的68关键点文件:
http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
然后解压后得到shape_predictor_68_face_landmarks.dat

其次,下面可能需要有一定python基础才能快速调用。

注意:Dlib库有cuda加速版本,用这个更快,否则CPU计算。

1.2.程序:

import cv2
import dlib
import numpy as npclass Face_Align(object):def __init__(self,shape_predictor_path):self.detector = dlib.get_frontal_face_detector()self.predictor = dlib.shape_predictor(shape_predictor_path)self.LEFT_EYE_INDICES = [36, 37, 38, 39, 40, 41]self.RIGHT_EYE_INDICES = [42, 43, 44, 45, 46, 47]def rect_to_tuple(self, rect):left = rect.left()right = rect.right()top = rect.top()bottom = rect.bottom()return left, top, right, bottomdef extract_eye(self, shape, eye_indices):points = map(lambda i: shape.part(i), eye_indices)return list(points)def extract_eye_center(self, shape, eye_indices):points = self.extract_eye(shape, eye_indices)xs = map(lambda p: p.x, points)ys = map(lambda p: p.y, points)return sum(xs) // 6, sum(ys) // 6def extract_left_eye_center(self, shape):return self.extract_eye_center(shape, self.LEFT_EYE_INDICES)def extract_right_eye_center(self, shape):return self.extract_eye_center(shape, self.RIGHT_EYE_INDICES)def angle_between_2_points(self, p1, p2):x1, y1 = p1x2, y2 = p2tan = (y2 - y1) / (x2 - x1)return np.degrees(np.arctan(tan))def get_rotation_matrix(self, p1, p2):angle = self.angle_between_2_points(p1, p2)x1, y1 = p1x2, y2 = p2xc = (x1 + x2) // 2yc = (y1 + y2) // 2M = cv2.getRotationMatrix2D((xc, yc), angle, 1)return Mdef crop_image(self, image, det):left, top, right, bottom = self.rect_to_tuple(det)return image[top:bottom, left:right]def __call__(self, image=None,image_path=None,save_path=None,only_one=True):'''Face alignment, can select input image variable or image path, when inputimage format that return alignment face image crop or image path as inputwill return None but save image to the save path.:image: Face image input:image_path: if image is None than can input image:save_path: path to save image:detector: detector = dlib.get_frontal_face_detector():predictor: predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")'''if image is not None:# convert BGR format to Grayimage_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)elif image_path is not None:image_gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)image = cv2.imread(image_path)height, width = image.shape[:2]# Dector facedets = self.detector(image_gray, 1)# i donate the i_th face detected in imagecrop_images = []for i, det in enumerate(dets):shape = self.predictor(image_gray, det)left_eye = self.extract_left_eye_center(shape)right_eye = self.extract_right_eye_center(shape)M = self.get_rotation_matrix(left_eye, right_eye)rotated = cv2.warpAffine(image, M, (width, height), flags=cv2.INTER_CUBIC)cropped = self.crop_image(rotated, det)if only_one == True:if save_path is not None:cv2.imwrite(save_path, cropped)return croppedelse:crop_images.append(cropped)return crop_images

1.3. 调用:

if __name__ == "__main__":align = Face_Align("./face-alignment-dlib/shape_predictor_68_face_landmarks.dat")align(image_path="./face-alignment-dlib/123.jpg",save_path="test.jpg")

即可

2. 针对ArcFace:

2.1 环境:

克隆MTCNN的项目:

git clone https://github.com/RuoyuChen10/MTCNN_Portable.git

这个需要安装tensorflow 1的版本,以及opencv

优点就是可以GPU加速。

2.2 代码:

识别人脸的landmark:

from MTCNN_Portable.mtcnn import MTCNN
import cv2def detect_landmark(image, detector):'''image as numpy format with RGB formatnote that cv2 read is BGR format'''face = detector.detect_faces(image)[0]#draw pointsleft_eye = face["keypoints"]["left_eye"]right_eye = face["keypoints"]["right_eye"]nose = face["keypoints"]["nose"]mouth_left = face["keypoints"]["mouth_left"]mouth_right = face["keypoints"]["mouth_right"]landmark = [[left_eye[0], left_eye[1]],[right_eye[0], right_eye[1]],[nose[0], nose[1]],[mouth_left[0], mouth_left[1]],[mouth_right[0], mouth_right[1]]]return landmark

人脸对齐,针对ArcFace:

来自官方源码参考:https://github.com/deepinsight/insightface/blob/master/recognition/common/face_align.py

import numpy as np
from skimage import transform as transsrc1 = np.array([[51.642, 50.115], [57.617, 49.990], [35.740, 69.007],[51.157, 89.050], [57.025, 89.702]],dtype=np.float32)
#<--left
src2 = np.array([[45.031, 50.118], [65.568, 50.872], [39.677, 68.111],[45.177, 86.190], [64.246, 86.758]],dtype=np.float32)#---frontal
src3 = np.array([[39.730, 51.138], [72.270, 51.138], [56.000, 68.493],[42.463, 87.010], [69.537, 87.010]],dtype=np.float32)#-->right
src4 = np.array([[46.845, 50.872], [67.382, 50.118], [72.737, 68.111],[48.167, 86.758], [67.236, 86.190]],dtype=np.float32)#-->right profile
src5 = np.array([[54.796, 49.990], [60.771, 50.115], [76.673, 69.007],[55.388, 89.702], [61.257, 89.050]],dtype=np.float32)src = np.array([src1, src2, src3, src4, src5])
src_map = {112: src, 224: src * 2}arcface_src = np.array([[38.2946, 51.6963], [73.5318, 51.5014], [56.0252, 71.7366],[41.5493, 92.3655], [70.7299, 92.2041]],dtype=np.float32)arcface_src = np.expand_dims(arcface_src, axis=0)# lmk is prediction; src is template
def estimate_norm(lmk, image_size=112, mode='arcface'):assert lmk.shape == (5, 2)tform = trans.SimilarityTransform()lmk_tran = np.insert(lmk, 2, values=np.ones(5), axis=1)min_M = []min_index = []min_error = float('inf')if mode == 'arcface':assert image_size == 112src = arcface_srcelse:src = src_map[image_size]for i in np.arange(src.shape[0]):tform.estimate(lmk, src[i])M = tform.params[0:2, :]results = np.dot(M, lmk_tran.T)results = results.Terror = np.sum(np.sqrt(np.sum((results - src[i])**2, axis=1)))#         print(error)if error < min_error:min_error = errormin_M = Mmin_index = ireturn min_M, min_indexdef norm_crop(img, landmark, image_size=112, mode='arcface'):M, pose_index = estimate_norm(landmark, image_size, mode)warped = cv2.warpAffine(img, M, (image_size, image_size), borderValue=0.0)return warped

调用:

detector = MTCNN()img = cv2.cvtColor(cv2.imread("./MTCNN_Portable/test.jpg"), cv2.COLOR_BGR2RGB)	# To RGB
landmark = detect_landmark(img, detector)# 不需要把img变换回BGR格式,wrap还会自动出BGR
wrap = norm_crop(img, np.array(landmark), image_size=112, mode='arcface')

wrap即最终结果。
在这里插入图片描述

3. VGGFace2对齐

3.1 说明

这种仅采用了crop的方式,具体是MTCNN检测时有检测到人脸的框,在这个框基础上扩展0.15倍,然后取最长边为正方形,crop下来,再resize。

3.2 环境

MTCNN检测:

git clone https://github.com/RuoyuChen10/MTCNN_Portable.git

3.3 代码:

import cv2
import numpy as np
import os
import random
import tensorflow as tf
import mathfrom MTCNN_Portable.mtcnn import MTCNN# load input images and corresponding 5 landmarks
def load_img_and_box(img_path, detector):#Reading imageimage = Image.open(img_path)if img_path.split('.')[-1]=='png':image = image.convert("RGB")# BGRimg = cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB)#Detect 5 key pointface = detector.detect_faces(img)[0]box = face["box"]image = cv2.imread(img_path)return image, boxdef box_crop(image, box):shape=(224,224)# print(image.shape)# print((int(np.floor(box[1]-box[3]*0.15)),int(np.ceil(box[1]+box[3]*1.15))))# print((int(np.floor(box[0]-box[2]*0.15)),int(np.ceil(box[0]+box[2]*1.15))))if int(np.floor(box[1]-box[3]*0.15)) < 0:top = 0top_ = -int(np.floor(box[1]-box[3]*0.15))else:top = int(np.floor(box[1]-box[3]*0.15))top_ = 0if int(np.ceil(box[1]+box[3]*1.15)) > image.shape[0]:bottom = image.shape[0]else:bottom = int(np.ceil(box[1]+box[3]*1.15))if int(np.floor(box[0]-box[2]*0.15)) < 0:left = 0left_ = -int(np.floor(box[0]-box[2]*0.15))else:left = int(np.floor(box[0]-box[2]*0.15))left_ = 0if int(np.ceil(box[0]+box[2]*1.15)) > image.shape[1]:right = image.shape[1]else:right = int(np.ceil(box[0]+box[2]*1.15))img_zero = np.zeros((int(np.ceil(box[1]+box[3]*1.15))-int(np.floor(box[1]-box[3]*0.15)),int(np.ceil(box[0]+box[2]*1.15))-int(np.floor(box[0]-box[2]*0.15)),3))img = image[top:bottom,left:right]img_zero[top_:top_+bottom-top,left_:left_+right-left] = imgimg = img_zeroim_shape = img.shape[:2]ratio = float(shape[0]) / np.min(im_shape)img = cv2.resize(img,dsize=(math.ceil(im_shape[1] * ratio),   # widthmath.ceil(im_shape[0] * ratio))  # height)new_shape = img.shape[:2]h_start = (new_shape[0] - shape[0])//2w_start = (new_shape[1] - shape[1])//2img = img[h_start:h_start+shape[0], w_start:w_start+shape[1]]return img

调用:

detector = MTCNN()image_path = "Path to image!"img,box = load_img_and_box(image_path, detector)
crop_image = box_crop(img, box)

crop_image即为最终结果。


http://chatgpt.dhexx.cn/article/2I0a2SVK.shtml

相关文章

QGIS中也有“fishnet”——QGIS怎么生成渔网

QGIS堪称Mac上的ArcGIS&#xff0c;免费小巧&#xff0c;插件丰富&#xff0c;比ArcGIS更容易上手。今天分享的是如何在QGIS中生成规则网格&#xff0c;也就是ArcGIS中的fishnet功能怎么在QGIS中完美实现。 # 环境声明&#xff1a;QGIS3.10 MacOS10.15.6 # 分享背景&#xff…

ArcMap Fishnet生成规则网格

在利用ArcGIS处理数据时&#xff0c;有时需要对整个工作区域进行规则网格划分&#xff0c;这个在ArcGIS中是一件非常简单的事情&#xff0c;现在就将利用ArcGIS生成规则网格的步骤详细的介绍一下。 首先我有一个工作的范围&#xff0c;比如图一所示的范围&#xff1a; 我要在研…

POJ 1408 Fishnet

题目大意&#xff1a; 有一个1*1的正方形&#xff0c;分别给出下&#xff0c;上&#xff0c;左&#xff0c;右边每个边上的n个点&#xff0c;对边对应点连线&#xff0c;问这些线段相交的最大的四边形面积是多少&#xff08;面积最大的定义是必须当前面积内没有更小的四边形内…

创建渔网工具

创建渔网&#xff08;create fishnet&#xff09;工具是指创建由矩形像元组成的渔网。输出可以是折线或面要素。创建渔网需要三条基本信息&#xff1a;渔网的空间范围、行数和列数以及旋转的角度。要指定这些基本信息可通过多种方法。例如&#xff0c;您可能不确定准确的行数和…

ARCGIS怎么在地图上绘制长宽500m*500m的fishnet

用的是ArcGIS 10.6的版本。 参考教程&#xff1a;https://my.oschina.net/u/4416039/blog/3308651 首先先导入深圳市的shp文件 Layers右键&#xff0c;点击Properties 需要将坐标系改成投影坐标系 点击Projected Coordinate Systems 点击UTM 点击WGS 1984 选择WGS 1984 UT…

fishboat

渔船产品功能说明文档1.0 线上地址&#xff1a;http://101.200.121.215:9090/ git前端: https://gitee.com/cinblx/fishboat-ui.git git后端&#xff1a;https://gitee.com/cinblx/fishboat-server.git 产品介绍 为什么使用该产品 该产品致力于两方面。1.实现基础功能&#xff…

文献阅读笔记5——《Composited FishNet: Fish Detection and Species Recognition From Low-Quality ...》

《Composited FishNet: Fish Detection and Species Recognition From Low-Quality Underwater Videos》 写文章模板论文 Abstact 重要意义&#xff1a;水下视频中鱼类的自动检测和识别对于渔业资源评估和生态环境监测具有重要意义。 问题和挑战&#xff1a;由于水下图像质量…

使用Arc Map创建渔网(fishnet)

使用Arc Map创建渔网&#xff08;fishnet&#xff09; 工具位置&#xff1a;ArcToolbox----数据管理工具----采样----创建渔网 &#xff08;Arcgis 10.2以上版本&#xff09;&#xff08;找不到工具可以ControlF选择工具项搜索&#xff09; 添加图层&#xff0c;设置坐标系&am…

arcgis fishnet渔网功能学习

听说要来跟我请教fishnet功能&#xff0c;吓我一跳&#xff0c;arcgis不就只有个创建渔网功能吗&#xff1f;&#xff1f;纳尼&#xff1f;! 赶紧捡捡知识点&#xff0c;避免一问三不知.。 版本12.4后工具位于data management/sampling/create fishnet&#xff0c;12.4之前应…

POJ1408-Fishnet

全解题报告索引目录 -> 【北大ACM – POJ试题分类】 转载请注明出处&#xff1a;http://exp-blog.com ------------------------------------------------------------------------- 大致题意&#xff1a; 一个1X1的正方形&#xff0c;每条边上有n个不同的点&#xff08;…

关于在ArcGIS里创建fishnet时只有几个网格的解决办法

在ArcGIS里创建渔网时可能会出现以下情况&#xff0c;例如只有两个网格 可以看到在创建渔网的窗口中导入的数据中上下左右的单位是经纬度&#xff0c;不是米制单位。 这是由于在创建渔网时没有将坐标系进行转换&#xff0c;利用的shp数据本身的坐标系是度分秒单位的&#xf…

【ArcGIS微课1000例】0002:创建渔网(Create fishnet)

本文讲解ArcGIS软件中渔网(fishnet)工具的原理,方法及使用技巧。 文章目录 微课目标工具介绍实现过程微课目标 如下图所示,影像为无人机航测生产的DOM,现在需要在ArcGIS平台中进行DLG数据采集(数字化),由于测区较大,需要创建500*500的渔网,并对影像进行裁剪下发给多…

ArcGIS 10.2生成渔网(fishnet)

https://blog.csdn.net/lucky51222/article/details/72514885 工具路径&#xff1a;Data Management Tools→Feature Class→Create Fishnet。 &#xff08;1&#xff09;确定输出路径及文件名&#xff1b; &#xff08;2&#xff09;选择渔网范围&#xff0c;本例选择北方地区…

ArcGIS创建渔网Create Fishnet工具生成指定大小格网

本文介绍在ArcMap软件中&#xff0c;通过“Create Fishnet”工具创建渔网&#xff0c;从而获得指定大小的矢量格网数据的方法。 首先&#xff0c;我们在创建渔网前&#xff0c;需要指定渔网覆盖的范围。这里我们就以四川省为例&#xff0c;在这一范围内创建渔网&#xff1b;其中…

ArcGIS中ArcMap创建渔网Create Fishnet:生成指定大小的格网矢量文件

本文介绍在ArcMap软件中&#xff0c;通过“Create Fishnet”工具创建渔网&#xff0c;从而获得指定大小的矢量格网数据的方法。 首先&#xff0c;我们在创建渔网前&#xff0c;需要指定渔网覆盖的范围。这里我们就以四川省为例&#xff0c;在这一范围内创建渔网&#xff1b;其中…

Composited FishNet论文详解

论文名称&#xff1a;Composited FishNet: Fish Detection and Species Recognition From Low-Quality Underwater Videos Abstact (研究问题的重要意义&#xff0c;现在存在的问题&#xff0c;引出研究内容&#xff0c;研究内容的好处&#xff0c;本文创新点&#xff0c;实验…

利用ArcGIS处理土地利用数据:计算fishnet每个格网中不同地类的面积

前期准备&#xff1a;已经创建好的fishnet格网数据以及裁剪好的土地利用类型数据 创建渔网的过程就不讲了&#xff0c;创建渔网过程中可能遇见的问题在其他文章中也有讲到。我利用的土地利用类型数据是global30的数据。 首先将土地利用类型数据的属性表打开&#xff0c;添加一个…

Arcgis操作系列16-使用Arc Map创建渔网(fishnet)

1.目标&#xff1a;以生成一个范围包括黄陵县&#xff0c;格子大小为1000m的渔网为例。 2. 工具&#xff1a;Data Management Tools→Feature Class→Create Fishnet&#xff08;数据管理工具---要素类---创建渔网&#xff09; 3.步骤&#xff1a; &#xff08;1&#xff09;…

【ArcGIS风暴】ArcGIS 10.6创建规则格网(渔网fishnet)图文经典详解

GIS中常常需要地图分幅与编号,或者需要按照规则格网(三角网、矩形网等)去批量裁剪或提取矢量和栅格数据,相关内容可以参看下面的文章。本文主要详细讲解ArcGIS10.6软件中创建渔网的方法,为地图分幅或规则裁剪做好数据准备。 ArcGIS批量裁剪提取或分幅方法总结参考文章: 《…

FishNet网络结构阅读笔记

传统的残差网络&#xff0c;由于多了左边的卷积&#xff0c;导致像素不同&#xff0c;无法直接BP。而Fishnet的可以。 Figure2是FishNet的整体架构&#xff08;鱼型&#xff0c;左边是尾巴右边是头&#xff09;&#xff0c;Tail、Body、Head。主要讲三部分的类型、作用。 Tail是…