如何通过地标点注册面孔

时间:2014-08-08 14:18:45

标签: image-processing computer-vision face-recognition

面部识别是人脸识别系统中的一项重要任务。我知道如何通过像this这样的两个眼睛中心点来注册脸部。但我不知道如何使用超过两点(例如两个眼睛中心,鼻尖和两个嘴角)进行面部注册。

有什么想法吗?提前谢谢!

2 个答案:

答案 0 :(得分:2)

如果你有很多分数,比如68 ..然后你可以执行delaunay三角测量然后执行分段仿射变形。

如果你有少于68,比如5或6,那么你可以尝试最小二乘拟合仿射或透视变换。我相信您可以使用opencv的findhomography函数,然后使用perspectivetransform函数执行此步骤。

答案 1 :(得分:1)

对于2D对齐 - 要发现将一组地标点映射到另一组的仿射变换 - 您最好从经典Procrustes Analysis开始。

Here某人非常慷慨地提供了一个转换后的实现(从Matlab)到python。

使用这个,在这里我可以做我认为你想做的事情......

import procrustes as pc 
import numpy as np 
import matplotlib.pyplot as plt
import matplotlib.cm as cm 
import cv2

# Open images...
target_X_img = cv2.imread('arnie1.jpg',0)
input_Y_img = cv2.imread('arnie2.jpg',0)

# Landmark points - same number and order!
# l eye, r eye, nose tip, l mouth, r mouth
X_pts = np.asarray([[61,61],[142,62],[101,104],[71,143],[140,139]])
Y_pts = np.asarray([[106,91],[147,95],[129,111],[104,130],[141,135]])

# Calculate transform via procrustes...
d,Z_pts,Tform = pc.procrustes(X_pts,Y_pts)

# Build and apply transform matrix...
# Note: for affine need 2x3 (a,b,c,d,e,f) form
R = np.eye(3)
R[0:2,0:2] = Tform['rotation']
S = np.eye(3) * Tform['scale'] 
S[2,2] = 1
t = np.eye(3)
t[0:2,2] = Tform['translation']
M = np.dot(np.dot(R,S),t.T).T
tr_Y_img = cv2.warpAffine(input_Y_img,M[0:2,:],(400,400))

# Confirm points...
aY_pts = np.hstack((Y_pts,np.array(([[1,1,1,1,1]])).T))
tr_Y_pts = np.dot(M,aY_pts.T).T

# Show result - input transformed and superimposed on target...
plt.figure() 
plt.subplot(1,3,1)
plt.imshow(target_X_img,cmap=cm.gray)
plt.plot(X_pts[:,0],X_pts[:,1],'bo',markersize=5)
plt.axis('off')
plt.subplot(1,3,2)
plt.imshow(input_Y_img,cmap=cm.gray)
plt.plot(Y_pts[:,0],Y_pts[:,1],'ro',markersize=5)
plt.axis('off')
plt.subplot(1,3,3)
plt.imshow(target_X_img,cmap=cm.gray)
plt.imshow(tr_Y_img,alpha=0.6,cmap=cm.gray)
plt.plot(X_pts[:,0],X_pts[:,1],'bo',markersize=5) 
plt.plot(Z_pts[:,0],Z_pts[:,1],'ro',markersize=5) # same as...
plt.plot(tr_Y_pts[:,0],tr_Y_pts[:,1],'gx',markersize=5)
plt.axis('off')
plt.show()

enter image description here

所有这些只适用于平面/刚性和仿射变换。一旦你开始不得不迎合非仿射/透视和可变形表面,那么,这是一个完全不同的主题......