日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

深度学习之基于opencv和CNN实现人脸识别

發布時間:2023/12/15 pytorch 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习之基于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)# 視頻來源,可以來自一段已存好的視頻,也可以直接來自USB攝像頭cap = cv2.VideoCapture(camera_idx,cv2.CAP_DSHOW)# 告訴OpenCV使用人臉識別分類器classfier = cv2.CascadeClassifier('E:\ProgramData\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_alt.xml')# 識別出人臉后要畫的邊框的顏色,RGB格式color = (0, 255, 0)num = 0while cap.isOpened():ok, frame = cap.read() # 讀取一幀數據if not ok:breakgrey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 將當前楨圖像轉換成灰度圖像# 人臉檢測,1.2和2分別為圖片縮放比例和需要檢測的有效點數faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))if len(faceRects) > 0: # 大于0則檢測到人臉for faceRect in faceRects: # 單獨框出每一張人臉x, y, w, h = faceRect# 將當前幀保存為圖片img_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): # 如果超過指定最大保存數量退出循環break# 畫出矩形框cv2.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): break# 顯示圖像cv2.imshow(window_name, frame)c = cv2.waitKey(10)if c & 0xFF == ord('q'):break# 釋放攝像頭并銷毀所有窗口cap.release()cv2.destroyAllWindows()

效果如下所示:

本人的人臉庫中一共有三個數據集:

2.數據集處理

數據集處理包括捕捉人臉+數據集灰度化,將源文件路徑中的數據經過處理之后保存到目標文件中。
部分代碼:

try:#讀取照片,第一個元素是文件名resultArray = readALLImg(sourcePath,*suffix)#對list中的圖片逐一進行檢查,找出其中的人臉然后寫到目標文件夾中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.0# 將labels轉成 binary class matricesy_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可以自己選擇。

# 進行模型訓練的函數,具體的optimizer、loss可以進行不同選擇def train_model(self):self.model.compile(optimizer = 'adam',loss = 'categorical_crossentropy',metrics=['accuracy'])# epochs、batch_size為可調的參數,epochs為訓練多少輪、batch_size為每次訓練多少個樣本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):# opencv文件中人臉級聯文件的位置,用于幫助識別圖像或者視頻流中的人臉face_cascade = cv2.CascadeClassifier('E:\ProgramData\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_alt.xml')#讀取dataset數據集下的子文件夾名稱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)#利用模型對cv2識別出來的人臉進行對比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'):break# 釋放攝像頭并銷毀所有窗口cameraCapture.release()cv2.destroyAllWindows()

效果如下:



完整代碼請私信我。有不對的地方希望路過的大佬批評指正。

總結

以上是生活随笔為你收集整理的深度学习之基于opencv和CNN实现人脸识别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。