Aligning face images

Aligning face images

Some people have asked me how I've aligned the face images in my articles. Giving people my ImageMagick hack is embarrassing for me, so I've decided to rewrite it into a Python script. You don't need to copy and paste it, as the script comes with the source folder of my Guide on Face Recognition: crop_face.py.

The code is really easy to use. To scale, rotate and crop the face image you just need to callCropFace(image, eye_left, eye_right, offset_pct, dest_sz), where:

  • eye_left is the position of the left eye
  • eye_right is the position of the right eye
  • offset_pct is the percent of the image you want to keep next to the eyes (horizontal, vertical direction)
  • dest_sz is the size of the output image

If you are using the same offset_pct and dest_sz for your images, they are all aligned at the eyes.

example

Imagine we are given this photo of Arnold Schwarzenegger, which is under a Public Domain license. The(x,y)-position of the eyes are approximately(252,364) for the left and(420,366) for the right eye. Now you only need to define the horizontal offset, vertical offset and the size your scaled, rotated & cropped face should have. Here are some examples:

ConfigurationCropped, Scaled, Rotated Face
0.1 (10%), 0.1 (10%), (200,200)configuration
0.2 (20%), 0.2 (20%), (200,200)configuration
0.3 (30%), 0.3 (30%), (200,200)configuration
0.2 (20%), 0.2 (20%), (70,70)configuration

crop_face.py

#!/usr/bin/env python
# Software License Agreement (BSD License)
#
# Copyright (c) 2012, Philipp Wagner
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of the author(s) nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import sys, math, Image

def Distance(p1,p2):
  dx = p2[0] - p1[0]
  dy = p2[1] - p1[1]
  return math.sqrt(dx*dx+dy*dy)

def ScaleRotateTranslate(image, angle, center = None, new_center = None, scale = None, resample=Image.BICUBIC):
  if (scale is None) and (center is None):
    return image.rotate(angle=angle, resample=resample)
  nx,ny = x,y = center
  sx=sy=1.0
  if new_center:
    (nx,ny) = new_center
  if scale:
    (sx,sy) = (scale, scale)
  cosine = math.cos(angle)
  sine = math.sin(angle)
  a = cosine/sx
  b = sine/sx
  c = x-nx*a-ny*b
  d = -sine/sy
  e = cosine/sy
  f = y-nx*d-ny*e
  return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=resample)

def CropFace(image, eye_left=(0,0), eye_right=(0,0), offset_pct=(0.2,0.2), dest_sz = (70,70)):
  # calculate offsets in original image
  offset_h = math.floor(float(offset_pct[0])*dest_sz[0])
  offset_v = math.floor(float(offset_pct[1])*dest_sz[1])
  # get the direction
  eye_direction = (eye_right[0] - eye_left[0], eye_right[1] - eye_left[1])
  # calc rotation angle in radians
  rotation = -math.atan2(float(eye_direction[1]),float(eye_direction[0]))
  # distance between them
  dist = Distance(eye_left, eye_right)
  # calculate the reference eye-width
  reference = dest_sz[0] - 2.0*offset_h
  # scale factor
  scale = float(dist)/float(reference)
  # rotate original around the left eye
  image = ScaleRotateTranslate(image, center=eye_left, angle=rotation)
  # crop the rotated image
  crop_xy = (eye_left[0] - scale*offset_h, eye_left[1] - scale*offset_v)
  crop_size = (dest_sz[0]*scale, dest_sz[1]*scale)
  image = image.crop((int(crop_xy[0]), int(crop_xy[1]), int(crop_xy[0]+crop_size[0]), int(crop_xy[1]+crop_size[1])))
  # resize it
  image = image.resize(dest_sz, Image.ANTIALIAS)
  return image

if __name__ == "__main__":
  image =  Image.open("arnie.jpg")
  CropFace(image, eye_left=(252,364), eye_right=(420,366), offset_pct=(0.1,0.1), dest_sz=(200,200)).save("arnie_10_10_200_200.jpg")
  CropFace(image, eye_left=(252,364), eye_right=(420,366), offset_pct=(0.2,0.2), dest_sz=(200,200)).save("arnie_20_20_200_200.jpg")
  CropFace(image, eye_left=(252,364), eye_right=(420,366), offset_pct=(0.3,0.3), dest_sz=(200,200)).save("arnie_30_30_200_200.jpg")
  CropFace(image, eye_left=(252,364), eye_right=(420,366), offset_pct=(0.2,0.2)).save("arnie_20_20_70_70.jpg")

