# 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)
```

