人工智能之口罩检测算法

您所在的位置:网站首页 图像识别口罩检测 人工智能之口罩检测算法

人工智能之口罩检测算法

2022-12-15 06:54| 来源: 网络整理| 查看: 265

由于疫情的影响,口罩检测已经成为各个程序员竞相开发的一种算法。 百度的人脸检测SDK使用的还不错,他们还把口罩检测也给开源了 我这里使用基于OPENCV的检测

一般的思路可能就是手机带有口罩和没有戴口罩的数据集进行训练,但是我暂时没有找到这些数据集,我就采用使用opencv原来带有的训练集先检测出人脸,然后再对人脸检测鼻子和嘴巴。但是由于opencv的检测鼻子和嘴巴的算法准确性不高,需要经过附加条件检测是不是真正的嘴巴和鼻子,如果在人脸中检测出了嘴巴和鼻子的话,那么没有戴口罩puttext no mask,否则就进行人脸识别

那么要进行人脸识别的话,需要采集本人的数据,然后在获取ORL的数据集一同训练。我这里获取了ORL提供的40个样本,每个样本里面有10个bmp格式的图像。 现在我们开始获取数据集,思路很简单,就是打开摄像头,对每一帧图像进行处理。对这每一帧图像识别出人脸,如果人脸的size为1,那么表示这就是你的人脸,然后把处理后的人脸保存起来。 为了拍摄多角度图像,需要每处理一次都需要等待,设置一个计数器,当经过十次的拍摄后,就退出程序

