OpenCV如何实现口罩识别
本篇內(nèi)容介紹了“OpenCV如何實(shí)現(xiàn)口罩識(shí)別”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
昨天在GitHub上看到了一個(gè)開(kāi)源的項(xiàng)目,是利用深度學(xué)習(xí)來(lái)檢測(cè)是否有佩戴口罩的,感覺(jué)還挺好玩的,于是就去下載了訓(xùn)練好的模型,打算用OpenCV的dnn模塊來(lái)跑一跑。然而,在經(jīng)過(guò)前向傳播后,得到的推理矩陣prob是一個(gè)1x5972x2 的Mat矩陣,和之前遇到過(guò)的推理結(jié)果都不太一樣,在經(jīng)過(guò)多種解碼方式的嘗試后,還是沒(méi)能夠?qū)@個(gè)推理結(jié)果正確得解碼。并且在網(wǎng)上搜索也沒(méi)有找到相關(guān)的內(nèi)容,幾乎沒(méi)有網(wǎng)友使用OpenCV來(lái)運(yùn)行這個(gè)模型,基本都是使用深度學(xué)習(xí)的框架來(lái)運(yùn)行。這就很無(wú)奈了,現(xiàn)在只能暫時(shí)把這個(gè)模型放一邊,等其他時(shí)候再來(lái)研究一下該怎么對(duì)它的推理結(jié)果進(jìn)行解碼。
然而,我還是想嘗試一下做有無(wú)佩戴口罩的檢測(cè),因?yàn)楸还雌鹆撕闷嫘墓缓笥忠驗(yàn)槭褂瞄_(kāi)源項(xiàng)目的預(yù)訓(xùn)練模型解碼失敗,一氣之下,我就想要不自己試一試搞一個(gè)。說(shuō)搞就搞,由于本人對(duì)深度學(xué)習(xí)的涉及面并不深入,所以我的思路是:使用OpenCV的dnn模塊來(lái)進(jìn)行人臉檢測(cè)及定位,然后將檢測(cè)出的人臉利用OpenCV的ml模塊進(jìn)行識(shí)別是否佩戴口罩。
那么要做的第一步,就是訓(xùn)練出我們需要的分類器,我選用OpenCV中ml模塊的SVM分類器來(lái)訓(xùn)練口罩識(shí)別分類器。訓(xùn)練部分的代碼如下:
stringpositive_path="D:\\opencv_c++\\opencv_tutorial\\data\\test\\positive\\";stringnegative_path="D:\\opencv_c++\\opencv_tutorial\\data\\test\\negative\\";vector<string>positive_images_str,negative_images_str;glob(positive_path,positive_images_str);glob(negative_path,negative_images_str);vector<Mat>positive_images,negative_images;for(inti=0;i<positive_images_str.size();i++){Matpositive_image=imread(positive_images_str[i]);positive_images.push_back(positive_image);}for(intj=0;j<negative_images_str.size();j++){Matnegative_image=imread(negative_images_str[j]);negative_images.push_back(negative_image);}stringsavePath="face_mask_detection.xml";trainSVM(positive_images,negative_images,savePath);
首先讀取所有的訓(xùn)練圖像,包含正樣本(戴口罩)圖像和負(fù)樣本(不戴口罩)圖像,然后分別將正負(fù)樣本集打包成vector<Mat>類型,傳入訓(xùn)練函數(shù)trainSVM()中,這個(gè)函數(shù)定義在頭文件 “face_mask.h” 中。
在訓(xùn)練過(guò)程中,我們不是把圖像完全展開(kāi)進(jìn)行訓(xùn)練,而是通過(guò)特征提取,得到每個(gè)樣本圖像的HOG特征,再計(jì)算每個(gè)HOG特征的特征描述子,通過(guò)特征描述子來(lái)訓(xùn)練SVM分類器。
要注意的是,我們并不是對(duì)完整的樣本圖像進(jìn)行HOG特征的提取與描述,而是對(duì)樣本圖像先進(jìn)行人臉區(qū)域的提取,將提取出來(lái)的人臉區(qū)域圖像再進(jìn)行HOG特征提取與描述并進(jìn)行訓(xùn)練。
同時(shí),還需要對(duì)正負(fù)樣本集進(jìn)行標(biāo)注,正樣本標(biāo)記為1,負(fù)樣本標(biāo)記為-1。
代碼如下:
for(inti=0;i<positive_num;i++){Matpositive_face;Rectpositive_faceBox;if(faceDetected(positive_images[i],positive_face,positive_faceBox)){resize(positive_face,positive_face,Size(64,128));Matgray;cvtColor(positive_face,gray,COLOR_BGR2GRAY);vector<float>descriptor;hog_train->compute(gray,descriptor);train_descriptors.push_back(descriptor);labels.push_back(1);}}for(intj=0;j<negative_num;j++){Matnegative_face;Rectnegative_faceBox;if(faceDetected(negative_images[j],negative_face,negative_faceBox)){resize(negative_face,negative_face,Size(64,128));Matgray;cvtColor(negative_face,gray,COLOR_BGR2GRAY);vector<float>descriptor;hog_train->compute(gray,descriptor);train_descriptors.push_back(descriptor);labels.push_back(-1);}}intwidth=train_descriptors[0].size();intheight=train_descriptors.size();Mattrain_data=Mat::zeros(Size(width,height),CV_32F);for(intr=0;r<height;r++){for(intc=0;c<width;c++){train_data.at<float>(r,c)=train_descriptors[r][c];}}autotrain_svm=ml::SVM::create();train_svm->trainAuto(train_data,ml::ROW_SAMPLE,labels);train_svm->save(path);hog_train->~HOGDescriptor();train_svm->clear();
其中進(jìn)行人臉提取的函數(shù)faceDetected()定義在頭文件 “face.h” 中。在這里我們使用opencv_face_detector_uint8.pb人臉檢測(cè)模型。
那么到這一步,就實(shí)現(xiàn)了檢測(cè)是否佩戴口罩的SVM分類器的訓(xùn)練工作,訓(xùn)練得到的模型文件如下:
接下來(lái),我們就要加載這個(gè)xml文件并且對(duì)輸入的圖像進(jìn)行檢測(cè)啦。其中,檢測(cè)用的的函數(shù)是FaceMaskDetect(),這個(gè)函數(shù)定義在 “face_mask.h” 頭文件中。
autodetecModel=ml::SVM::load("face_mask_detection.xml");Mattest_image=imread("D:/BaiduNetdiskDownload/人臉口罩檢測(cè)數(shù)據(jù)集/val/test_00004577.jpg");FaceMaskDetect(test_image,detecModel);imshow("test_image",test_image);
到這里,我們就實(shí)現(xiàn)了從訓(xùn)練,到運(yùn)行檢測(cè)的過(guò)程,下面來(lái)看一下運(yùn)行的效果怎樣:
先看下沒(méi)帶口罩的圖像,如果檢測(cè)到?jīng)]佩戴口罩,那么人臉就用紅色框框出,而且標(biāo)記紅色的 “ Not Face Mask ” 字樣:
如果是有佩戴口罩,那么就用綠色框框出人臉,并且標(biāo)記 “ Face Mask ” :
從效果上來(lái)看,所采用的測(cè)試圖像都不在訓(xùn)練集之內(nèi),對(duì)單個(gè)人臉的照片識(shí)別成功率還是可以的,但是肯定沒(méi)有開(kāi)源項(xiàng)目里神經(jīng)網(wǎng)絡(luò)模型的識(shí)別正確率高。而且我這里訓(xùn)練的時(shí)候,正負(fù)樣本比例大約是1:2,總樣本集是四百多張訓(xùn)練圖像,相比起開(kāi)源項(xiàng)目里八千多張圖像的訓(xùn)練集來(lái)說(shuō)簡(jiǎn)直是不值一提。
不過(guò)由于人臉檢測(cè)那一部分中,并沒(méi)有對(duì)同一幅圖像中出現(xiàn)多個(gè)人臉這種情況進(jìn)行處理,以至于當(dāng)一副圖像中出現(xiàn)多個(gè)人臉時(shí),只會(huì)對(duì)其中人臉置信度最高的那個(gè)人進(jìn)行佩戴口罩檢測(cè),所以這個(gè)部分還需要進(jìn)一步優(yōu)化。
當(dāng)然了,只對(duì)一張圖像進(jìn)行檢測(cè)就沒(méi)啥意思了,我們同樣可以聯(lián)合攝像頭來(lái)實(shí)現(xiàn)實(shí)時(shí)檢測(cè),演示代碼如下:
VideoCapture capture;capture.open(0);if (!capture.isOpened()){cout << "can't open camera" << endl;exit(-1);}Mat frame;while (capture.read(frame)){FaceMaskDetect(frame, detecModel);imshow("test_image", frame);char ch = waitKey(1);if (ch == 27){break;}}
總結(jié)
以上是生活随笔為你收集整理的OpenCV如何实现口罩识别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: win 2016 ssh_如何使用BPF
- 下一篇: iphone7防水_什么是IP68防尘防