最近閑來無事,想寫一個本人畢設(shè)基于深度學(xué)習(xí)的人臉識別文章。我主要利用兩個不同的神經(jīng)網(wǎng)絡(luò)進(jìn)行實(shí)現(xiàn),分別是一個簡單三層的卷積神經(jīng)網(wǎng)絡(luò)和結(jié)構(gòu)復(fù)雜的VGG16神經(jīng)網(wǎng)絡(luò),并比對了兩種網(wǎng)絡(luò)訓(xùn)練出的模型的識別效果。從最終的結(jié)果來看,與預(yù)想的一樣結(jié)構(gòu)更復(fù)雜的VGG16的效果更勝一籌。下面我就來具體介紹一下其實(shí)現(xiàn)過程。
(鑒于很多小伙伴私聊我對這個項(xiàng)目感興趣,我將代碼鏈接附在評論區(qū)了,有需要的小伙伴請自取,覺得有用的話記得點(diǎn)贊哦,栓Q~~~)
接下來我將從以下的順序來進(jìn)行講解:
環(huán)境配置
人臉檢測部分
訓(xùn)練模型部分
人臉識別部分
?
1. 環(huán)境配置
對了還有就是在安裝這些庫的時候,如果是使用pip install的方法,建議就都使用這個方法,不然使用不同方法安裝到時就會報(bào)錯(一條來自踩坑者的忠告哈哈),配置大概是這些了,可能有的沒寫出來,可能就需要大家踩一些坑配置了(此處是不是要啪啪打臉了?。?/span>
2. 人臉檢測
此部分主要采用的是opencv來調(diào)用攝像頭并進(jìn)行圖像處理,然后使用基于級聯(lián)分類器+haar特征的方法進(jìn)行人臉檢測。opencv使用起來非常方便,這里使用到的函數(shù)很少,也就普通的讀取圖片,灰度轉(zhuǎn)換,顯示圖像,簡單的編輯圖像罷了。
1)讀取圖片
只需要給出待操作的圖片的路徑即可。
import cv2
image = cv2.imread(imagepath)
2)灰度轉(zhuǎn)換
灰度轉(zhuǎn)換的作用就是:轉(zhuǎn)換成灰度的圖片的計(jì)算強(qiáng)度得以降低。因?yàn)楝F(xiàn)在的彩色圖片都是三通道的數(shù)據(jù),不做任何處理,數(shù)據(jù)量會很大,對于我們學(xué)生用的機(jī)子來說hold不住。
import cv2
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
灰色圖片大概就是這樣的。
3)畫圖
opencv 的強(qiáng)大之處的一個體現(xiàn)就是其可以對圖片進(jìn)行任意編輯,處理。
下面的這個函數(shù)最后一個參數(shù)指定的就是畫筆的大小。其實(shí)就是要把檢測到的人臉邊框給描出來。
import cv2
cv2.rectangle(image,(x,y),(x+w,y+w),(0,255,0),2)
4)顯示圖像
編輯完的圖像要么直接的被顯示出來,要么就保存到物理的存儲介質(zhì)。
import cv2
cv2.imshow("Image Title",image)
5)獲取人臉識別訓(xùn)練數(shù)據(jù)
看似復(fù)雜,其實(shí)就是對于人臉特征的一些描述,這樣opencv在讀取完數(shù)據(jù)后很據(jù)訓(xùn)練中的樣品數(shù)據(jù),就可以感知讀取到的圖片上的特征,進(jìn)而對圖片進(jìn)行人臉識別。
import cv2
face_cascade = cv2.CascadeClassifier(r'./haarcascade_frontalface_default.xml')
里面的xml文件非常關(guān)鍵,可以說是這個模型的核心了,就是靠它才能獲取到人臉數(shù)據(jù)的。它是opencv在GitHub上共享出來的具有普適的訓(xùn)練好的數(shù)據(jù)。我們可以直接的拿來使用。
6)探測人臉
說白了,就是根據(jù)訓(xùn)練的數(shù)據(jù)來對新圖片進(jìn)行識別的過程。
import cv2
# 探測圖片中的人臉
?
faces = face_cascade.detectMultiScale(
? ?gray,
? ?scaleFactor = 1.15,
? ?minNeighbors = 5,
? ?minSize = (5,5),
? ?flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
我們可以隨意的指定里面參數(shù)的值,來達(dá)到不同精度下的識別。返回值就是opencv對圖片的探測結(jié)果的體現(xiàn)。
處理人臉探測的結(jié)果
結(jié)束了剛才的人臉探測,我們就可以拿到返回值來做進(jìn)一步的處理了。但這也不是說會多么的復(fù)雜,無非添加點(diǎn)特征值罷了。
import cv2
?
print "發(fā)現(xiàn){0}個人臉!".format(len(faces))
for(x,y,w,h) in faces:
? ?cv2.rectangle(image,(x,y),(x+w,y+w),(0,255,0),2)
以上就介紹完了一些必備函數(shù),包括人臉檢測的函數(shù)。那我們就是要來講這個模型了,講模型其實(shí)很好講,首先獲取訓(xùn)練數(shù)據(jù),然后寫好模型訓(xùn)練,最后檢測效果即可。按照這個順序來,我們先講講如何來收集人臉數(shù)據(jù)。
我們只要收集兩個人的圖片即可,考慮到大家的筆記本電腦配置,每個人只要收集幾百張圖片即可。文件名記為get_face.py,代碼如下:
def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name):
? ? cv2.namedWindow(window_name)
? ? # 視頻來源,可以來自一段已存好的視頻,也可以直接來自USB攝像頭
? ? cap = cv2.VideoCapture(camera_idx)
?
? ? # 告訴OpenCV使用人臉識別分類器
? ? data_path = "haarcascade_frontalface_default.xml"
? ? classfier = cv2.CascadeClassifier(data_path)
?
? ? # 識別出人臉后要畫的邊框的顏色,RGB格式
? ? color = (0, 255, 0)
?
? ? num = 0
? ? while cap.isOpened():
? ? ? ? ok, frame = cap.read() ?# 讀取一幀數(shù)據(jù)
? ? ? ? if not ok:
? ? ? ? ? ? break
?
? ? ? ? grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) ?# 將當(dāng)前楨圖像轉(zhuǎn)換成灰度圖像
? ? ? ? # 人臉檢測,1.2和2分別為圖片縮放比例和需要檢測的有效點(diǎn)數(shù)
? ? ? ? faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
? ? ? ? if len(faceRects) > 0: ?# 大于0則檢測到人臉
? ? ? ? ? ? for faceRect in faceRects: ?# 單獨(dú)框出每一張人臉
? ? ? ? ? ? ? ? x, y, w, h = faceRect
?
? ? ? ? ? ? ? ? # 將當(dāng)前幀保存為圖片
? ? ? ? ? ? ? ? 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 += 1
? ? ? ? ? ? ? ? if num > catch_pic_num: ?# 如果超過指定最大保存數(shù)量退出循環(huán)
? ? ? ? ? ? ? ? ? ? break
?
? ? ? ? ? ? ? ? # 畫出矩形框
? ? ? ? ? ? ? ? cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
?
? ? ? ? ? ? ? ? # 顯示當(dāng)前捕捉到了多少人臉圖片
? ? ? ? ? ? ? ? font = cv2.FONT_HERSHEY_SIMPLEX
? ? ? ? ? ? ? ? cv2.putText(frame ,'num:%d' % (num) ,(x + 30, y + 30), font, 1, (255 ,0 ,255) ,4)
?
? ? ? ? ? ? ? ? # 超過指定最大保存數(shù)量結(jié)束程序
? ? ? ? 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()
?
3. 訓(xùn)練模型
數(shù)據(jù)拿到了,接下來就是要寫模型訓(xùn)練了,我分別用了兩個模型。下面的模型是采用了3個卷積操作+1個全連接操作實(shí)現(xiàn)的,如果是VGG16的話只需換以下部分即可,其它部分代碼一樣。
模型代碼如下:
def build_model(self, dataset, nb_classes=2):
? ? ? ? # 構(gòu)建一個空的網(wǎng)絡(luò)模型,它是一個線性堆疊模型,各神經(jīng)網(wǎng)絡(luò)層會被順序添加,專業(yè)名稱為序貫?zāi)P突蚓€性堆疊模型
? ? ? ? self.model = Sequential()
?
? ? ? ? # 以下代碼將順序添加CNN網(wǎng)絡(luò)需要的各層,一個add就是一個網(wǎng)絡(luò)層
? ? ? ? self.model.add(Convolution2D(32, 3, 3, border_mode='same',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?input_shape=dataset.input_shape)) ?# 1 2維卷積層
? ? ? ? self.model.add(Activation('relu')) ?# 2 激活函數(shù)層
?
? ? ? ? self.model.add(MaxPooling2D(pool_size=(2, 2))) ?# 5 池化層
? ? ? ? self.model.add(Dropout(0.25)) ?# 6 Dropout層
?
? ? ? ? self.model.add(Convolution2D(64, 3, 3, border_mode='same')) ?# 7 ?2維卷積層
? ? ? ? self.model.add(Activation('relu')) ?# 8 ?激活函數(shù)層
?
? ? ? ? self.model.add(MaxPooling2D(pool_size=(2, 2))) ?# 11 池化層
? ? ? ? self.model.add(Dropout(0.25)) ?# 12 Dropout層
?
? ? ? ? self.model.add(Flatten()) ?# 13 Flatten層
? ? ? ? self.model.add(Dense(512)) ?# 14 Dense層,又被稱作全連接層
? ? ? ? self.model.add(Activation('relu')) ?# 15 激活函數(shù)層
? ? ? ? self.model.add(Dropout(0.5)) ?# 16 Dropout層
? ? ? ? self.model.add(Dense(nb_classes)) ?# 17 Dense層
? ? ? ? self.model.add(Activation('softmax')) ?# 18 分類層,輸出最終結(jié)果
?
? ? ? ? # 輸出模型概況
? ? ? ? self.model.summary()
因?yàn)槭怯胟eras寫的,所以看起來比較簡潔。
訓(xùn)練模型的函數(shù)也很簡潔
sgd = SGD(lr=0.01, decay=1e-6,
? ? ? ? ? ? ? ? ? momentum=0.9, nesterov=True) ?# 采用SGD+momentum的優(yōu)化器進(jìn)行訓(xùn)練,首先生成一個優(yōu)化器對象
? ? ? ? self.model.compile(loss='categorical_crossentropy',
? ? ? ? ? ? ? ? ? ? ? ? ? ?optimizer=sgd,
? ? ? ? ? ? ? ? ? ? ? ? ? ?metrics=['accuracy']) ?# 完成實(shí)際的模型配置工作
這兒再說一點(diǎn),我們知道如果要判別兩個人是誰,訓(xùn)練的時候肯定是要給兩個人的照片分類的,比如A標(biāo)記為0,B標(biāo)記為1。此模型也是如此來訓(xùn)練的,在load_face.py中的load_dataset()函數(shù)里有一行代碼就是如此,代碼如下:
# 標(biāo)注數(shù)據(jù),'LDY'文件夾下都是我的臉部圖像,全部指定為0,另外一個文件夾下是同學(xué)的,全部指定為1
labels = np.array([0 if label.endswith('LDY') else 1 for label in labels])
此文件的該處地方也是需要大家修改的,即把“LDY”改為自己文件夾的名稱。
如果你要做多人識別的話,也是在這處地方做手腳的,我這兒就標(biāo)記了0和1,所以大家很自然的知道我是做兩人識別的,如果你要多識別一些人,就多做一些標(biāo)記就行了。
最后還有一處地方需要修改,就是train.py文件的主函數(shù)部分:
# 此處文件地址是你收集的圖片的文件夾地址
? ? dataset = Dataset('D:\PyCharm-Community\Workplace\Face_Recognition\\face_data')
? ? dataset.load()
? ? model = Model()
? ? model.build_model(dataset)
? ? model.train(dataset)
# 此處地址是你保存訓(xùn)練好模型的地址
? ? model.save_model(file_path='D:\PyCharm-Community\Workplace\Face_Recognition\\face_data\model\ldy_face_model.h5')
? ? model.evaluate(dataset)
?
4. 人臉識別
模型訓(xùn)練好了,最后就可以拿照片來測試了。
文件名叫:Face_recognition.py,代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-806406.html
if __name__ == '__main__':
? ? if len(sys.argv) != 1:
? ? ? ? print("Usage:%s camera_id\r\n" % (sys.argv[0]))
? ? ? ? sys.exit(0)
?
? ? # 加載模型
? ? model = Model()
? ? model.load_model(file_path='D:\PyCharm-Community\Workplace\Face_Recognition\model\jianxin_face_model.h5')
?
? ? # 框住人臉的矩形邊框顏色
? ? color = (0, 255, 0)
?
? ? # 捕獲指定攝像頭的實(shí)時視頻流
? ? cap = cv2.VideoCapture(0)
?
? ? # 人臉識別分類器本地存儲路徑
? ? cascade_path = "D:\opencv\\build\etc\haarcascades\haarcascade_frontalface_default.xml"
?
? ? # 循環(huán)檢測識別人臉
? ? while True:
? ? ? ? ret, frame = cap.read() ?# 讀取一幀視頻
?
? ? ? ? if ret is True:
?
? ? ? ? ? ? # 圖像灰化,降低計(jì)算復(fù)雜度
? ? ? ? ? ? frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
? ? ? ? else:
? ? ? ? ? ? continue
? ? ? ? # 使用人臉識別分類器,讀入分類器
? ? ? ? cascade = cv2.CascadeClassifier(cascade_path)
?
? ? ? ? # 利用分類器識別出哪個區(qū)域?yàn)槿四?? ? ? ? faceRects = cascade.detectMultiScale(frame_gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
? ? ? ? if len(faceRects) > 0:
? ? ? ? ? ? for faceRect in faceRects:
? ? ? ? ? ? ? ? x, y, w, h = faceRect
?
? ? ? ? ? ? ? ? # 截取臉部圖像提交給模型識別這是誰
? ? ? ? ? ? ? ? image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
? ? ? ? ? ? ? ? faceID = model.face_predict(image)
? ? ? ? ? ? ? ? print("faceID", faceID)
? ? ? ? ? ? ? ? # 如果是“我”
? ? ? ? ? ? ? ? if faceID == 0:
? ? ? ? ? ? ? ? ? ? cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
? ? ? ? ? ? ? ? ? ? # 文字提示是誰
? ? ? ? ? ? ? ? ? ? cv2.putText(frame, 'Chengjianxin',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (x + 30, y + 30), ?# 坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cv2.FONT_HERSHEY_SIMPLEX, ?# 字體
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1, ?# 字號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (255, 0, 255), ?# 顏色
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2) ?# 字的線寬
? ? ? ? ? ? ? ? else:
? ? ? ? ? ? ? ? ? ? cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
? ? ? ? ? ? ? ? ? ? cv2.putText(frame, 'Nobody',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (x + 30, y + 30), ?# 坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cv2.FONT_HERSHEY_SIMPLEX, ?# 字體
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2, ?# 字號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (255, 0, 0), ?# 顏色
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2) ?# 字的線寬
? ? ? ? ? ? ? ? ? ? pass
?
? ? ? ? cv2.imshow("Face Recognition", frame)
?
? ? ? ? # 等待10毫秒看是否有按鍵輸入
? ? ? ? k = cv2.waitKey(10)
? ? ? ? # 如果輸入q則退出循環(huán)
? ? ? ? if k & 0xFF == ord('q'):
? ? ? ? ? ? break
?
? ? # 釋放攝像頭并銷毀所有窗口
? ? cap.release()
? ? cv2.destroyAllWindows()
其中有3處地方需要修改
# 加載模型
model = Model()
model.load_model(file_path='D:\PyCharm-Community\Workplace\Face_Recognition\model\jianxin_face_model.h5')
模型地址改成你自己的。
# 人臉識別分類器本地存儲路徑
cascade_path = "D:\opencv\\build\etc\haarcascades\haarcascade_frontalface_default.xml"
這個xml文件地址也改成你自己的,前面的get_face.py也是這樣。
# 如果是“我”
if faceID == 0:
? ?cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
? ?# 文字提示是誰
? ?cv2.putText(frame, 'Chengjianxin',
? ? ? ? ? ? ? ? ? ? ?(x + 30, y + 30), ?# 坐標(biāo)
? ? ? ? ? ? ? ? ? ? ?cv2.FONT_HERSHEY_SIMPLEX, ?# 字體
? ? ? ? ? ? ? ? ? ? ?1, ?# 字號
? ? ? ? ? ? ? ? ? ? ?(255, 0, 255), ?# 顏色
? ? ? ? ? ? ? ? ? ? ?2) ?# 字的線寬
else:
? ?cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness=2)
? ?cv2.putText(frame, 'Nobody',
? ? ? ? ? ? ? ? ? ? (x + 30, y + 30), ?# 坐標(biāo)
? ? ? ? ? ? ? ? ? ? cv2.FONT_HERSHEY_SIMPLEX, ?# 字體
? ? ? ? ? ? ? ? ? ? 2, ?# 字號
? ? ? ? ? ? ? ? ? ? (255, 0, 0), ?# 顏色
? ? ? ? ? ? ? ? ? ? 2) ?# 字的線寬
這里面的文字提示改成你自己的就行了。文章來源地址http://www.zghlxwxcb.cn/news/detail-806406.html
到了這里,關(guān)于畢設(shè)--基于深度學(xué)習(xí)的人臉識別(詳細(xì)步驟+代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!