從CK+庫提取標記點信息


1.CK+動態表情庫介紹

The Extended Cohn-Kanade Dataset(CK+)

下載地址

這個數據庫是在 Cohn-Kanade Dataset 的基礎上擴展來的,發布於2010年。這個數據庫比起JAFFE 要大的多。而且也可以免費獲取,包含表情的label和Action Units 的label。

這個數據庫包括123個subjects, 593 個 image sequence,每個image sequence的最后一張 Frame 都有action units 的label,而在這593個image sequence中,有327個sequence 有 emotion的 label。這個數據庫是人臉表情識別中比較流行的一個數據庫,很多文章都會用到這個數據做測試。

 

In this Phase there are 4 zipped up files. They relate to: 
下載數據庫后有以下四個文件

1) The Images (cohn-kanade-images.zip) - there are 593 sequences across 123 subjects which are FACS coded at the peak frame. All sequences are from the neutral face to the peak expression.

2) The Landmarks (Landmarks.zip) - All sequences are AAM tracked with 68points landmarks for each image.

3) The FACS coded files (FACS_labels.zip) - for each sequence (593) there is only 1 FACS file, which is the last frame (the peak frame). Each line of the file corresponds to a specific AU and then the intensity. An example is given below.

4) The Emotion coded files (Emotion_labels.zip) - ONLY 327 of the 593 sequences have emotion sequences. This is because these are the only ones the fit the prototypic definition. Like the FACS files, there is only 1 Emotion file for each sequence which is the last frame (the peak frame). There should be only one entry and the number will range from 0-7 (i.e. 0=neutral, 1=anger, 2=contempt, 3=disgust, 4=fear, 5=happy, 6=sadness, 7=surprise). N.B there is only 327 files- IF THERE IS NO FILE IT MEANS THAT THERE IS NO EMOTION LABEL (sorry to be explicit but this will avoid confusion).

 

The Images (cohn-kanade-images.zip)圖片庫中包含了從平靜到表情表現峰值的圖片,實際使用中建議使用比較明顯的圖片,並進行相應的預處理。

Emotion_labels.zip標簽壓縮包中 
0-中性 
1-憤怒 
2-蔑視 
3-厭惡 
4-恐懼 
5-高興 
6-悲傷 
7-驚訝 

 

2.特征點分析

因為我們自己建立的表情庫是用RealSense攝像頭采集的,我們想驗證我們的識別方法在在CK+庫上的識別效果,所以需要做的是對CK庫進行特征點提取。

在提取之前我們先要分析CK庫中特征點的ID,這樣方便我們找到RealSense中對應的點。

選擇CK庫中的一張圖片,讀數據,將標記點在圖片中畫出來。

 1 def drawLandmarkPoint(img,color):
 2     draw = ImageDraw.Draw(img)
 3     myfont = ImageFont.truetype("C:\\WINDOWS\\Fonts\\SIMYOU.TTF", 10)
 4 
 5     file_txt = open("S035_003_00000001_landmarks.txt", "a+")
 6     lines = file_txt.readlines()
 7     t=1             #特征點標號
 8     for line in lines:
 9         line_object=line.split(" ")
10         x=float(line_object[3])         #原始數據是科學記數法,這里轉換成浮點型
11         y=float(line_object[-1])
12         print x,y
13         #draw.ellipse((0, 0, 200, 200), fill="red", outline="red")
14         draw.text((x,y), bytes(t), font=myfont, fill=color)
15         t+=1
16     file_txt.close()

 CK庫中的標記點共有68個。

 

3.特征點轉換CK_to_RealSense

可以看出特征點的順序和RealSense是不一樣的。相比RealSense的78個標記點,CK+中只有68個,且CK庫中有幾個點RealSense中沒有,所以,我們最后存下來的點在66個。

轉化之后主要缺失的點是眉毛下眉的2x3=6個點,左右眼睛2x2=4個點。

多出的2個點是鼻子2側,CK有5個,RealSense只有3個。所以最后保存了66個點。

在程序里面建立元祖,標注轉化的對應關系。

