手勢自動標記及分類工具

傳統的手勢辨識採用影像處理手法,針對手部圖片進行影像分析,重點在於形狀及特徵點的取得,缺點是需要控制嚴格的外在環境因子(如燈光、背景、顏色…等),以避免在影像分析時造成干擾。而近年來得利於AI技術,透過深度學習自動萃取特徵並進行影像分類及物件偵測,可讓手勢辨識變得更加精確也不易受外在環境所干擾。

不過,如果您打算自行訓練一個手勢辨識模型,首先要面對的第一項工作便是圖片的搜集及標記,這是一個相當繁雜且花時間的人力密集工作,因此,如果有個方便好用的工具能自動將影片或攝影機中的手勢,自動裁切並依手勢類型分類好,甚至於還能手勢自動標記好,那不是非常的方便嗎?

可以的,我們只要先訓練好一個偵測手部的模型,便可以利用它來製作一個手勢自動分類及標記的工具,來產生兩種類型的dataset:

  1. Classified image dataset
  2. VOC labeled dataset

本文目的是希望透過該工具,可節省

  1. 圖片資料搜集
  2. 圖片分類
  3. 圖片標記

這三項工作上的時間,而我們唯一的工作僅是準備影片、或者在鏡頭前比出需要的各種手勢,讓該工具直接替我們產生出可直接用來訓練影像分類或物件偵測使用的dataset。

製作手部偵測模型

不過,在設計這套工具之前,我們需要訓練一個手部偵測模型,這個模型的目的是,無論是任何姿勢,只要是人的手掌都要能偵測到。至於如何訓練該模型,您可使用任何常用的開源物件偵測framework,下方我們分別以YOLOV3-Tiny以及SSD-Mobilenet 2作為訓練示範,dataset則是使用兩種開源hand dataset以及一個自製的hand dataset來訓練。

訓練的dataset介紹

下方介紹兩個開源的dataset以及一個自己製作的dataset:

A) EgoHands: A Dataset for Hands in Complex Egocentric Interactions

  1. 網址: http://vision.soic.indiana.edu/projects/egohands/
  2. 該dataset來源為48個影片(二個人在進行互動遊戲,以第一人稱視角拍攝)。
  3. 圖片尺寸為720x1280px,每個影片匯出100 frames並已labeled,總計有4800張。
  4. Label的格式為matlab的mat檔,poly多邊形(每個手部約200~300 points)。

B) VGG hand dataset

  1. 網址: http://www.robots.ox.ac.uk/~vgg/data/hands/
  2. VGG (Visual Geometry Group)為牛津大學工程科學系的社群。
  3. 已分為train/test/validation三個dataset,圖片來源為其它開源影像資料庫(如PASCAL VOC…)以及電影片段。
  4. Label為依物體長寬而變化傾斜的矩形,非常用的左右垂直上下水平的label,使用Matlab的mat格式。
  5. 圖片尺寸不定,長寬一般介於300~600px之間。

http://www.robots.ox.ac.uk/~vgg/data/hands/hand_dataset_files/Picture_1.png

C) 自拍的hand dataset

  1. 使用webcam拍攝,尺寸為640x480px,數量1,723張。
  2. 原先是作為數字0~5的手勢dataset,VOC格式的label。
  3. 拍攝地點為office。

Hand dataset格式轉換

EgoHands以及VGG hand dataset的標記格式皆是Matlab的mat,我習慣先將它們轉為PASCAL VOC格式,以方便後續YOLO或是SSD models的訓練。

EgoHands dataset

  1. 下載EgoHands dataset:

進入http://vision.soic.indiana.edu/projects/egohands/後,點選下圖中紅框的link,不需申請即可直接下載。

  1. 解壓後,第一層的metadata.mat即為存放標記資訊的地方。圖片則放置於_LABELLED_SAMPLES folder。

  1. 轉為VOC格式檔
  1. 轉檔結果

