生活随笔
收集整理的這篇文章主要介紹了
深度学习之基于opencv和CNN实现人脸识别
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這個項目在之前人工智能課設上做過,但是當時是劃水用的別人的。最近自己實現了一下,基本功能可以實現,但是效果并不是很好。容易出現錯誤識別,或者更改了背景之后識別效果變差的現象。個人以為是數據選取的問題,希望路過的大佬批評指正。
所需要的庫
tensorflow
-gpu
2.0.0
Keras
2.3.1
opencv
-python
4.5.1.48
numpy
1.20.2
1.數據集獲取
這個數據集是通過自己電腦的攝像頭獲取的,也可以通過一段視頻獲取。這一過程是建立自己的人臉庫。通過Opencv中的CascadeClassifier人臉識別分類器來實現。
部分代碼:
def CatchPICFromVideo(window_name
, camera_idx
, catch_pic_num
, path_name
):cv2
.namedWindow
(window_name
)cap
= cv2
.VideoCapture
(camera_idx
,cv2
.CAP_DSHOW
)classfier
= cv2
.CascadeClassifier
('E:\ProgramData\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_alt.xml')color
= (0, 255, 0)num
= 0while cap
.isOpened
():ok
, frame
= cap
.read
() if not ok
:breakgrey
= cv2
.cvtColor
(frame
, cv2
.COLOR_BGR2GRAY
) faceRects
= classfier
.detectMultiScale
(grey
, scaleFactor
=1.2, minNeighbors
=3, minSize
=(32, 32))if len(faceRects
) > 0: for faceRect
in faceRects
: x
, y
, w
, h
= faceRectimg_name
= '%s/%d.jpg' % (path_name
, num
)image
= frame
[y
- 10: y
+ h
+ 10, x
- 10: x
+ w
+ 10]cv2
.imwrite
(img_name
, image
)num
+= 1if num
> (catch_pic_num
): breakcv2
.rectangle
(frame
, (x
- 10, y
- 10), (x
+ w
+ 10, y
+ h
+ 10), color
, 2)font
= cv2
.FONT_HERSHEY_SIMPLEXcv2
.putText
(frame
, 'num:%d' % (num
), (x
+ 30, y
+ 30), font
, 1, (255, 0, 255), 4)if num
> (catch_pic_num
): breakcv2
.imshow
(window_name
, frame
)c
= cv2
.waitKey
(10)if c
& 0xFF == ord('q'):breakcap
.release
()cv2
.destroyAllWindows
()
效果如下所示:
本人的人臉庫中一共有三個數據集:
2.數據集處理
數據集處理包括捕捉人臉+數據集灰度化,將源文件路徑中的數據經過處理之后保存到目標文件中。
部分代碼:
try:resultArray
= readALLImg
(sourcePath
,*suffix
)count
= 1face_cascade
= cv2
.CascadeClassifier
('E:\ProgramData\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_alt.xml')for i
in resultArray
:if type(i
) != str:gray
= cv2
.cvtColor
(i
,cv2
.COLOR_BGR2GRAY
)faces
= face_cascade
.detectMultiScale
(gray
,1.3,5)for (x
,y
,w
,h
) in faces
:listStr
= [str(int(time
.time
())),str(count
)] fileName
= ''.join
(listStr
)f
= cv2
.resize
(gray
[y
:(y
+h
),x
:(x
+w
)],(200,200))cv2
.imwrite
(objectPath
+os
.sep
+'%s.jpg'%fileName
,f
)count
+=1except IOError
:print('error')else:print('Already read ' + str(count
-1) +' Faces to Destination '+objectPath
)
經過處理之后的效果如下所示:
注:并不是所有的圖片都會轉化為灰度圖片,因為捕捉器在識別的時候有可能出錯,個別的圖片無法識別。我的數據集采用了1500張圖片。
3.劃分訓練集和測試集
訓練集和測試集采用8:2的比例,所有的圖片經過歸一化處理,大小為128*128的灰度圖片,隨機打亂。
部分代碼:
X_train
,X_test
,y_train
,y_test
= train_test_split
(imgs
,labels
,test_size
=0.2,random_state
=random
.randint
(0, 100))X_train
= X_train
.reshape
(X_train
.shape
[0],1,self
.img_size
,self
.img_size
)/255.0X_test
= X_test
.reshape
(X_test
.shape
[0],1,self
.img_size
,self
.img_size
)/255.0y_train
= np_utils
.to_categorical
(y_train
, num_classes
=counter
)y_test
= np_utils
.to_categorical
(y_test
, num_classes
=counter
)
4.模型搭建
CNN模型為三層卷積池化層+兩層全連接層,抹平之后進行分類。中間加入Dropout層,防止過擬合。
部分代碼:
def build_model(self
):self
.model
= keras
.Sequential
([keras
.layers
.Conv2D
(filters
=32,kernel_size
=(5,5),padding
="same",activation
="relu",input_shape
=self
.dataset
.X_train
.shape
[1:]),keras
.layers
.MaxPooling2D
(pool_size
=(2, 2), strides
=(2, 2), padding
='same'),keras
.layers
.Conv2D
(filters
=64,kernel_size
=(5,5),padding
="same",activation
="relu"),keras
.layers
.MaxPooling2D
(pool_size
=(2, 2), strides
=(2, 2), padding
='same'),keras
.layers
.Conv2D
(filters
=128,kernel_size
=(5,5),padding
="same",activation
="relu"),keras
.layers
.MaxPooling2D
(pool_size
=(2, 2), strides
=(2, 2), padding
='same'),keras
.layers
.Dropout
(0.5),keras
.layers
.Flatten
(),keras
.layers
.Dense
(512,activation
="relu"),keras
.layers
.Dense
(self
.dataset
.num_classes
,activation
="softmax")])
模型訓練+測試
其中epochs和batch_size可以自己選擇。
def train_model(self
):self
.model
.compile(optimizer
= 'adam',loss
= 'categorical_crossentropy',metrics
=['accuracy'])self
.model
.fit
(self
.dataset
.X_train
,self
.dataset
.Y_train
,epochs
=50,batch_size
=90)def evaluate_model(self
):print('Testing---------------')loss
, accuracy
= self
.model
.evaluate
(self
.dataset
.X_test
, self
.dataset
.Y_test
)print('test loss:',loss
)print('test accuracy:',accuracy
)
訓練結果如下所示:
(這準確率高的我自己都害怕
Epoch
50/5090/2705 [..............................] - ETA
: 1s
- loss
: 9.0821e-04 - accuracy
: 1.0000270/2705 [=>............................] - ETA
: 1s
- loss
: 5.1787e-04 - accuracy
: 1.0000450/2705 [===>..........................] - ETA
: 0s
- loss
: 0.0022 - accuracy
: 0.9978 630/2705 [=====>........................] - ETA
: 0s
- loss
: 0.0022 - accuracy
: 0.9984810/2705 [=======>......................] - ETA
: 0s
- loss
: 0.0023 - accuracy
: 0.9988990/2705 [=========>....................] - ETA
: 0s
- loss
: 0.0057 - accuracy
: 0.9980
1170/2705 [===========>..................] - ETA
: 0s
- loss
: 0.0055 - accuracy
: 0.9983
1350/2705 [=============>................] - ETA
: 0s
- loss
: 0.0049 - accuracy
: 0.9985
1530/2705 [===============>..............] - ETA
: 0s
- loss
: 0.0044 - accuracy
: 0.9987
1710/2705 [=================>............] - ETA
: 0s
- loss
: 0.0039 - accuracy
: 0.9988
1890/2705 [===================>..........] - ETA
: 0s
- loss
: 0.0036 - accuracy
: 0.9989
2070/2705 [=====================>........] - ETA
: 0s
- loss
: 0.0033 - accuracy
: 0.9990
2250/2705 [=======================>......] - ETA
: 0s
- loss
: 0.0031 - accuracy
: 0.9991
2430/2705 [=========================>....] - ETA
: 0s
- loss
: 0.0029 - accuracy
: 0.9992
2610/2705 [===========================>..] - ETA
: 0s
- loss
: 0.0027 - accuracy
: 0.9992
2705/2705 [==============================] - 1s 443us
/step
- loss
: 0.0026 - accuracy
: 0.9993
測試集結果:
(攤手)
Testing
---------------32/677 [>.............................] - ETA
: 4s
192/677 [=======>......................] - ETA
: 0s
352/677 [==============>...............] - ETA
: 0s
512/677 [=====================>........] - ETA
: 0s
672/677 [============================>.] - ETA
: 0s
677/677 [==============================] - 0s 668us
/step
test loss
: 0.00010534183920105803
test accuracy
: 1.0
5.模型測試
對經過訓練之后的模型進行測試,重新拍攝幾張照片進行測試。
def test_onBatch(path
):model
= Model
()model
.load
()index
= 0img_list
, label_lsit
, counter
= read_file
(path
)for img
in img_list
:picType
,prob
= model
.predict
(img
)if picType
!= -1:index
+= 1name_list
= read_name_list
('E:\\faceRecognition')print(name_list
[picType
],prob
)else:print(" Don't know this person")return index
結果如下所示:
Model Loaded
.
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
yqx_tst
1.0
6.調用攝像頭識別
部分代碼:
def build_camera(self
):face_cascade
= cv2
.CascadeClassifier
('E:\ProgramData\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_alt.xml')name_list
= read_name_list
("E:\\faceRecognition")cameraCapture
= cv2
.VideoCapture
(0,cv2
.CAP_DSHOW
)success
,frame
= cameraCapture
.read
()while success
and cv2
.waitKey
(1) == -1:success
,frame
= cameraCapture
.read
()gray
= cv2
.cvtColor
(frame
,cv2
.COLOR_BGR2GRAY
)faces
= face_cascade
.detectMultiScale
(gray
,1.3,5)for (x
,y
,w
,h
) in faces
:ROI
= gray
[x
:x
+w
,y
:y
+h
]ROI
= cv2
.resize
(ROI
,(self
.img_size
,self
.img_size
),interpolation
=cv2
.INTER_LINEAR
)label
,prob
= self
.model
.predict
(ROI
)if prob
> 0.9:show_name
= name_list
[label
]else:show_name
= 'Stranger'cv2
.putText
(frame
,show_name
,(x
,y
-20),cv2
.FONT_HERSHEY_SIMPLEX
,1,255,2)frame
= cv2
.rectangle
(frame
,(x
,y
),(x
+w
,y
+h
),(255,0,0),2)cv2
.imshow
("Camera",frame
)c
= cv2
.waitKey
(10)if c
& 0xFF == ord('q'):breakcameraCapture
.release
()cv2
.destroyAllWindows
()
效果如下:
完整代碼請私信我。有不對的地方希望路過的大佬批評指正。
總結
以上是生活随笔為你收集整理的深度学习之基于opencv和CNN实现人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。