依次是,左眉,右眉,左眼,右眼,鼻子,外嘴唇,內嘴唇,臉輪廓

 1 #將ck點轉換成realsense的點 r:ck 共66個點。
 2 CK_to_RealSense={0:22,1:21,2:20,3:19,4:18,
 3                  5:23,6:24,7:25,8:26,9:27,
 4                  10:10,11:39,12:38,14:37,16:42,17:41,
 5                  18:43,19:44,20:45,22:46,24:47,25:48,
 6                  26:28,27:29,28:30,29:31,30:32,31:34,32:36,
 7                  33:49,34:50,35:51,36:52,37:53,38:54,39:55,40:56,41:57,42:58,43:59,44:60,
 8                  45:61,46:62,47:63,48:64,49:65,50:66,51:67,52:68,
 9                  53:1,54:2,55:3,56:4,57:5,58:6,59:7,60:8,61:9,62:10,63:11,64:12,65:13,66:14,67:15,68:16,69:17
10                  }
11 RealSenseID=[0,1,2,3,4,
12              5,6,7,8,9,
13              10,11,12,14,16,17,
14              18,19,20,22,24,25,
15              26,27,28,29,30,31,32,
16              33,34,35,36,37,38,39,40,41,42,43,44,
17              45,46,47,48,49,50,51,52,
18              53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69
19              ]

 

4.進行處理

CK+庫中的動態表情是通過動態序列來展示的,所以一個表情會有多張圖片,需要的是將一個表情的多張圖片進行處理,提取特征點信息,然后存到一個txt中,表現出動態的變化。

所以open操作的模式要寫成

fCK_image = open(CKDataDir, "a"),可以多次寫入,這樣對同一個目錄下多個圖片的數據寫入一個文件。
 1 def readFile(filepath):
 2     f1 = open(filepath, "r")
 3     nowDir = os.path.split(filepath)[0]             #獲取路徑中的父文件夾路徑
 4     fileName = os.path.split(filepath)[1]           #獲取路徑中文件名
 5     #對新生成的文件進行命名的過程
 6     CKDataDir = os.path.join(nowDir, "CKData.txt")
 7 
 8     fCK_image = open(CKDataDir, "a")
 9     fCK_image.write(os.path.splitext(fileName)[0]+"\t")
10 
11     lines = f1.readlines()
12     for n in range(0,66):
13     #for n in range(1, lines_count+1):
14         line = lines[CK_to_RealSense[RealSenseID[n]]-1]
15         line_object = line.split(' ')
16 
17         id=RealSenseID[n]
18         if n==63:
19             time=4
20         image_x = float(line_object[3])
21         image_y = float(line_object[-1])
22         pointData = bytes(id) + "\t" + bytes(image_x) + "\t" + bytes(image_y) +"\t"
23         fCK_image.write(pointData)
24         print pointData
25 
26     fCK_image.write("\n")
27     f1.close()
28     fCK_image.close()
29     
30     global picturecount
31     picturecount+=1

 

5.遞歸批量處理數據

對CK庫中,標記點的文件夾進行遞歸操作。

需要注意的是,打開文件操作的時候,需要在路徑前面加上字符r。

eachFile(r"E:\RealSense\CK+\Landmarks_track")

因為在過程中存在這樣的路徑,里面有\0,程序會認為是這個字符串結束了,然后運行不下去。

E:\RealSense\CK+\Landmarks\S010\001\S010_001_00000001_landmarks.txt
 1 def eachFile(filepath):
 2     global emotioncount
 3 
 4     pathDir = os.listdir(filepath)      #獲取當前路徑下的文件名,返回List
 5     for s in pathDir:
 6         newDir=os.path.join(filepath,s)     #將文件命加入到當前文件路徑后面
 7         if os.path.isfile(newDir) :         #如果是文件
 8             if os.path.splitext(newDir)[1]==".txt":  #判斷是否是txt
 9                 readFile(newDir)                     #讀文件
10                 pass
11         else:
12             eachFile(newDir)                #如果不是文件,遞歸這個文件夾的路徑
13             emotioncount += 1

 

最后的將處理的圖片數量和表情個數打印輸出。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM