综述
我们在进行人脸属性识别深度学习算法研究过程中除了使用开源带标签的数据以外,都会根据具体使用场景与需求用到大量自收集的图像数据(开源/爬虫/自拍等),然这些数据一般是没有人脸对应属性标注标签的。而我们在研究人脸各种检测算法时最终训练需要的数据就是图像+标签,所以如何快速标注这些特定数据便是数据收集工作的重点。本文主要讲一下如何通过python工具辅助标注人脸姿态数据,在此做一个分享。
标注目标确定
- 待标注图片:带有人脸的照片(单人脸/人脸区域在整个图像的占比足够多/各种场景下的人脸)
-
标注属性:人脸3个方向旋转角度标注,偏航角yaw 左右转头(左+ 右-) 俯仰角pitch 抬头低头(上+ 下-) 翻滚角roll 左右歪头(左- 右+)(如下图所示)
pose - 标签文件:txt文本
- 标注文本格式:
图片文件相对路径 yaw pitch roll
}
- 数据命名规范:图片文件根目录与标签文件同名(除后缀名以外)
辅助工具开发所需的关键技术
去坐标图像显示
- 实现功能:将图像正常显示在一个控件内,去除各种干扰显示
- 关键代码:
# 显示待标记图片
im = Image.open(img_path)
plt.imshow(im)
plt.xticks([]) # 去掉横坐标值
plt.yticks([]) # 去掉纵坐标值
plt.axis('off')
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
plt.margins(0, 0)
plt.show()
待标注图像遍历处理
- 实现功能:遍历待标注图片,并逐一进行显示和标注操作
- 关键代码:
def MarkToolWithImg(wait_mark_image_root_path, output_label_txt_path):
"""
根据图片标注并生成标签文件
:param wait_mark_image_root_path: 待标记图片根目录路径
:param output_label_txt_path: 输出标签路径
:return:
"""
for parent, dirnames, filenames in os.walk(wait_mark_image_root_path):
for filename in filenames:
img_path = os.path.join(parent, filename)
# 消重
f = open('Face_data_mark.log', 'rb')
a = f.readlines()
matchObj = re.search(filename, "%s" % a, re.M | re.I)
if matchObj:
print(img_path + " 已标记过")
else:
print("正在标记:" + str(img_path))
imgShowAndMark(img_path, output_label_txt_path, None)
def MarkToolWithTxt(label_txt_path):
"""
根据标签文件定位图片并更新标注
:param label_txt_path: 已标注标签路径
:return:
"""
with open(label_txt_path, 'r') as tt:
while True:
try:
line = tt.readline()
num = list(map(str, line.strip().split()))
# 获取图片路径
img_path = num.__getitem__(0)
# 过滤已标注的行
with open('Face_data_mark.log', 'r') as fdm:
markedLines = fdm.readlines()
fdm.close()
current_img_name = os.path.basename(img_path)
print(current_img_name)
is_mark = False
for c in markedLines:
if current_img_name.strip() in c:
print(img_path + " 已标注过")
is_mark = True
if is_mark is False:
print("正在标注:" + str(img_path))
imgShowAndMark(img_path, label_txt_path, line)
except Exception as e:
print("标注结束:" + str(e))
break
tt.close()
待标注图像人脸姿态角度动态设置与保存
- 实现功能:判断待标注图片中人脸三个方向的姿态角度旋转情况,并可以通过手动输入标注3个方向的姿态角度(-90~90),并保存到标签文件中。
- 关键代码:
if current_line != None:
# 获取待标注目标行原信息
global linelist
with open(label_txt_path, 'r') as fr:
linelist = fr.readlines()
fr.close()
# 待标注行信息
global oldLine
for line in linelist:
if img_path in line:
oldLine = line
# 根据对比信息标注新的属性值
newLine = myInput("请输入当前图片姿态 Yaw Pitch Roll 属性,已标注属性提示为:" + str(current_line))
print("你输入的属性值为,{}!".format(newLine).strip())
# 用新标注行替换原标注行
replaceLine(label_txt_path, oldLine, newLine)
else:
newLine = myInput("请输入当前图片姿态 Yaw Pitch Roll 属性")
print("你输入的属性为,{}!".format(newLine).strip())
with open(label_txt_path, "a") as ot:
ot.write(newLine)
ot.close()
# 插入对应标签文件指定行
logging.info("已标记为:" + str(newLine).strip())
标注工具完整工程地址
工具使用
待标注图片
标注信息
至此,我们的人脸姿态角度标注工具便开发完成了,完美解决了人脸姿态信息标注难的问题,极大提升了标注工作的效率,不知各位大佬是否还有其他更好的方法,欢迎评论区交流讨论。