由于原作者的FAN-2D模型中,是基于一个头网络+4个Hourglass模块,在Titan X上需要43-50ms的处理时间。为了提高一些模型速度,这里尝试重新压缩简化一下模型,只采用2个Hourglass模块。
由于作者并未开放pytorch版的训练源码,因此根据自己的理解重新实现训练代码,并进行训练验证。
数据集准备
计划使用300W-LP数据集。并根据数据集生成对应的Heatmaps标签文件。
主要利用torc.utils.data.Dataset包以及torch.utils.data.DataLoader包,实现数据的读入与处理。主要的代码如下:
def createheatmap(landmarks,map_height,map_width,num_points=68):
#输入关键点的归一化x坐标和y坐标(x/img_width,y/img_height)
heatmap=np.zeros((map_height,map_width,num_points),dtype=np.float)
assert(len(landmarks)==num_points)
for p in range(len(landmarks)):
x=landmarks[p][0]*map_width
y=landmarks[p][1]*map_height
for i in range(map_width):
for j in range(map_height):
if (x-i)*(x-i)+(y-j)*(y-j)<=4:
heatmap[j][i][p]=1.0/(1+(x-i)*(x-i)*2+(y-j)*(y-j)*2)
return heatmap
def cropandrecalculatepoints(landmarks,img_pil,pad=0.3):
#根据关键点,将人脸区域pad后,再crop出来,并且为正方形的方式crop(对于pad后超出图像范围的部分直接用黑色背景填充)
w,h = img_pil.size
land_np=np.array(landmarks)
xmin=int(np.min(land_np[:,0]))
xmax=int(np.max(land_np[:,0]))
ymin=int(np.min(land_np[:,1]))
ymax=int(np.max(land_np[:,1]))
x_center=int((xmax-xmin)/2+xmin)
y_center=int((ymax-ymin)/2+ymin)
pad=pad
cropsize= int((1+pad)*(ymax-ymin)) if ((ymax-ymin)>(xmax-xmin)) else int((1+pad)*(xmax-xmin))
xmin,xmax=int(x_center-cropsize/2),int(x_center+cropsize/2)
ymin,ymax=int(y_center-cropsize/2),int(y_center+cropsize/2)
#print(xmin,xmax,ymin,ymax)
newimg=np.array(img_pil.convert('RGB'))
mask=np.zeros(np.array([cropsize,cropsize,3], dtype=np.int32),dtype=np.uint8)
newX=np.array([max(1, xmin+1), min(xmax, w)],dtype=np.int32) #在原图crop的x方向位置
newY=np.array([max(1, ymin+1), min(ymax, h)], dtype=np.int32) #在原图crop的y方向位置
maskX=np.array([max(1,-xmin+1), min(xmax,w)-xmin], dtype=np.int32) #crop的区域在mask上的x方向放置范围
maskY=np.array([max(1,-ymin+1), min(ymax,h)-ymin], dtype=np.int32) #crop的区域在mask上的y方向放置范围
#print(newX,newY,maskX,maskY)
mask[maskY[0] - 1:maskY[1], maskX[0] - 1:maskX[1]] = newimg[newY[0] - 1:newY[1], newX[0] - 1:newX[1], :] #将输入图像crop的区域放置到mask对应区域
landmarks_crop=np.array(land_np)
#print (land_np.shape,landmarks_crop.shape)
landmarks_crop[:,0]-=xmin
landmarks_crop[:,1]-=ymin
landmarks_crop=landmarks_crop*1.