int makepicture() { CascadeClassifier cascada; cascada.load("E:/OPENCV/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml"); VideoCapture cap(0); Mat frame, myFace; int pic_num = 1; while (1) { cap >> frame; vector faces;//vector容器存检测到的faces Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//转灰度化,减少运算 cascada.detectMultiScale(frame_gray, faces, 1.1, 4, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(1000, 1000)); for (int i = 0; i Mat faceROI = frame_gray(faces[0]);//在灰度图中将圈出的脸所在区域裁剪出 //cout break; } //10us内输入esc则退出循环 imshow("frame", frame);//显示视频流 waitKey(100);//等待100us } return 0; }

然后需要对自己的样本进行处理

void initdata() { /* 对于训练样本: Ptr model = createLBPHFaceRecognizer(); model->train(img, labels);train函数的两个参数也很简单,训练的图像组vector和对应的标签组vector,这个label标签只需保证同一个人的标签相同即可,不需要保证图像的按标签顺序输入。 */ vector img; vector labels;//定义标签还有图片 for (int i = 1; i string path = "样本/s"+to_string(i)+"/" + to_string(j) + ".bmp"; Mat img_gray = imread(path); cvtColor(img_gray, img_gray, COLOR_BGR2GRAY); img.push_back(img_gray); labels.push_back(i); } } Ptr model = createFisherFaceRecognizer();//训练 model->train(img, labels); model->save("model.xml"); }

ok,处理完自己的样本之后,就可以直接打开摄像头,对每一帧识别出人脸,如果人脸有嘴巴或者鼻子的时候,就把他视作没有带口罩;如果没有的话,加载数据集,然后预测人脸,显示预测结果 核心代码如下

void fun(Mat& img, CascadeClassifier& face_cascade, CascadeClassifier& eyes_cascade, CascadeClassifier& nose_cascade, CascadeClassifier& mouse_cascade, Ptr model, Vector name) { vector faces;//脸的存储 vector noses; vector mouses; Mat frame;//需要使用灰度图 Mat predect; cvtColor(img, frame, COLOR_BGR2GRAY); face_cascade.detectMultiScale(frame, faces, 1.2, 7, 0, Size(80, 80));//分类器检测人脸 //输入照片,检测到的人脸序列,图像尺寸减小比例,检测5次,最小尺寸 最大尺寸 for (int i = 0; i if (predectnumber>70) putText(img, name[label-1], Point(faces[i].x, faces[i].y), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 4, 8); else putText(img, "I dont know", Point(faces[i].x, faces[i].y), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255),4,8); } } imshow("FacesOfPrettyGirl", img); }

测试的结果如下图 在这里插入图片描述

在这里插入图片描述

整个程序如下

#include #include #include #include "opencv2\opencv.hpp" #include #include #include using namespace std; using namespace cv; String face_cascade_name = "E:/OPENCV/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml"; String eyes_cascade_name = "E:\\OPENCV\\opencv\\sources\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml"; String mouse_cascade_name = "E:/OPENCV/opencv/sources/data/haarcascades/haarcascade_mcs_mouth.xml"; String nose_cascade_name = "E:/OPENCV/opencv/sources/data/haarcascades/haarcascade_mcs_nose.xml"; CascadeClassifier face_cascade; //定义人脸分类器 CascadeClassifier eyes_cascade; //定义人眼分类器 CascadeClassifier nose_cascade; //定义鼻子分类器 CascadeClassifier mouse_cascade; //定义嘴巴分类器 String window_name = "Capture - Face detection"; void fun(Mat& img, CascadeClassifier& face_cascade, CascadeClassifier& eyes_cascade, CascadeClassifier& nose_cascade, CascadeClassifier& mouse_cascade, Ptr model, Vector name); void initdata(); void initdataname(); int makepicture(); int main() { if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascade\n"); return -1; }; if (!nose_cascade.load(nose_cascade_name)) { printf("--(!)Error loading nose cascade\n"); return -1; }; if (!mouse_cascade.load(mouse_cascade_name)) { printf("--(!)Error loading mouse cascade\n"); return -1; }; //initdataname(); //initdata(); //makepicture(); Vectorname; ifstream infile("dataname.csv", ios::in); string line, field; for (int i = 0; i Mat frame; capture >> frame; fun(frame, face_cascade, eyes_cascade,nose_cascade,mouse_cascade ,model,name); waitKey(1); } system("pause"); return 0; } void fun(Mat& img, CascadeClassifier& face_cascade, CascadeClassifier& eyes_cascade, CascadeClassifier& nose_cascade, CascadeClassifier& mouse_cascade, Ptr model, Vector name) { vector faces;//脸的存储 vector noses; vector mouses; Mat frame;//需要使用灰度图 Mat predect; cvtColor(img, frame, COLOR_BGR2GRAY); face_cascade.detectMultiScale(frame, faces, 1.2, 7, 0, Size(80, 80));//分类器检测人脸 //输入照片,检测到的人脸序列,图像尺寸减小比例,检测5次,最小尺寸 最大尺寸 for (int i = 0; i if (predectnumber>70) putText(img, name[label-1], Point(faces[i].x, faces[i].y), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 4, 8); else putText(img, "I dont know", Point(faces[i].x, faces[i].y), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255),4,8); } } imshow("FacesOfPrettyGirl", img); } void initdata() { /* 对于训练样本: Ptr model = createLBPHFaceRecognizer(); model->train(img, labels);train函数的两个参数也很简单,训练的图像组vector和对应的标签组vector,这个label标签只需保证同一个人的标签相同即可,不需要保证图像的按标签顺序输入。 */ vector img; vector labels;//定义标签还有图片 for (int i = 1; i string path = "样本/s"+to_string(i)+"/" + to_string(j) + ".bmp"; Mat img_gray = imread(path); cvtColor(img_gray, img_gray, COLOR_BGR2GRAY); img.push_back(img_gray); labels.push_back(i); } } Ptr model = createFisherFaceRecognizer();//训练 model->train(img, labels); model->save("model.xml"); } void initdataname() { ofstream file1("dataname.csv", ios::out); for (int i = 1; i CascadeClassifier cascada; cascada.load("E:/OPENCV/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml"); VideoCapture cap(0); Mat frame, myFace; int pic_num = 1; while (1) { cap >> frame; vector faces;//vector容器存检测到的faces Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//转灰度化,减少运算 cascada.detectMultiScale(frame_gray, faces, 1.1, 4, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(1000, 1000)); for (int i = 0; i Mat faceROI = frame_gray(faces[0]);//在灰度图中将圈出的脸所在区域裁剪出 //cout break; } //10us内输入esc则退出循环 imshow("frame", frame);//显示视频流 waitKey(100);//等待100us } return 0; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3