文章轉自:https://blog.csdn.net/sinat_26917383/article/details/72885715
人臉識別熱門,表情識別更加。但是表情識別很難,因爲人臉的微表情很多,本節介紹一種比較粗線條的表情分類與識別的辦法。
Keras系列:
1、keras系列︱Sequential與Model模型、keras基本結構功能(一)
2、keras系列︱Application中五款已訓練模型、VGG16框架(Sequential式、Model式)解讀(二)
3、keras系列︱圖像多分類訓練與利用bottleneck features進行微調(三)
4、keras系列︱人臉表情分類與識別:opencv人臉檢測+Keras情緒分類(四)
5、keras系列︱遷移學習:利用InceptionV3進行fine-tuning及預測、完整案例(五)
本次講述的表情分類是識別的分析流程分爲:
- 1、加載pre-model網絡與權重;
- 2、利用opencv的函數進行簡單的人臉檢測;
- 3、摳出人臉的圖並灰化;
- 4、表情分類器檢測
.
一、表情數據集
主要來源於kaggle比賽,下載地址。
有七種表情類別: (0=Angry, 1=Disgust, 2=Fear, 3=Happy, 4=Sad, 5=Surprise, 6=Neutral).
數據是48x48 灰度圖,格式比較奇葩。
第一列是情緒分類,第二列是圖像的numpy,第三列是train or test。
.
二、opencv的人臉識別
參考《opencv+Recorder︱OpenCV 中使用 Haar 分類器進行面部檢測》
理論略過,直接來看重點:
(1)加載人臉檢測器,haarcascade_frontalface_default.xml;
(2)圖片加載並灰化,cvtColor,可參考: opencv︱圖像的色彩空間cvtColor(HSV、HSL、HSB 、BGR)
(2)人臉探測,detectMultiScale.
# (1)加載人臉檢測器
cascPath = '/.../haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(cascPath)
# (2)圖片加載並灰化
jpg_file = '/home/ubuntu/keras/image/8c80abb4gw1f3b5hxd3aaj20jg0cx411.jpg'
img_gray = cv2.imread(jpg_file)
img_gray = cv2.cvtColor(img_gray, cv2.COLOR_BGR2GRAY)
# 人臉探測
faces = faceCascade.detectMultiScale(
img_gray,
scaleFactor=1.1,
minNeighbors=1,# minNeighbors=5比較難檢測
minSize=(30, 30),
flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
其中minNeighbors設置小一些,容易檢測出來。這個檢測器還是有點粗糙。
.
三、表情分類與識別
本節源自github的mememoji。
網絡結構:
opencv中的人臉檢測的pre-model文件(haarcascade_frontalface_default.xml)和表情識別pre-model文件(model.h5)都在作者的github下載。
是利用Keras實現的。直接來看完整的代碼:
import cv2
import sys
import json
import time
import numpy as np
from keras.models import model_from_json
emotion_labels = ['angry', 'fear', 'happy', 'sad', 'surprise', 'neutral']
# load json and create model arch
json_file = open('/.../model.json','r')
loaded_model_json = json_file.read()
json_file.close()
model = model_from_json(loaded_model_json)
# load weights into new model
model.load_weights('/.../model.h5')
def predict_emotion(face_image_gray): # a single cropped face
resized_img = cv2.resize(face_image_gray, (48,48), interpolation = cv2.INTER_AREA)
# cv2.imwrite(str(index)+'.png', resized_img)
image = resized_img.reshape(1, 1, 48, 48)
list_of_list = model.predict(image, batch_size=1, verbose=1)
angry, fear, happy, sad, surprise, neutral = [prob for lst in list_of_list for prob in lst]
return [angry, fear, happy, sad, surprise, neutral]
# -------------------直接預測-----------------------
img_gray = cv2.imread('/.../real-time_emotion_analyzer-master/meme_faces/angry-angry.png')
img_gray = cv2.cvtColor(img_gray, cv2.COLOR_BGR2GRAY)
angry, fear, happy, sad, surprise, neutral = predict_emotion(img_gray)
# -------------------人臉預測-----------------------
# 加載檢測器
cascPath = '/.../real-time_emotion_analyzer-master/haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(cascPath)
# 圖像灰化
jpg_file = '/.../001.jpg'
img_gray = cv2.imread(jpg_file)
img_gray = cv2.cvtColor(img_gray, cv2.COLOR_BGR2GRAY)
# 人臉檢測
faces = faceCascade.detectMultiScale(
img_gray,
scaleFactor=1.1,
minNeighbors=1,# minNeighbors=5比較難檢測
minSize=(30, 30),
flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)
# 表情畫框
for (x, y, w, h) in faces:
face_image_gray = img_gray[y:y+h, x:x+w]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
angry, fear, happy, sad, surprise, neutral = predict_emotion(face_image_gray)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58