在网上看到很多例程,不过都讲的不是很好,既有自己单纯写的代码,又有利用opencv做的,但是在Python中利用opencv中的warpAffine函数的详细教程比较少,所以在我自己实现的基础上,写下了这篇文章。
首先你需要清楚的就是你是以什么位置为中心点,以什么角度做仿射变换,例如,我就是在通过mtcnn获得人脸的五个关键点坐标后,以双眼的位置中心为中心点,以双眼的倾斜角度为纠正角度,对其做放射变换。
其中的和
分别为两眼中心点的x和y值。
其中的dy和dx是两眼在y方向和x方向的差值,由此可以构建一个直角三角形,来表示倾斜角度。
上图是我画的示意图。
下面,贴出实现的代码
cols, rows, hn = img.shape
for subPoint in points_result:
print("左眼的位置(%s, %s)" % (subPoint[0], subPoint[5]))
print("右眼的位置(%s, %s)" % (subPoint[1], subPoint[6]))
eye_center_x = (subPoint[0] + subPoint[1]) * 0.5 # 322
eye_center_y = (subPoint[5] + subPoint[6]) * 0.5 # 218.256915
dy = subPoint[5] - subPoint[6] # 5.95704
dx = subPoint[0] - subPoint[1] # -72.19827
angle = math.atan2(dy, dx) * 180.0 / math.pi+180.0
print("旋转角度为: %s" % angle)
M = cv2.getRotationMatrix2D((eye_center_x, eye_center_y), angle, 1)
dst = cv2.warpAffine(img, M, (cols, rows))
img是原图像,dst是变换后的图像
里面用到了opencv里的getRotationMatrix2D()以及waripAffine()两个函数,这两个函数自行百度吧,这里我就不多介绍了,下面贴出效果图。
上图是未使用仿射变换时,所截到的人脸图
最后一张图,是经过仿射变换后得到的,怎么样,如果不看原图的话,是不是很难看出来本来市长倾斜的脸,总体来说效果还可以,不过还有需要改进的地方,等待后续完善吧,拜拜!