會於指定的palm_egohands/目錄下,產生labels及images兩個資料夾,接著,你可用labelImg開啟,檢驗格式轉換是否正確。如下圖所示,轉換結果正確。

VGG hand dataset

  1. dataset下載:進入http://www.robots.ox.ac.uk/~vgg/data/hands/,點選下方的link,不需申請即可直接下載。

  1. 下載解壓後,內有training、test、validation等三個資料夾,每個資料夾下分為images及annotations兩個目錄,每個圖檔搭配一個與圖檔同名的matlab標記檔。
  2. 新增images及annotations目錄,接著將各目錄下的images圖檔及annotations標記檔,集中放置於新建的images及annotations資料夾中。
  3. 轉為VOC格式檔
  1. 轉檔結果

會於指定的palm_oxford_hands/train/目錄下,產生labels及images兩個資料夾,接著,你可用labelImg開啟,檢驗格式轉換是否正確。如下圖所示,轉換結果正確。

Palm detection 訓練

下面我們分別使用YOLOV3-Tiny以及SSD-Mobilenet來訓練此手部偵測模型。

YOLOV3-Tiny訓練

可利用我之前所撰寫的makeYOLOV3程式,只需要在安裝好Darknet環境的PC上,輸入VOC格式dataset的路徑,便可自動轉換為YOLO dataset,接著產生YOLO的data、cfg、names等設定檔案、執行結束後會顯示您所要執行的訓練command,只需要copy/paste執行該行指令便可開始訓練。

另外,訓練之前,建議先執行先驗框程式,取得六組先驗框(YOLOV3為九組)放在yolov3-tiny.cfg的anchors參數中。

訓練過程:

SSD-Mobilenet V2訓練

  1. 轉換為Tensorflow TF-Record dataset
  1. Download pre-trained model及config file

models: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md

Download ssd_mobilenet_v2_coco.config: https://github.com/tensorflow/models/tree/master/research/object_detection/samples/configs

  1. 修改ssd_mobilenet_v2_coco.config,灰色字的部份。

num_classes:1

batch_size:24

fine_tune_checkpoint: “ssd_mobilenet_v2_coco/model.ckpt"

train_input_reader: {

tf_record_input_reader {

input_path: “ssd_dataset/train.record"

}

label_map_path: “ssd_dataset/object-detection.pbtxt"

}

eval_input_reader: {

tf_record_input_reader {

input_path: “ssd_dataset/test.record"

}

label_map_path: “ssd_dataset/object-detection.pbtxt"

shuffle: false

num_readers: 1}

  1. 開始訓練。

python train.py –logtostderr –train_dir=/home/chtseng/works/train_palm_model/training/ –pipeline_config_path=/home/chtseng/works/train_palm_model/palm_ssd_mobilenet_v2.config

在Jetson Nano上測試手部偵測模型的效果

將圖片size縮小至VGA尺寸後,Jetson Nano開發板上透過GPU加速,YOLOV3-Tiny與SSD-MobileNetV2的FPS皆可到七以上。

YOLOV3-Tiny

SSD-MobileNetV2

這個手部偵測模型將可協助我們取得影像中的手部區域,接著我們便可設計程式針對該區域進行標記或分類,以便於產生手部的classification dataset以及VOC labeled dataset。舉例來說,我們透過鍵盤輸入手勢的名稱,接著在鏡頭前比出各種需要的手勢,該工具便可自動將手部區域crop另外儲存為依類別分類的手勢圖片庫,或者自動label成VOC dataset。

開始製作手勢自動分類及標記工具

在上文中,我們已經利用數個開源的手勢dataset訓練好了一個可偵測手部的YOLOV3-Tiny模型,其效果如下:

接下來將介紹如何利用此model來設計一個工具,可協助我們產生下列二種dataset:

  1. 已label好的手勢VOC dataset
  2. 依手勢類別分類好的classified dataset。

參數說明

程式請參考附錄,所使用的參數如下:

#想要要偵測的物件名稱。

