Haar-Feature分类器和卷积神经网络
交流QQ:452026443?
以情感識別模型為例!?
我一直都看到它:“基于Haar特征的級聯分類器”,“Viola和Jones首先提出的類哈爾特征”......但究竟是什么類似Haar?它與卷積神經網絡有什么關系?
?
Haar-Feature就像CNN中的內核,除了在CNN中,內核的值由訓練確定,而Haar-Feature是手動確定的。
?
以下是一些Haar功能。前兩個是“邊緣特征”,用于檢測邊緣。第三個是“線特征”,而第四個是“四個矩形特征”,很可能用于檢測斜線。
?
?
圖1:常見的哈爾特征
?
在數字上,它們可能看起來像這樣:
?
圖2:哈爾特征以數字表示
?
每一個在圖像的3×3內核的動作和做矩陣乘法與圖像的每一個3x3的一部分,強調某些功能和平滑等。
?
Haar-Features擅長檢測邊緣和線條。這使得它在面部檢測中特別有效。例如,在Beyonce的一個小圖像中,這個Haar特征將能夠檢測到她的眼睛(頂部較暗且下面較亮的區域)。
?
圖3:哈爾特征可用于檢測面部標志,例如眼影
?
但是,由于必須手動確定哈爾特征,因此它可以檢測到的事物類型存在一定的限制。如果給分類器(網絡或任何檢測面的算法)邊和線要素,那么它只能檢測具有清晰邊和線的對象。即使作為面部檢測器,如果我們稍微操縱面部(比如用太陽鏡遮住眼睛,或者將頭部傾斜到一側),基于Haar的分類器可能無法識別面部。另一方面,卷積核具有更高的自由度(因為它是由訓練確定的),并且能夠識別部分覆蓋的面(取決于訓練數據的質量)。
?
從好的方面來說,因為我們不需要訓練Haar-Features,所以我們可以創建一個具有相對較小數據集的分類器。我們所要做的就是訓練每個特征的權重(即應該更多地使用哪個哈爾特征?),這樣我們就可以在沒有大量訓練圖像的情況下很好地訓練分類器。此外,它還具有更高的執行速度,因為基于Haar的分類器通常涉及較少的計算。
?
觸發對基于哈爾的分類器的這種小型調查的原因是這種識別情緒的模型。去年,在一次交易會上,我遇到了情感識別系統。但是,它沒有使用神經網絡。如果我能找到完全基于CNN的情緒識別算法,我很好奇。
模型:https://github.com/oarriaga/face_classification
?
簡要介紹一下這個模型,我看到它使用OpenCV的基于Haar的級聯分類器來檢測面部。在找到面孔之后,團隊然后訓練他們自己的CNN來識別臉上的情緒。
?
由于它使用基于哈爾的分類,我不能真正稱之為基于算法完全卷積神經網絡。如果我為MTCNN人臉識別系統更換了基于Haar的分類器怎么辦?
MTCNN:https://github.com/ipazc/mtcnn?
?
最初,它裝載了基于Haar的分類器。我把它換成MTCNN探測器:
?
#detection_model_path?=?'../trained_models/detection_models/haarcascade_frontalface_default.xml' #face_detection?=?load_detection_model(detection_model_path) emotion_model_path?=?'../trained_models/emotion_models/fer2013_mini_XCEPTION.102-0.66.hdf5' emotion_labels?=?get_labels('fer2013') detector?=?MTCNN()?
然后,我做了一點數據處理,因為他們的基于Haar的分類器輸出返回一個方形邊界框作為二維數組,而MTCNN模型輸出返回字典中的矩形邊界框。
?
bgr_image?=?video_capture.read()[1]gray_image?=?cv2.cvtColor(bgr_image,?cv2.COLOR_BGR2GRAY)rgb_image?=?cv2.cvtColor(bgr_image,?cv2.COLOR_BGR2RGB)#faces?=?detect_faces(face_detection,?gray_image)?<-?Their?original?Haar-based?classifier?coderesult?=?detector.detect_faces(bgr_image)if?result?!=?[]:boundingbox?=?result[0]['box']#Their?Haar-based?classifier?outputs?a?square?bounding?box,?while?the?MTCNN?detector?doesn't.#Therefore,?I'll?take?the?whatever's?smaller--the?width?or?height--and?shift?that?outwards?to?become?a?square#Because?that?might?create?a?not-quite-centered?bounding?box,?I?shifted?the?box?back?a?little?to?center?it?again.#Boundingbox[0]?and?[1]?are?the?coordinates?of?the?top?left?corner?of?the?bounding?box#Boundingbox[2]?and?[3]?are?the?width?and?height?of?the?bounding?boxif?boundingbox[2]<boundingbox[3]:?#x<ydiff=boundingbox[3]-boundingbox[2]boundingbox[2]=boundingbox[3]boundingbox[0]=int(boundingbox[0]-(diff/2))if?boundingbox[3]<boundingbox[2]:?#x>ydiff=boundingbox[3]-boundingbox[2]boundingbox[3]=boundingbox[2]boundingbox[1]=int(boundingbox[1]-(diff/2))boundingbox=[boundingbox]?#Their?original?Haar-based?classifier?output?has?an?extra?dimension? ??
當我改變輸出和調試時,我保持基于Haar的分類器和MTCNN檢測器運行(以比較它們的輸出)。有趣的是,似乎我的計算機無法承受如此大的計算量:程序一直在崩潰。
?
最后,我運行了程序,現在運行MTCNN而不是基于Haar的分類器。以下是一些觀察:
?
-
基于OpenCV Haar的分類器明顯更快。在將其切換到MTCNN檢測器后,視頻開始滯后。它仍然可以實時運行,但質量不是很好。
-
MTCNN檢測器能夠檢測到更多種類的面部。即使我傾斜我的臉,將其部分地遠離相機,或用手部分地遮住它,它仍然能夠將其識別為臉部。基于OpenCV Haar的分類器只能真正識別完整的前臉。
-
根據基于Haar的分類器訓練的情緒識別網絡只能準確識別完整的前向臉部上的不同情緒。因此,即使MTCNN檢測器允許我們在部分模糊的面部周圍繪制邊界框,程序也無法真正識別出臉部的情緒。
?
所有這些觀察都與我所發現的一致:雖然訓練有素的CNN可以學習更多參數(從而檢測更多種類的面部),基于Haar的分類器運行得更快。根據您的任務,一個人可能比另一個人更合適。
?
在這里下載您的資源:
?
-
MTCNN Github下載:https://github.com/ipazc/mtcnn
-
情感識別Github下載:https://github.com/oarriaga/face_classification
-
我的代碼(將其置于“src”下并記住將MTCNN中的“mtcnn”文件夾放在Emotion Recognition模型的“src”文件夾中,然后運行此代碼)代碼如下:
?
from?statistics?import?modeimport?cv2 import?tensorflow?as?tf #from?tensorflow.keras.models?import?load_model import?numpy?as?npfrom?utils.datasets?import?get_labels from?utils.inference?import?detect_faces from?utils.inference?import?draw_text from?utils.inference?import?draw_bounding_box from?utils.inference?import?apply_offsets #from?utils.inference?import?load_detection_model from?utils.preprocessor?import?preprocess_input from?mtcnn.mtcnn?import?MTCNN#?parameters?for?loading?data?and?images #detection_model_path?=?'../trained_models/detection_models/haarcascade_frontalface_default.xml' emotion_model_path?=?'../trained_models/emotion_models/fer2013_mini_XCEPTION.102-0.66.hdf5' emotion_labels?=?get_labels('fer2013') detector?=?MTCNN()#?hyper-parameters?for?bounding?boxes?shape frame_window?=?10 emotion_offsets?=?(20,?40)#?loading?models #face_detection?=?load_detection_model(detection_model_path) model?=?tf.keras.models.Sequential([tf.keras.layers.Flatten(),tf.keras.layers.Dense(512,?activation=tf.nn.relu),tf.keras.layers.Dropout(0.2),tf.keras.layers.Dense(10,?activation=tf.nn.softmax) ]) emotion_classifier?=?tf.keras.models.load_model(emotion_model_path,?compile=False)#?getting?input?model?shapes?for?inference emotion_target_size?=?emotion_classifier.input_shape[1:3]#?starting?lists?for?calculating?modes emotion_window?=?[]#?starting?video?streaming cv2.namedWindow('window_frame') video_capture?=?cv2.VideoCapture(0) while?True:bgr_image?=?video_capture.read()[1]gray_image?=?cv2.cvtColor(bgr_image,?cv2.COLOR_BGR2GRAY)rgb_image?=?cv2.cvtColor(bgr_image,?cv2.COLOR_BGR2RGB)#faces?=?detect_faces(face_detection,?gray_image)result?=?detector.detect_faces(bgr_image)if?result?!=?[]:boundingbox?=?result[0]['box']if?boundingbox[2]<boundingbox[3]:?#x<ydiff=boundingbox[3]-boundingbox[2]boundingbox[2]=boundingbox[3]boundingbox[0]=int(boundingbox[0]-(diff/2))if?boundingbox[3]<boundingbox[2]:?#x<ydiff=boundingbox[3]-boundingbox[2]boundingbox[3]=boundingbox[2]boundingbox[1]=int(boundingbox[1]-(diff/2))boundingbox=[boundingbox]#print("faces:?",faces,"\nbounding?box:?",boundingbox)for?face_coordinates?in?boundingbox:x1,?x2,?y1,?y2?=?apply_offsets(face_coordinates,?emotion_offsets)gray_face?=?gray_image[y1:y2,?x1:x2]try:gray_face?=?cv2.resize(gray_face,?(emotion_target_size))except:continuegray_face?=?preprocess_input(gray_face,?True)gray_face?=?np.expand_dims(gray_face,?0)gray_face?=?np.expand_dims(gray_face,?-1)emotion_prediction?=?emotion_classifier.predict(gray_face)emotion_probability?=?np.max(emotion_prediction)emotion_label_arg?=?np.argmax(emotion_prediction)emotion_text?=?emotion_labels[emotion_label_arg]emotion_window.append(emotion_text)if?len(emotion_window)?>?frame_window:emotion_window.pop(0)try:emotion_mode?=?mode(emotion_window)except:continueif?emotion_text?==?'angry':color?=?emotion_probability?*?np.asarray((255,?0,?0))elif?emotion_text?==?'sad':color?=?emotion_probability?*?np.asarray((0,?0,?255))elif?emotion_text?==?'happy':color?=?emotion_probability?*?np.asarray((255,?255,?0))elif?emotion_text?==?'surprise':color?=?emotion_probability?*?np.asarray((0,?255,?255))else:color?=?emotion_probability?*?np.asarray((0,?255,?0))color?=?color.astype(int)color?=?color.tolist()draw_bounding_box(face_coordinates,?rgb_image,?color)draw_text(face_coordinates,?rgb_image,?emotion_mode,color,?0,?-45,?1,?1)bgr_image?=?cv2.cvtColor(rgb_image,?cv2.COLOR_RGB2BGR)cv2.imshow('window_frame',?bgr_image)if?cv2.waitKey(1)?&?0xFF?==?ord('q'):break?
?
?
總結
以上是生活随笔為你收集整理的Haar-Feature分类器和卷积神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于函数strtok和strtok_r的
- 下一篇: 开关灯效果HTML,js实现开关灯效果