opencv 仿射变换

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.html

c#code

        Image<Bgr, byte> cutImg(Image<Bgr, byte> img,Point eyeleft,Point eyeright)
        {
            double[] offset = { 0.2, 0.2 };
            int dest_w = 100;
            int dest_h = 100;         
            double angle = -Math.Atan2(eyeright.Y - eyeleft.Y, eyeright.X -eyeleft.X);
            double Dik = Math.Sqrt(Math.Pow(eyeleft.X - eyeright.X, 2) + Math.Pow(eyeleft.Y - eyeright.Y, 2));
            int offset_h = Convert.ToInt16(offset[0] * dest_w);
            int offset_v = Convert.ToInt16(offset[1] * dest_h);
            double reference = dest_w - 2.0 * offset_h;
            double scale = Dik / reference;
            img = img.Rotate(angle / Math.PI * 180, eyeleft, INTER.CV_INTER_AREA, new Bgr(Color.Black), true);
            Rectangle rect = new Rectangle(new Point(Convert.ToInt16(eyeleft.X - scale * offset_h), Convert.ToInt16(eyeleft.Y - scale * offset_v)), new Size(Convert.ToInt16(dest_w * scale), Convert.ToInt16(dest_w * scale)));
            img.ROI = rect;
            img = img.Resize(dest_w, dest_h, Emgu.CV.CvEnum.INTER.CV_INTER_AREA);
            return img;
        }

C++code

Mat cutImage(Mat src,Point2f eyeleft,Point2f eyeright)  
{  
	Mat dst;
	dst=Mat::zeros( src.rows, src.cols, src.type());
	float offset[2] = { 0.2, 0.2 };  
	int dest_w = 100;  
	int dest_h =100;           
	float angle = atan2(eyeright.y - eyeleft.y, eyeright.x -eyeleft.x);  
	float Dik = sqrt(pow(eyeleft.x - eyeright.x, 2) + pow(eyeleft.y - eyeright.y, 2));  
	int offset_h =offset[0] * dest_w;  
	int offset_v =offset[1] * dest_h;  
	float reference = dest_w - 2.0 * offset_h;  
	float scale = Dik / reference; 
	Mat rot_mat(2,3,CV_32FC1);
	angle=angle/CV_PI*180.0;
	rot_mat=getRotationMatrix2D(eyeleft,angle,scale);
	warpAffine(src,dst,rot_mat,src.size());
	Rect rect((int)(eyeleft.x-scale*offset_h),(int)(eyeleft.y - scale * offset_v),(int)(dest_w * scale), (int)(dest_w * scale));   
	dst=dst(rect);
	Mat dst2=Mat(Size(dest_w,dest_h),src.type());
	resize(dst,dst2,dst2.size());
	//namedWindow("warp_window",CV_WINDOW_AUTOSIZE);
	//imshow("warp_window",dst2);
	//namedWindow("src_window",CV_WINDOW_AUTOSIZE);
	//imshow("src_window",dst);	
	//waitKey(0);
	return dst2;
}

