人臉自收集資料集輔助製作工具——人臉姿態資料標註
綜述
我們在進行人臉屬性識別深度學習演算法研究過程中除了使用開源帶標籤的資料以外,都會根據具體使用場景與需求用到大量自收集的影象資料(開源/爬蟲/自拍等),然這些資料一般是沒有人臉對應屬性標註標籤的。而我們在研究人臉各種檢測演算法時最終訓練需要的資料就是影象+標籤,所以如何快速標註這些特定資料便是資料收集工作的重點。本文主要講一下如何透過python工具輔助標註人臉姿態資料,在此做一個分享。
標註目標確定
待標註圖片:帶有人臉的照片(單人臉/人臉區域在整個影象的佔比足夠多/各種場景下的人臉)
標註屬性:人臉3個方向旋轉角度標註,偏航角yaw 左右轉頭(左+ 右-) 俯仰角pitch 抬頭低頭(上+ 下-) 翻滾角roll 左右歪頭(左- 右+)(如下圖所示)
姿態標註示意
標籤檔案: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())
標註工具完整工程地址
PoseAnnotation
工具使用
待標註圖片
標註資訊
至此,我們的人臉姿態角度標註工具便開發完成了,完美解決了人臉姿態資訊標註難的問題,極大提升了標註工作的效率,不知各位大佬是否還有其他更好的方法,歡迎評論區交流討論。