#本例的model只有一個物件,也是我們所打算偵測的

objects = (“palm")

#每隔多少frame才偵測一次?以避免相似的圖片太多。

frame_interval = 3

#物件偵測分數需高於多少?此值設高則precision高,但recall及accuracy低,反之亦然。

#如果您希望自動偵測出的結果一定都要對的,那就把它設高。

#如果希望不要有物件未被偵測到,那麼就把它設低。

score = 0.9

#所有自動label及自動classify完成的dataset,會放在此路徑下。

datasetPath = “hand_gestures/"

# classified dataset的目錄名稱

#本程式會產生兩種classified dataset,即crop和original兩種。

classify_path = “classify/"

#自動label好的VOC dataset,圖片及標記檔的目錄。

imgPath = “images/"  #voc images path

labelPath = “labels/"  #voc labels path

#dataset的圖片格式

imgType = “jpg"  # jpg, png

#輸入來源,可為video影片檔,或web camera。

inputType = “webcam"  # webcam, video

#輸入來源若為video,指定影片檔的path

media = “/home/chtseng/works/alpr/videos/4K/IMG_2241.MOV"

#是否將物件偵測過程錄製成影片?可掌握影片中那些物件被偵測並轉為dataset使用

write_video = True

#影片的路徑名稱

video_out = “labeled.avi"

#輸出的image是否要先旋轉?

output_rotate = False

#指定旋轉角度

rotate = 0

#設定手掌模型的參數,程式將用此模型來偵測及製作auto labeling。

yolo = opencvYOLO(modeltype="yolov3-tiny", \

objnames="models/1_palm_hand_gesture/obj.names", \

weights="models/1_palm_hand_gesture/yolov3-tiny_500000.weights",\

cfg="models/1_palm_hand_gesture/yolov3-tiny.cfg", score=score)

使用說明

使用上相當簡單,只用到兩個快捷鍵:

  1. 按下「l」錄(小寫的L),可切換class名稱,表示接下來的影像畫面,若有偵測到手掌,其class皆為指定的名稱。
  2. 按下「q」錄,將結束此auto labeling程式。

執行:

python3 auto_labeling_hand_gestures.py

操作示範

下面將示範如何透過本auto labeling程式製作一個手勢dataset。

下方為該dataset的classes及其對應名稱:

石頭 剪刀 讚上 讚左
10 11
讚下 讚右

Step 1.         執行auto_labeling_hand_gestures.py

Step 2.         按「l」鍵,輸入「0」,接著在鏡頭前方比出石頭的手勢。

視Frame rate速度、設定的frame interval以及是否有偵測到手掌而定,每分鐘所搜集到的image數量會有所差異。以我自己在Intel i5-3470 CPU透過Virtual Box執行為例,每分鐘可搜集到80張左右的圖片。

Step 3.         依次按「l」鍵,分別輸入各class的代碼(0~11),分別比出相對應的手勢。

Step 4.         可回頭輸入不同class的手勢,本程式會自動將圖片補在對應的class資料夾中。

Step 5.        錄製結束後,按「q」鍵結束。

我將整個Auto labeling的操作過程錄成影片如下,總共12種手勢,在六分鐘內便可錄製完成。

自動產生的Dataset

操作完成後,會在指定目錄下產生出下列三種dataset:

  1. VOC標記格式的dataset,總共1370張。

  1. 分類好的手勢圖片,共有12個資料夾,每個資料夾約100~200張圖片。

 

  1. 分類好的手勢圖片原圖,共有12個資料夾,每個資料夾約100~200張圖片。

 

  1. 本例所示範自動產生的dataset,其圖片數目還不夠,我們尚需不同的人物、不同的場景及環境,透過本程式來產生更多的圖片才行。
  1. Auto labeling並非萬能,後續還是需要人工的review及增修標記框,或者篩選錯誤的圖片,不過假如我們用於自動標記的模型訓練得相當優異,則後續的review時間可以減少。