引自:http://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 )
其中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)