[Day 1 of 17]使用opencv和DL的人脸检测

https://pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/?utm_source=Drip&utm_medium=Email&utm_campaign=CVandDLCrashCourse&utm_content=email1
Face detection with OpenCV and deep learning

opencv可以使用库附带的经过预训练的深度学习人脸检测器模型,执行快速、准确的人脸检测

goal:

  1. 这个模型在OpenCV库中的位置
  2. 何使用OpenCV and deep learning在图像中执行人脸检测
  3. 如何使用OpenCV and deep learning在视频中执行面部检测

1

The Caffe-based face detector can be found in the face_detector sub-directory of the dnn samples
基于Caffe的人脸检测器可以在dnn样本的face_detector子目录中找到。当将OpenCV的深度神经网络模块与Caffe模型一起使用时,您需要两组文件:

  • The .prototxt file(s) which define the model architecture (i.e., the layers themselves)定义模型体系结构(即层本身)的.prototxt文件
  • The .caffemodel file which contains the weights for the actual layers包含实际层的权重

使用使用Caffe训练的模型进行深度学习时,这两个文件都是必需的

How does the OpenCV deep learning face detector work?

基于单镜头检测器(SSD)框架,具有ResNet基础网络。

#import the necessary packages
import numpy as np
import argparse
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
	help="path to input image")
ap.add_argument("-p", "--prototxt", required=True,
	help="path to Caffe 'deploy' prototxt file")
# caffe prototxt文件路径
ap.add_argument("-m", "--model", required=True,
	help="path to Caffe pre-trained model")
# 过预训练的Caffe模型的路径
ap.add_argument("-c", "--confidence", type=float, default=0.5,
	help="minimum probability to filter weak detections")
# 可选参数,默认0.5
args = vars(ap.parse_args())

cv2.dnn是 OpenCV 中的深度学习模块。readNetFromCaffe()用于从 Caffe 框架中读取神经网络模型,接收两个参数:一个表示神经网络架构的配置文件(定义了神经网络的层次结构、层参数和连接关系);一个包含经过训练权重的模型文件(包含了训练过的神经网络模型的权重参数)。

根据caffe prototxt和caffe model的路径加载并建立模型net–>加载图像,提取尺寸–>create a blob。(dnn.blobFromImage负责预处理,包括设置blob尺寸和标准化)如下:

# load our serialized model from disk
print("[INFO] loading model...")
net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"]) #加载模型并存储为net
# net对象可以用于进行图像分类、对象检测等深度学习任务
# load the input image and construct an input blob for the image
# by resizing to a fixed 300x300 pixels and then normalizing it
image = cv2.imread(args["image"])   # 加载图像
(h, w) = image.shape[:2]            # 提取尺寸,取 shape 的前两个元素,即图像的高度和宽度
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,
	(300, 300), (104.0, 177.0, 123.0))  # create a blob,生成输入神经网络的图像块
	#将输入的image调整制定尺寸300,300
# dnn.blobFromImage负责预处理,生成blob作为神经网络的输入,包括设置blob尺寸和标准化,接收调整后的image;1.0是缩放因子,1表示不缩放;300,300是期望尺寸,因为神经网络输入层需要固定尺寸;(104.0, 177.0, 123.0) 是一个可选的均值减法操作,从图像的每个通道中减去对应的均值值,帮助预处理。
#blob 对象现在为:经过调整大小、缩放和预处理的图像数据

apply face detection:

# pass the blob through the network and obtain the detections and
# predictions
print("[INFO] computing object detections...")
net.setInput(blob)#输入blob到神经网络模型,对输入blob进行推断,并获取输出结果
detections = net.forward()#对神经网络进行前向推断,得到推断结果,可能包含物体检测的边界框、分类结果、置信度等信息

为了检测人脸,我们将blob应用net模型。将开启循环检测,并在检测到的人脸周围绘制方框:



# loop over the detections
for i in range(0, detections.shape[2]):#循环次数:检测对象的数量
# detections 是神经网络的输出结果,通常是一个包含多个检测对象的数组或矩阵。
# shape 是一个属性,用于获取数组或矩阵的维度信息。
# detections.shape[2] 表示获取 detections 的第三个维度的大小,也就是检测对象的数量
# 在循环体内部,可以通过 detections[:,:,i] 来访问和处理每个具体的检测对象的相关信息
	# extract the confidence (i.e., probability) associated with the
	# prediction
	confidence = detections[0, 0, i, 2] #提取置信度
	# filter out weak detections by ensuring the `confidence` is
	# greater than the minimum confidence
	if confidence > args["confidence"]: #比较,为了过滤出弱检测,当满足最小阈值时执行:
		# compute the (x, y)-coordinates of the bounding box for the
		# object
		box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
		# detections[0, 0, i, 3:7] 是用于访问第 i 个检测对象的边界框信息。
		# 0, 0 表示第一个维度和第二个维度的索引,i 表示第三个维度的索引,
		# 3:7 表示从第四个元素到第七个元素的切片,对应边界框的坐标信息。
		# np.array([w, h, w, h]) 创建了一个包含图像宽度 w 和高度 h 的数组,
		# 重复两次以对应边界框的坐标顺序为 (x, y, width, height)
		# 该语句:对边界框的坐标进行了缩放操作,以匹配原始图像的尺寸。
		# 得到的 box 对象包含了经过缩放的边界框坐标信息
		(startX, startY, endX, endY) = box.astype("int")
        # 计算边界框坐标,将box边界框中的坐标转换为整数类型

		# draw the bounding box of the face along with the associated
		# probability
		text = "{:.2f}%".format(confidence * 100)   # 置信度文本
		y = startY - 10 if startY - 10 > 10 else startY + 10 
		# 防止文本远离图像,将其下移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)
		#显示检测概率
# show the output image
cv2.imshow("Output", image)
cv2.waitKey(0)

参数解析

import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
	help="path to input image")
args = vars(ap.parse_args())

ap = argparse.ArgumentParser() 是创建一个参数解析器对象的代码,它是 argparse 模块中的一个类,用于创建命令行参数解析器。
ap 是创建的参数解析器对象,可以用于定义、解析和获取命令行参数。
通过调用该函数,可以创建一个空的参数解析器对象,并将其赋值给变量 ap。参数解析器对象可以用于在命令行中解析和获取参数值,以便根据不同的参数执行相应的操作。

ap.add_argument("-i", "--image", required=True, help="path to input image") 是向参数解析器添加一个名为 -i 或 --image 的命令行参数的代码。
ap.add_argument() 是参数解析器对象的方法,用于向解析器添加命令行参数
"-i" 是命令行参数的短格式,即单个字符形式的参数名
"--image" 是命令行参数的格式,即多个字符形式的参数名
required=True 表示该参数是必需的,必须在命令行中提供。
help="path to input image" 是该参数的帮助信息,用于在命令行中显示参数的用法和描述。

args = vars(ap.parse_args())解析命令行参数并将其存储在字典中的代码。
ap.parse_args() 是参数解析器对象的方法,用于解析命令行参数。
vars() 是 Python 内置函数,用于将对象转换为字典形式。
可以通过 args["image"]args.image 来获取输入图像的路径值。

你可能感兴趣的:(opencv,caffe,深度学习,人工智能)