#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// 加载模型和配置文件
std::string model_path = "./model/res10_300x300_ssd_iter_140000_fp16.caffemodel";
std::string config_path = "./model/deploy.prototxt";
cv::dnn::Net net = cv::dnn::readNetFromCaffe(config_path, model_path);
// 打开摄像头
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
std::cerr << "Cannot open camera.\n";
return -1;
}
cv::Mat frame;
while (true)
{
// 读取摄像头捕捉的帧
cap.read(frame);
// 对帧进行预处理
cv::Mat input_blob = cv::dnn::blobFromImage(frame, 1.0, cv::Size(300, 300), cv::Scalar(104, 177, 123), false, false);
net.setInput(input_blob, "data");
// 进行人脸检测
cv::Mat detection = net.forward("detection_out");
// 解析检测结果
cv::Mat detection_mat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
for (int i = 0; i < detection_mat.rows; i++)
{
float confidence = detection_mat.at<float>(i, 2);
// 如果置信度大于0.5,表示检测到人脸
if (confidence > 0.5)
{
int x1 = static_cast<int>(detection_mat.at<float>(i, 3) * frame.cols);
int y1 = static_cast<int>(detection_mat.at<float>(i, 4) * frame.rows);
int x2 = static_cast<int>(detection_mat.at<float>(i, 5) * frame.cols);
int y2 = static_cast<int>(detection_mat.at<float>(i, 6) * frame.rows);
// 绘制人脸框
cv::rectangle(frame, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2);
// 进行口罩检测
cv::Mat face = frame(cv::Rect(x1, y1, x2 - x1, y2 - y1));
cv::Mat face_blob = cv::dnn::blobFromImage(face, 1.0, cv::Size(224, 224), cv::Scalar(0, 0, 0), true, false);
net.setInput(face_blob, "data");
cv::Mat mask_detection = net.forward("fc");
// 判断是否戴口罩
float mask_confidence = mask_detection.at<float>(0, 0);
float no_mask_confidence = mask_detection.at<float>(0, 1);
if (mask_confidence > no_mask_confidence)
{
cv::putText(frame, "Wearing Mask", cv::Point(x1, y1 - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2);
}
else
{
cv::putText(frame, "Not Wearing Mask", cv::Point(x1, y1 - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 2);
}
}
}
// 显示帧
cv::imshow("Frame", frame);
// 按下ESC键退出程序
if (cv::waitKey(1) == 27)
{
break;
}
}
return 0;
}