人臉自收集數(shù)據(jù)集輔助制作工具——人臉關鍵點數(shù)據(jù)標注

綜述

我們在進行人臉屬性識別深度學習算法研究過程中除了使用開源帶標簽的數(shù)據(jù)以外,都會根據(jù)具體使用場景與需求用到大量自收集的圖像數(shù)據(jù)(開源/爬蟲/自拍等),然這些數(shù)據(jù)一般是沒有人臉對應屬性標注標簽的。而我們在研究人臉各種檢測算法時最終訓練需要的數(shù)據(jù)就是圖像+標簽,所以如何快速標注這些特定數(shù)據(jù)便是數(shù)據(jù)收集工作的重點。本文主要講一下如何通過python工具輔助標注人臉關鍵點數(shù)據(jù),在此做一個分享。

標注目標確定

  • 待標注圖片:帶有人臉的照片(單人臉/人臉區(qū)域在整個圖像的占比足夠多)
  • 標注屬性:人臉68關鍵點坐標(如下圖所示)


    face_68_landmark_sample
  • 標簽文件:pts文本(可轉(zhuǎn)為txt)
  • 標注文本格式:
version: 1
n_points: 68
{
x0 y0
x1 y1
......
x67 y67
}
  • 數(shù)據(jù)命名規(guī)范:圖片文件與標簽文件同名(除后綴名以外)

輔助工具開發(fā)所需的關鍵技術

圖像按實際像素尺寸顯示

  • 實現(xiàn)功能:將圖像按左上角為坐標原點,水平向右為x軸正方向,垂直向下為y軸正方向
  • 關鍵代碼:
# 設置顯示圖片
im = Image.open(img_path)
# 創(chuàng)建figure(繪制面板)、創(chuàng)建圖表(axes)
self.fig, self.ax = plt.subplots()
plt.imshow(im)
# 設置標題
self.ax.set_title(img_path + "\n" + 'Click and drag a point to move it, this will update the ax txt!')
# 設置坐標軸范圍
self.img_size = im.size
self.ax.set_xlim(0, self.img_size[0])  # 圖片像素寬度
self.ax.set_ylim(0, self.img_size[1])  # 圖片像素高度
self.ax.xaxis.set_ticks_position('top')  # 將x軸的位置設置在頂部
self.ax.invert_yaxis()  # y軸反向

待標注圖像人臉關鍵點坐標初始化

  • 實現(xiàn)功能:將待標注圖片初始化一個帶68關鍵點坐標信息的標簽,需要使用預訓練好的深度學習模型(人臉區(qū)域檢測+人臉68關鍵點檢測)
  • 關鍵代碼:
def getFacePoit(self, img_path):
    """
    根據(jù)標簽文件中的坐標在人臉圖片上繪制關鍵點
    :param img_path: 待標注圖片路徑
    :param txt_path: 標注文件路徑
    :return:
    """
    
    x = []
    y = []
    self.txt_path = ""
    # 根據(jù)圖片路徑求得標簽文件路徑
    if os.path.splitext(img_path)[1] == '.jpg' or os.path.splitext(img_path)[1] == '.png':
        fileName = os.path.splitext(img_path)[0]
        self.txt_path = fileName + ".pts"
        # 判斷標簽文件后是否存在
        if not os.path.exists(self.txt_path):
            with open(self.txt_path, 'a') as fw:
                fw.write("version: 1" + "\n")
                fw.write("n_points: 68" + "\n")
                fw.write("{" + "\n")
                fw.close()
            # 調(diào)用模型輸出并寫入預測關鍵點坐標
            try:
                landmarks, x1, y1 = PFLD.getLandMarks(img_path)
                # if landmarks is not None:
                for (x0, y0) in landmarks.astype(np.float32):
                    with open(self.txt_path, 'a') as fw:
                        fw.write('%.7s' % str(x0+x1) + " " + '%.7s' % str(y0+y1) + "\n")
                        fw.close()
                    x.append(float('%.7s' % str(x0+x1)))
                    y.append(float('%.7s' % str((y0+y1))))
                with open(self.txt_path, 'a') as fw:
                    fw.write("}")
                    fw.close()
            except Exception:
                os.remove(self.txt_path)
                print("該圖片未檢測到人臉,無法輸出標簽數(shù)據(jù)")
        else:
            # 直接讀取標簽文件獲取關鍵點信息
            try:
                num_of_line = 1
                with open(self.txt_path, 'r') as f:
                    while True:
                        line = f.readline()
                        print(line)
                        if num_of_line <= 4:
                            print("非坐標行")
                        elif num_of_line > 4 and num_of_line < 73:
                            num = list(map(float, line.strip().split()))
                            # 坐標變換
                            x.append(float('%.7s' % str(num.__getitem__(0))))
                            y.append(float('%.7s' % str(num.__getitem__(1))))
                        else:
                            break
                        num_of_line = num_of_line + 1
            except Exception:
                os.remove(self.txt_path)
                print("該標簽數(shù)據(jù)不完整,請重新運行本程序?qū)懭?)
    return x, y

待標注圖像人臉關鍵點坐標動態(tài)設置與保存

  • 實現(xiàn)功能:將待標注圖片初始化的68關鍵點按像素位置繪制顯示到圖像中,并可以通過手動拖動未準確標注的關鍵點來矯正其位置,并更新保存到標簽文件中。
  • 關鍵代碼:
# 設置關鍵點初始值
self.x, self.y = self.getFacePoit(img_path) # 調(diào)用模型或讀取標簽文件中關鍵點坐標信息
# 繪制2D的點到圖像中
self.line = Line2D(self.x, self.y, ls="", marker='.', markersize=2, markerfacecolor='g', animated=True)
self.ax.add_line(self.line)
# 標志值設為none
self._ind = None
# 設置畫布,方便后續(xù)畫布響應事件
canvas = self.fig.canvas
self.fig.canvas.mpl_connect('draw_event', self.draw_callback)
self.fig.canvas.mpl_connect('button_press_event', self.button_press_callback)
self.fig.canvas.mpl_connect('button_release_event', self.button_release_callback)
self.fig.canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
self.canvas = canvas
plt.show()

標注工具完整工程地址

LandmarksAnnotation

工具使用

標注示例

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

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容