使用TensorFlow和OpenCV實(shí)現(xiàn)口罩檢測
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
在這段艱難的疫情期間,我們決定建立一個(gè)非常簡單和基本的卷積神經(jīng)網(wǎng)絡(luò)(CNN)模型,使用TensorFlow與Keras庫和OpenCV來檢測人們是否佩戴口罩。

圖片來源于澳門圖片社
為了建立這個(gè)模型,我們將使用由Prajna Bhandary 提供的口罩?jǐn)?shù)據(jù)集。這個(gè)數(shù)據(jù)集包括大約1,376幅圖像,其中690幅圖像包含戴口罩的人,686幅圖像包含沒有戴口罩的人。
我們將使用這些圖像懸鏈一個(gè)基于TensorFlow框架的CNN模型,之后通過電腦端的網(wǎng)絡(luò)攝像頭來檢測人們是否戴著口罩。此外,我們也可以使用手機(jī)相機(jī)做同樣的事情。
首先,我們需要標(biāo)記數(shù)據(jù)集中兩個(gè)類別的全部圖像。我們可以看到這里有690張圖像在‘yes’類里,也就是戴口罩的一類;有686張圖像在‘no’類中,也就是沒有帶口罩的一類。
The number of images with facemask labelled 'yes': 690The number of images with facemask labelled 'no': 686
這里,我們需要增強(qiáng)我們的數(shù)據(jù)集,為訓(xùn)練提供更多數(shù)量的圖像。在數(shù)據(jù)增強(qiáng)時(shí),我們旋轉(zhuǎn)并翻轉(zhuǎn)數(shù)據(jù)集中的每幅圖像。在數(shù)據(jù)增強(qiáng)后,我們總共有2751幅圖像,其中‘yes’類中有1380幅圖像,‘no’類中有1371幅圖像。
Number of examples: 2751Percentage of positive examples: 50.163576881134134%, number of pos examples: 1380Percentage of negative examples: 49.836423118865866%, number of neg examples: 1371
我們將我們的數(shù)據(jù)分割成訓(xùn)練集和測試集,訓(xùn)練集中包含將要被CNN模型訓(xùn)練的圖像,測試集中包含將要被我們模型測試的圖像。
在此,我們?nèi)?/span>split_size=0.8,這意味著80%的圖像將進(jìn)入訓(xùn)練集,其余20%的圖像將進(jìn)入測試集。
The number of images with facemask in the training set labelled 'yes': 1104The number of images with facemask in the test set labelled 'yes': 276The number of images without facemask in the training set labelled 'no': 1096The number of images without facemask in the test set labelled 'no': 275
在分割后,我們看到圖像已經(jīng)按照分割的百分比分配給訓(xùn)練集和測試集。
在這一步中,我們將使用Conv2D,MaxPooling2D,Flatten,Dropout和Dense等各種層構(gòu)建順序CNN模型。在最后一個(gè)Dense層中,我們使用‘softmax’函數(shù)輸出一個(gè)向量,給出兩個(gè)類中每個(gè)類的概率。
model = tf.keras.models.Sequential([tf.keras.layers.Conv2D(100, (3,3), activation='relu', input_shape=(150, 150, 3)),tf.keras.layers.MaxPooling2D(2,2),tf.keras.layers.Conv2D(100, (3,3), activation='relu'),tf.keras.layers.MaxPooling2D(2,2),tf.keras.layers.Flatten(),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(50, activation='relu'),tf.keras.layers.Dense(2, activation='softmax')])model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
在這里,我們使用 ‘adam’ 優(yōu)化器和‘binary_crossentropy’ 作為我們的損失函數(shù),因?yàn)橹挥袃蓚€(gè)類。此外,也甚至可以使用MobileNetV2以獲得更高的精度。
在構(gòu)建我們的模型之后,我們創(chuàng)建“train_generator”和“validation_generator”,以便在下一步將它們與我們的模型相匹配。 我們看到訓(xùn)練集中總共有2200張圖像,測試集中有551張圖像。
Found 2200 images belonging to 2 classes.Found 551 images belonging to 2 classes.
這一步是主要的步驟,我們使用訓(xùn)練集中的圖像來訓(xùn)練我們的模型,并使用測試集中的數(shù)據(jù)來測試我們的訓(xùn)練結(jié)果,給出準(zhǔn)確率。我們進(jìn)行了30次迭代,我們訓(xùn)練的輸出結(jié)果在下面給出。同時(shí),我們可以訓(xùn)練更多的迭代,以獲得更高的精度,以免發(fā)生過擬合。
history = model.fit_generator(train_generator,epochs=30,validation_data=validation_generator,callbacks=[checkpoint])>>Epoch 30/30[==============================] - 231s 1s/step - loss: 0.0368 - acc: 0.9886 - val_loss: 0.1072 - val_acc: 0.9619
我們看到,在第30個(gè)時(shí)期之后,我們的模型中訓(xùn)練集的精度為98.86%,測試集的精度為96.19%。 這意味著它是訓(xùn)練結(jié)果很好,沒有任何過度擬合。
在建立模型后,我們?yōu)槲覀兊慕Y(jié)果標(biāo)記了兩個(gè)概率
[‘0’?作為‘without_mask’?和‘1’作為‘with_mask’]。我們還使用RGB值設(shè)置邊界矩形顏色。 [‘RED’?代表?‘without_mask’?和‘GREEN’?代表?‘with_mask]
labels_dict={0:'without_mask',1:'with_mask'}color_dict={0:(0,0,255),1:(0,255,0)}
在此之后,我們打算使用PC的網(wǎng)絡(luò)攝像頭來檢測我們是否佩戴口罩。為此,首先我們需要實(shí)現(xiàn)人臉檢測。在此,我們使用基于Haar特征的級(jí)聯(lián)分類器來檢測人臉的特征。
face_clsfr=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')這種級(jí)聯(lián)分類器是由OpenCV設(shè)計(jì)的,通過訓(xùn)練數(shù)千幅圖像來檢測正面的人臉。代碼中需要的.xml文件可以在公眾號(hào)后臺(tái)回復(fù)“口罩檢測”獲得。
在最后一步中,我們通過OpenCV庫運(yùn)行一個(gè)無限循環(huán)程序,使用我們的網(wǎng)絡(luò)攝像頭,在其中我們使用Cascade Classifier檢測人臉。代碼是webcam = cv2.VideoCapture(0)表示使用網(wǎng)絡(luò)攝像頭。
該模型將預(yù)測兩類中每一類的可能性([without_mask, with_mask])?;诟怕?/span>的大小,標(biāo)簽將被選擇并顯示在我們臉的區(qū)域。
此外,還可以下載用于手機(jī)和PC的DroidCam 應(yīng)用程序來使用我們的移動(dòng)相機(jī),并將代碼中的0改為1 webcam= cv2.VideoCapture(1).
測試:
我們來看一下測試的結(jié)果

從上面的演示視頻中,我們看到模型能夠正確地檢測是否佩戴面具并在標(biāo)簽上顯示相同的內(nèi)容。
如果小伙伴需要本文的相關(guān)代碼和文件,可以在公眾號(hào)后臺(tái)回復(fù)【口罩檢測】獲得。
交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會(huì)逐漸細(xì)分),請掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會(huì)請出群,謝謝理解~

