綜述
我們在進行人臉屬性識別深度學習算法研究過程中除了使用開源帶標簽的數(shù)據(jù)以外,都會根據(jù)具體使用場景與需求用到大量自收集的圖像數(shù)據(jù)(開源/爬蟲/自拍等),然這些數(shù)據(jù)一般是沒有人臉對應屬性標注標簽的。而我們在研究人臉各種檢測算法時最終訓練需要的數(shù)據(jù)就是圖像+標簽,所以如何快速標注這些特定數(shù)據(jù)便是數(shù)據(jù)收集工作的重點。本文主要講一下如何通過python工具輔助標注人臉遮擋數(shù)據(jù),在此做一個分享。
標注目標確定
- 待標注圖片:帶有人臉的照片(單人臉/人臉區(qū)域在整個圖像的占比足夠多/各種場景下包括遮擋和正常的人臉)
-
標注屬性:人臉7個主要區(qū)域遮擋標注,0為未遮擋,1為遮擋(如下圖所示)
人臉遮擋區(qū)域劃分 - 標簽文件:txt文本
- 標注文本格式:
圖片文件相對路徑 左眼遮擋標志 右眼遮擋標志 鼻子遮擋標志 嘴巴遮擋標志 下巴遮擋標志 左臉遮擋標志 右臉遮擋標志
}
- 數(shù)據(jù)命名規(guī)范:圖片文件根目錄與標簽文件同名(除后綴名以外)
輔助工具開發(fā)所需的關鍵技術
去坐標圖像顯示
- 實現(xiàn)功能:將圖像正常顯示在一個控件內(nèi),去除各種干擾顯示
- 關鍵代碼:
# 顯示待標記圖片
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()
待標注圖像遍歷處理
- 實現(xiàn)功能:遍歷待標注圖片,并逐一進行顯示和標注操作
- 關鍵代碼:
def MarkToolWithImg(wait_mark_image_root_path, output_label_txt_path):
"""
根據(jù)圖片標注并生成標簽文件
: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):
"""
根據(jù)標簽文件定位圖片并更新標注
:param label_txt_path: 已標注標簽路徑
:return:
"""
num_of_line = 1
with open(label_txt_path, 'r') as tt:
while True:
line = tt.readline()
num = list(map(str, line.strip().split()))
img_path = num.__getitem__(0)
# 消重
f = open('Face_data_mark.log', 'r')
a = f.readlines()
current_img_name = os.path.basename(img_path)
print(current_img_name)
is_mark = False
for c in a:
if current_img_name.strip() in c:
# if matchObj:
print(img_path + " 已標記過")
is_mark = True
if is_mark is False:
print("正在標記:" + str(img_path))
imgShowAndMark(img_path, label_txt_path, num_of_line)
num_of_line += 1
待標注圖像人臉遮擋情況動態(tài)設置與保存
- 實現(xiàn)功能:判斷待標注圖片中人臉的遮擋情況,并可以通過手動輸入標注七個區(qū)域的遮擋與否,并保存到標簽文件中。
- 關鍵代碼:
if relaceLineNum != None:
# 自定義輸入屬性
lines = []
with open(label_txt_path, 'r') as fr:
linelist = fr.readlines()
fr.close()
for l in linelist:
lines.append(l)
newLine = myInput("請輸入當前圖片7遮擋屬性,已標記屬性為:" + str(lines[relaceLineNum - 1]))
print("你輸入的屬性為,{}!".format(newLine).strip())
# 替換對應標簽文件指定行
replaceLine(label_txt_path, relaceLineNum, str(img_path) + " " + newLine)
else:
newLine = myInput("請輸入當前圖片7遮擋屬性")
print("你輸入的屬性為,{}!".format(newLine).strip())
with open(label_txt_path, "a") as ot:
ot.write(newLine)
ot.close()
logging.info("已標記:" + str(img_path) + " 屬性為:" + str(newLine).strip())
標注工具完整工程地址
工具使用

wait_label_img

label_info
至此,我們的人臉遮擋標注工具便開發(fā)完成了,完美解決了人臉遮擋信息標注難的問題,極大提升了標注工作的效率,不知各位大佬是否還有其他更好的方法,歡迎評論區(qū)交流討論。
