用Python和OpenCV人脸检测神经网络检测人脸
用Python和OpenCV人脸检测神经网络检测人脸
现在,我们都知道人工智能正在变得越来越真实,它日益填补人类和机器之间的能力差距。它不再是一个花哨的词。多年来,它在许多领域取得了许多进步,其中一个领域是计算机视觉领域。
谈到计算机视觉,它的目标是训练机器像人类一样观察和识别世界。并且还收集足够多的知识以执行图像和视频识别,图像分析和分类,媒体娱乐,自然语言处理等。
卷积神经网络
随着时间的推移,计算机视觉的进步已经逐步实现和完善,主要是通过一种特定的算法 - 卷积神经网络(CNNs或ConvNets),这是一种特殊类型的前馈网络,主要用于分析视觉图像。卷积神经网络与普通神经网络非常相似,由可学习权重和偏差的神经元组成。
卷积神经网络由于其独特的处理过程而优于其他深层神经网络体系结构。ConvNets不是一次查看一个像素,而是将多个像素分组,以便理解时间模式。换句话说,ConvNets可以“看到”一组像素组成一条线或一条曲线。由于深度神经网络的深层性质,在下一深度中,它们看到的不是一组像素,而是一组形成某些形状的直线和曲线组。依此类推,直到他们形成完整的画面。
迁移学习
然而,CNNs需要大量的数据集和大量的计算时间来训练。有些甚至可能需要2-3周才能在多个GPU上运行。如果你想了解CNNs,你需要学习很多东西,从基本的东西,从最基本的东西开始,比如内核、池层等等。但是现在, 您可以直接使用许多开源项目来实现这项技术。
这实际上是因为称为迁移学习的技术。迁移学习是一种非常实用和强大的技术,它利用训练过的模型而不是从头开始训练网络。迁移学习利用不同数据集上的训练模型,并使其适应我们试图解决的问题。
为了构建我们的应用程序,我们将遵循迁移学习技术并使用经过训练的模型,该模型使用Caffe框架进行训练,这是一个深入学习框架,以表达,速度和模块化为基础。Caffe附带了一个存储库,供研究人员和机器学习从业者用来共享他们训练过的模型。该库称为Model Zoo。
启动程序
在我们的应用程序中,我们将使用以下库:
- OpenCV,它支持许多与计算机视觉和机器学习相关的算法,更不用说它是建立在深度神经网络中的,我们将在应用程序中使用。
- Numpy,这是一个用于python科学计算的软件包。
- OS,提供使用操作系统相关功能的可移植方法
因此,要安装它们,可以在“命令提示符”窗口中运行以下命令。pip install opencv-python安装OpenCV,pip install numpy安装Numpy,不需要专门安装OS库,因为Python中已经附带有了,我们只是需要导入即可。
构建应用程序
首先,让我们创建一个名为faceDetection.py的文件并导入我们的库。
#import libraries import os import cv2 import numpy
现在,我们将获得工作目录的绝对路径,我们将所有图像放置在这里,
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__))
现在,我们将创建一个名为“Output”的文件夹,以放置我们的最终图像。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output')
之后,我们将从当前工作目录加载我们预先训练的模型和proto.txt文件。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output') #Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
然后,我们将遍历当前文件夹中可用的文件,以检查是否存在扩展名为.png,.jpg和.jpeg的文件。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output') #Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel') for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file) #check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']):
如果找到具有上述扩展名的图像,我们将使用OpenCV读取图像,并通过访问image.shape获取它的高度和宽度,然后取前两个元素来绘制矩形。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output') #Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel') for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file) #check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file) #accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2]
然后,我们将cv2.dnn.blobFromImage函数通过将图像作为输入来获取我们的blob 。使用cv2.dnn.blobFromImage函数我们将图像调整为300x300维度,1.0是比例因子,这里我们使用默认值,因此没有缩放,之后是卷积神经网络预测的空间大小,最后的值是元组中的平均减法值,它们是RGB均值,最后,函数返回一个“blob”,它是调整大小,平均减法和标准化后的输入图像。
之后,我们将blob输入模型并使用model.foreward函数获取检测。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output') #Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel') for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file) #check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file) #accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2] #get our blob which is our input image blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) #input the blob into the model and get back the detections model.setInput(blob) detections = model.forward()
然后,我们将遍历所有检测到的所有面,并提取它们的起点和终点。我们将提取置信度并将其与置信度阈值进行比较,这样我们就可以过滤掉微弱的检测。如果算法对人脸检测的置信度超过16.5%,我们将在其上显示一个绿色矩形。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output') #Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel') for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file) #check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file) #accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2] #get our blob which is our input image blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) #input the blob into the model and get back the detections model.setInput(blob) detections = model.forward() #Iterate over all of the faces detected and extract their start and end points count = 0 for i in range(0, detections.shape[2]): box = detections[0, 0, i, 3:7] * numpy.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") confidence = detections[0, 0, i, 2] #if the algorithm is more than 16.5% confident that the detection is a face, show a rectangle around it if (confidence > 0.165): cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2) count = count + 1
最后,我们将输出图像保存在我们创建的Output文件夹中,并输出一条成功消息,让用户知道它已完成。
#import libraries import os import cv2 import numpy #get the absolute path of the working directory dir_path = os.path.dirname(os.path.realpath(__file__)) #create the Output folder if it doesn't already exist if not os.path.exists('Output'): os.makedirs('Output') #Reads the network model stored in Caffe framework's format. model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel') for file in os.listdir(dir_path): #split the file name and the extension into two variales filename, file_extension = os.path.splitext(file) #check if the file extension is .png,.jpeg or .jpg if (file_extension in ['.png','.jpg','.jpeg']): #read the image using cv2 image = cv2.imread(file) #accessing the image.shape tuple and taking the elements (h, w) = image.shape[:2] #get our blob which is our input image blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) #input the blob into the model and get back the detections model.setInput(blob) detections = model.forward() #Iterate over all of the faces detected and extract their start and end points count = 0 for i in range(0, detections.shape[2]): box = detections[0, 0, i, 3:7] * numpy.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") confidence = detections[0, 0, i, 2] #if the algorithm is more than 16.5% confident that the detection is a face, show a rectangle around it if (confidence > 0.165): cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2) count = count + 1 #save the modified image to the Output folder cv2.imwrite('Output/' + file, image) #print out a success message print("Face detection complete for image "+ file + " ("+ str(count) +") faces found!")
我希望你喜欢这个结果!现在,您可以随时使用代码来了解每个函数的作用。如果您想阅读并获取更多信息,OpenCV提供了很好的文档和教程。
结论
在这篇文章中,我们讲解了:
- 卷积神经网络的概念以及我们如何通过迁移学习和预训练模型节省大量时间和精力。
- 以及我们如何使用预先训练好的Caffe模型来实现我们的应用程序。
- 安装所需的库并设置环境。
最后,我们实现了一个可以使用图像进行检测的python程序。