标题人事档案管理系统设计与实现研究AI更换标题第1章引言介绍人事档案管理系统的研究背景、意义、国内外研究现状以及论文的方法和创新点。1.1研究背景与意义分析人事档案管理在企业中的重要性及系统开发的必要性。1.2国内外研究现状概述国内外人事档案管理系统的研究进展和现状。1.3研究方法及创新点阐述本文的研究方法和在系统设计上的创新点。第2章相关理论介绍人事档案管理系统设计的相关理论。2.1档案管理理论阐述档案分类、存储、检索等基本理论。2.2信息系统开发理论介绍信息系统开发的基本流程、方法和技术。2.3数据库管理理论讨论数据库设计、数据安全与备份等理论。第3章人事档案管理系统设计详细介绍人事档案管理系统的设计方案和实现过程。3.1系统需求分析分析系统的功能需求、性能需求和用户需求。3.2系统架构设计给出系统的整体架构、模块划分和交互流程。3.3数据库设计设计数据库结构,包括表结构、字段设置和关系模型。第4章系统实现与测试阐述人事档案管理系统的实现过程和测试方法。4.1系统开发环境与工具介绍系统开发所使用的环境和工具。4.2系统实现过程详细描述系统各个模块的实现过程和关键代码。4.3系统测试与优化对系统进行功能测试、性能测试和安全测试,并进行优化。第5章研究结果与分析呈现人事档案管理系统的实验分析结果。5.1系统功能实现情况介绍系统各项功能的实现情况和效果。5.2系统性能评估从响应时间、吞吐量等指标评估系统性能。5.3对比方法分析将本系统与其他类似系统进行对比分析,突出优势。第6章结论与展望总结本文的研究成果,并展望未来的研究方向。6.1研究结论概括本文的主要研究结论和系统实现效果。6.2展望指出系统存在的不足和未来改进的方向。
提供了关于时间序列分析与预测的宝贵资源,特别聚焦于**自回归积分滑动平均模型(ARIMA)**及其应用。对于那些希望深入理解并实践时间序列建模的学者、研究人员以及数据分析爱好者来说,这是一个不可或缺的学习材料。本资源不仅包括了详细的理论讲解,涵盖了时间序列分析的基础,如移动平均(MA)、自回归(AR)、指数平滑等关键概念,而且通过具体的ARIMA模型解析,搭配MATLAB编程实现实例,帮助用户从理论到实践全面掌握这一重要统计工具。 内容概览 理论讲解: 深入浅出地介绍了时间序列分析的基本原理,重点阐述ARIMA模型的构建步骤,包括如何识别模型的参数(p,d,q),以及其在处理非平稳数据中的作用。 MATLAB代码实现: 提供了多个ARIMA模型的MATLAB实现示例,这些代码覆盖了从数据准备、模型拟合、诊断检验到预测的全过程,是学习如何利用MATLAB进行时间序列分析的实用工具。 实例分析: 包括不同行业或领域的实际案例研究,展示如何应用ARIMA及其它时间序列方法解决真实世界的数据预测问题,增强理解和应用能力。 文件结构 时间序列模型ARIMA的讲解与matlab代码实现(含多个实例).rar: 主要资源压缩包,解压后包含文档和MATLAB代码文件夹。 文档: 提供了理论知识讲解。 MATLAB代码: 实现了文中讨论的各种模型,附带注释,便于理解与修改。 使用指南 下载资源: 点击下载“时间序列模型ARIMA的讲解与matlab代码实现(含多个实例).rar”文件。 解压文件: 解压缩至本地,确保你可以访问文档和代码。 环境准备: 确保你的电脑上已安装MATLAB,并熟悉基本操作。 学习流程: 首先阅读文档理解时间序列分析的理论基础,然后逐步跟随MATLAB代码示例进行实践。 实践应用: 尝试将所学应用到自己的数据集上,调整参数以优化模型性能。 注意事项 请根据M
自然语言处理技术日益发展,就如何让机器能够理解和执行人类指令这一问题,成为了研究的重要方向。这涉及到如何将自然语言和机器学习模型有效地融合,从而让机器能够通过自然语言理解人类的指令,并按照指令进行行动。 据目前的研究表明,最有效的方法是对语言模型进行训练,通过数据驱动的方法,让机器能够理解人类的指令,从而完成特定的任务。要实现这一目标,需要采用一定的语言模型和机器学习算法。 其中,最流行的算法包括序列标注、文本生成、神经机器翻译等。这些算法都能通过对文本进行深度学习来训练模型,从而让机器能够更好地理解指令和完成任务。 然而,一些挑战依然存在。首先,不同的语言之间存在巨大的差异,因此需要针对不同的语言训练不同的模型。其次,语言模型需要和任务场景建立紧密的联系,才能更好地理解和执行指令。 最后,持续的技术进步也需要不断地改进和更新语言模型,以保证在不同的场景下,机器能够更好地理解和执行人类的指令。这意味着,对数据的收集和处理,对算法和模型的优化,都需要不断地实践和创新。 总之,针对语言模型的训练和优化,是实现机器按照人类指令执行的关键。只有通过不断的探索和实践,才能让机器更好地理解我们的指令,并更加有效地完成任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值