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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

OpenCV如何实现口罩识别

發(fā)布時(shí)間:2023/12/19 综合教程 36 生活家
生活随笔 收集整理的這篇文章主要介紹了 OpenCV如何实现口罩识别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本篇內(nèi)容介紹了“OpenCV如何實(shí)現(xiàn)口罩識(shí)別”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

昨天在GitHub上看到了一個(gè)開源的項(xiàng)目,是利用深度學(xué)習(xí)來檢測(cè)是否有佩戴口罩的,感覺還挺好玩的,于是就去下載了訓(xùn)練好的模型,打算用OpenCV的dnn模塊來跑一跑。然而,在經(jīng)過前向傳播后,得到的推理矩陣prob是一個(gè)1x5972x2 的Mat矩陣,和之前遇到過的推理結(jié)果都不太一樣,在經(jīng)過多種解碼方式的嘗試后,還是沒能夠?qū)@個(gè)推理結(jié)果正確得解碼。并且在網(wǎng)上搜索也沒有找到相關(guān)的內(nèi)容,幾乎沒有網(wǎng)友使用OpenCV來運(yùn)行這個(gè)模型,基本都是使用深度學(xué)習(xí)的框架來運(yùn)行。這就很無奈了,現(xiàn)在只能暫時(shí)把這個(gè)模型放一邊,等其他時(shí)候再來研究一下該怎么對(duì)它的推理結(jié)果進(jìn)行解碼。

然而,我還是想嘗試一下做有無佩戴口罩的檢測(cè),因?yàn)楸还雌鹆撕闷嫘墓?,然后又因?yàn)槭褂瞄_源項(xiàng)目的預(yù)訓(xùn)練模型解碼失敗,一氣之下,我就想要不自己試一試搞一個(gè)。說搞就搞,由于本人對(duì)深度學(xué)習(xí)的涉及面并不深入,所以我的思路是:使用OpenCV的dnn模塊來進(jìn)行人臉檢測(cè)及定位,然后將檢測(cè)出的人臉利用OpenCV的ml模塊進(jìn)行識(shí)別是否佩戴口罩。

那么要做的第一步,就是訓(xùn)練出我們需要的分類器,我選用OpenCV中ml模塊的SVM分類器來訓(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)練過程中,我們不是把圖像完全展開進(jìn)行訓(xùn)練,而是通過特征提取,得到每個(gè)樣本圖像的HOG特征,再計(jì)算每個(gè)HOG特征的特征描述子,通過特征描述子來訓(xùn)練SVM分類器。

要注意的是,我們并不是對(duì)完整的樣本圖像進(jìn)行HOG特征的提取與描述,而是對(duì)樣本圖像先進(jìn)行人臉區(qū)域的提取,將提取出來的人臉區(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)練得到的模型文件如下:

接下來,我們就要加載這個(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è)的過程,下面來看一下運(yùn)行的效果怎樣:

先看下沒帶口罩的圖像,如果檢測(cè)到?jīng)]佩戴口罩,那么人臉就用紅色框框出,而且標(biāo)記紅色的 “ Not Face Mask ” 字樣:

如果是有佩戴口罩,那么就用綠色框框出人臉,并且標(biāo)記 “ Face Mask ” :

從效果上來看,所采用的測(cè)試圖像都不在訓(xùn)練集之內(nèi),對(duì)單個(gè)人臉的照片識(shí)別成功率還是可以的,但是肯定沒有開源項(xiàng)目里神經(jīng)網(wǎng)絡(luò)模型的識(shí)別正確率高。而且我這里訓(xùn)練的時(shí)候,正負(fù)樣本比例大約是1:2,總樣本集是四百多張訓(xùn)練圖像,相比起開源項(xiàng)目里八千多張圖像的訓(xùn)練集來說簡(jiǎn)直是不值一提。

不過由于人臉檢測(cè)那一部分中,并沒有對(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è)就沒啥意思了,我們同樣可以聯(lián)合攝像頭來實(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ǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。