diff --git "a/data/1.OpenCV\345\210\235\351\230\266/7.OpenCV\344\270\255\347\232\204\346\267\261\345\272\246\345\255\246\344\271\240/3.\344\272\272\350\204\270\346\243\200\346\265\213/detect_faces.md" "b/data/1.OpenCV\345\210\235\351\230\266/7.OpenCV\344\270\255\347\232\204\346\267\261\345\272\246\345\255\246\344\271\240/3.\344\272\272\350\204\270\346\243\200\346\265\213/detect_faces.md" new file mode 100644 index 0000000000000000000000000000000000000000..675ac285ef189dda542222f969ea8fa1541511af --- /dev/null +++ "b/data/1.OpenCV\345\210\235\351\230\266/7.OpenCV\344\270\255\347\232\204\346\267\261\345\272\246\345\255\246\344\271\240/3.\344\272\272\350\204\270\346\243\200\346\265\213/detect_faces.md" @@ -0,0 +1,140 @@ +# opencv实现人脸检测功能 + +早在 2017 年 8 月,OpenCV 3.3 正式发布,带来了高度改进的“深度神经网络”(dnn)模块。 该模块支持多种深度学习框架,包括 Caffe、TensorFlow 和 Torch/PyTorch。OpenCV 的官方版本中包含了一个更准确、基于深度学习的人脸检测器,链接:https://github.com/opencv/opencv/tree/4.x/samples/dnn/face_detector。我已经实现了模型加载和预测的代码,但是如何将结果取出来并绘制到图片上呢?如下图: + +![01](https://gitee.com/wanghao1090220084/cloud-image/raw/master/01.jpg) + +遍历代码的逻辑如下: + +- 遍历检测结果。 +- 然后,我们提取置信度并将其与置信度阈值进行比较。 我们执行此检查以过滤掉弱检测。 如果置信度满足最小阈值,我们继续绘制一个矩形以及检测概率。 +- 为此,我们首先计算边界框的 (x, y) 坐标。 然后我们构建包含检测概率的置信文本字符串。 如果我们的文本偏离图像(例如当面部检测发生在图像的最顶部时),我们将其向下移动 10 个像素。 我们的面部矩形和置信文本绘制在图像上。 +- 然后,我们再次循环执行该过程后的其他检测。 如果没有检测到,我们准备在屏幕上显示我们的输出图像)。 + + +框架代码如下: + +``` +import numpy as np +import cv2 + +low_confidence=0.5 +image_path='2.jpg' +proto_txt='deploy.proto.txt' +model_path='res10_300x300_ssd_iter_140000_fp16.caffemodel' +# 加载模型 +print("[INFO] loading model...") +net = cv2.dnn.readNetFromCaffe(proto_txt, model_path) +# 加载输入图像并为图像构建一个输入 blob +# 将大小调整为固定的 300x300 像素,然后对其进行标准化 +image = cv2.imread(image_path) +(h, w) = image.shape[:2] +blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, + (300, 300), (104.0, 177.0, 123.0)) +# 通过网络传递blob并获得检测和预测 +print("[INFO] computing object detections...") +net.setInput(blob) +detections = net.forward() +# 循环检测 +# TODO(You):请实现循环检测的代码。 + +# 展示图片并保存 +cv2.imshow("Output", image) +cv2.imwrite("01.jpg",image) +cv2.waitKey(0) +``` + +# 答案: + +``` +# 循环检测 +for i in range(0, detections.shape[2]): + # 提取与相关的置信度(即概率) + # 预测 + confidence = detections[0, 0, i, 2] + # 通过确保“置信度”来过滤掉弱检测 + # 大于最小置信度 + if confidence > low_confidence: + # 计算边界框的 (x, y) 坐标 + box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) + (startX, startY, endX, endY) = box.astype("int") + # 绘制人脸的边界框以及概率 + text = "{:.2f}%".format(confidence * 100) + y = startY - 10 if startY - 10 > 10 else startY + 10 + cv2.rectangle(image, (startX, startY), (endX, endY), + (0, 0, 255), 2) + cv2.putText(image, text, (startX, y), + cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2) +``` + +# 选项 + +## 宽和高颠倒 + +``` +# 循环检测 +for i in range(0, detections.shape[2]): + # 提取与相关的置信度(即概率) + # 预测 + confidence = detections[0, 0, i, 2] + # 通过确保“置信度”来过滤掉弱检测 + # 大于最小置信度 + if confidence > low_confidence: + # 计算边界框的 (x, y) 坐标 + box = detections[0, 0, i, 3:7] * np.array([h, w, h, w]) + (startX, startY, endX, endY) = box.astype("int") + # 绘制人脸的边界框以及概率 + text = "{:.2f}%".format(confidence * 100) + y = startY - 10 if startY - 10 > 10 else startY + 10 + cv2.rectangle(image, (startX, startY), (endX, endY), + (0, 0, 255), 2) + cv2.putText(image, text, (startX, y), + cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2) +``` + +## box框顺序错误 + +``` +# 循环检测 +for i in range(0, detections.shape[2]): + # 提取与相关的置信度(即概率) + # 预测 + confidence = detections[0, 0, i, 2] + # 通过确保“置信度”来过滤掉弱检测 + # 大于最小置信度 + if confidence > low_confidence: + # 计算边界框的 (x, y) 坐标 + box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) + (startX, endX, startY, endY) = box.astype("int") + # 绘制人脸的边界框以及概率 + text = "{:.2f}%".format(confidence * 100) + y = startY - 10 if startY - 10 > 10 else startY + 10 + cv2.rectangle(image, (startX, startY), (endX, endY), + (0, 0, 255), 2) + cv2.putText(image, text, (startX, y), + cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2) +``` + +## detections取值错误 + +``` +# 循环检测 +for i in range(0, detections.shape[2]): + # 提取与相关的置信度(即概率) + # 预测 + confidence = detections[0, i, 0, 2] + # 通过确保“置信度”来过滤掉弱检测 + # 大于最小置信度 + if confidence > low_confidence: + # 计算边界框的 (x, y) 坐标 + box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) + (startX, startY, endX, endY) = box.astype("int") + # 绘制人脸的边界框以及概率 + text = "{:.2f}%".format(confidence * 100) + y = startY - 10 if startY - 10 > 10 else startY + 10 + cv2.rectangle(image, (startX, startY), (endX, endY), + (0, 0, 255), 2) + cv2.putText(image, text, (startX, y), + cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2) +``` +