使用 Haar Cascade 进行人脸检测

927 阅读6分钟

面部检测是计算机视觉中的一项重要任务,在安全、娱乐和健康等领域有着广泛的应用。Haar Cascade 是一种流行的面部检测算法,可以使用 Python 中的 OpenCV 库轻松实现。在本文中,我们将讨论如何使用 Haar Cascade 检测人脸,并提供带有注释的完整代码示例。

什么是哈尔级联?

Haar Cascade是一种基于机器学习的算法,用于检测图像或视频中的对象。该算法使用一组类似 Haar 的特征(像素值的矩形模式)来区分对象和背景。该算法使用这些特征训练分类器,然后可用于检测新图像或视频中的对象。

image.png

用于面部检测的 Haar Cascade

Haar Cascade 特别适合面部检测,因为类 Haar 特征可用于区分眼睛、鼻子和嘴巴等面部特征。该算法首先使用一组正面和负面图像创建 Haar Cascade 分类器来检测人脸。正图像包含人脸,而负图像不包含人脸。

然后使用分类器扫描新图像或视频中的面孔。扫描过程涉及在图像上滑动固定大小的窗口并将分类器应用于每个窗口。如果分类器在窗口中检测到人脸,则将其标记为潜在人脸。然后根据他们的大小、位置和形状过滤潜在的面孔,以减少误报。

image.png

在 Python 中实现 Haar Cascade

要在 Python 中实施 Haar Cascade,我们将使用 OpenCV 库,它提供用于面部检测的预训练 Haar Cascade 分类器。我们将使用 cv2.CascadeClassifier 类创建分类器,并使用detectMultiScale方法检测图像中的人脸。

第 1 步:安装所需的库

我们将从安装所需的库开始。可以使用 pip 安装 OpenCV 和 TensorFlow。要安装这些库,请打开终端或命令提示符并键入以下命令:

pip 安装 opencv-python 
pip 安装 tensorflow

第 2 步:实施 Haar Cascade 进行人脸检测

我们将从 Haar Cascade 开始,然后转向 TensorFlow 以进行更准确的检测。

让我们从导入必要的库开始:

导入cv2将matplotlib.pyplot
导入为plt

接下来,我们将创建一个CascadeClassifier对象并加载用于面部检测的预训练分类器:

face_cascade = cv2.CascadeClassifier( 'haarcascade_frontalface_default.xml' )

haarcascade_frontalface_default.xml文件包含用于面部检测预训练分类器。

现在,让我们加载图像并将其转换为灰度:

img = cv2.imread( 'face.jpg' ) 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

我们将使用cv2.imread方法加载图像,并使用cv2.cvtColor方法将其转换为灰度。灰度图像比彩色图像更容易处理,并且可以提高人脸检测的准确性。

接下来,我们将应用detectMultiScale方法来检测图像中的人脸:

faces = face_cascade.detectMultiScale(灰色, scaleFactor= 1.1 , minNeighbors= 5 )

detectMultiScale方法将灰度图像作为输入,并返回每个检测到的人脸的直角坐标列表。scaleFactor参数控制用于在扫描过程中调整图像大小的比例因子 ** **minNeighbors参数控制将潜在人脸视为人脸所需的最小相邻窗口数

最后,我们将在检测到的人脸周围绘制矩形:

对于面中的(x, y, w, h) :
    cv2.rectangle(img, (x, y), (x+w, y+h), ( 0 , 255 , 0 ), 2 ) 
plt.imshow(cv2 .cvtColor(img, cv2.COLOR_BGR2RGB))

cv2.rectangle方法用于在每个检测到的人脸周围绘制矩形 ** **(x, y) 坐标指定矩形的左上角,而 (x+w, y+h) 坐标指定右下角。(0, 255, 0)参数指定矩形的颜色,2参数指定矩形的粗细。

第 3 步:实施 TensorFlow 进行人脸检测

虽然 Haar Cascade 是一种流行的人脸检测算法,但它有一些局限性,可能并非在所有情况下都准确。另一方面,TensorFlow 是一个机器学习库,可用于训练更准确的人脸检测模型。

为了实现用于人脸检测的 TensorFlow,我们将使用来自 TensorFlow Object Detection API 的预训练模型。该模型在 WIDER FACE 数据集上进行训练,该数据集包含超过32,000 张带有标记面孔的图像。

让我们从导入必要的库开始:

导入numpy作为np
导入o ​​s
导入six.moves.urllib作为urllib导入sys
导入tarfile导入tensorflow作为tf从集合
导入zipfile从io导入StringIO从matplotlib导入pyplot作为plt导入PIL.image _

接下来,我们将从 TensorFlow Object Detection API 下载预训练模型:

MODEL_NAME = 'ssd_mobilenet_v1_coco_2018_01_28'
 MODEL_FILE = MODEL_NAME + '.tar.gz'
 DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/' 

# 下载模型

opener = urllib.request.URLopener() 
opener.retrieve( DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE) 

# 提取模型

tar_file = tarfile. 在 tar_file.getmembers() 中打开( MODEL_FILE)文件:  file_name = os.path.basename(file.name)如果在file_name中为“frozen_inference_graph.pb” :     tar_file.extract(file, os.getcwd())


    

ssd_mobilenet_v1_coco_2018_01_28模型是来自 TensorFlow 对象检测API 的预训练模型。我们将下载模型并使用上面的代码将其解压缩。现在,让我们将模型加载到内存中:

# 加载模型

PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'

 detection_graph = tf.Graph() 
with detection_graph.as_default(): 
  od_graph_def = tf.GraphDef() 
  with tf.gfile.GFile(PATH_TO_CKPT, 'rb' ) as fid : 
    serialized_graph = fid.read() 
    od_graph_def.ParseFromString(serialized_graph) 
    tf.import_graph_def(od_graph_def, name= '' )

上面的代码将模型加载到 TensorFlow 图中。我们使用 with 语句创建一个新图并将模型加载到其中。tf.gfile.GFile方法用于从文件系统中读取模型

接下来,我们将为检测到的对象定义标签:

    # 定义标签

    PATH_TO_LABELS = os.path.join( 'data' , 'mscoco_label_map.pbtxt' ) 

    category_index = {} 
    with  open (PATH_TO_LABELS, 'r' ) as f: 
      for line in f: 
        if  'id:'  in line : 
          id = int (line.split( ":" )[ 1 ]) 
        elif  'display_name'  in line: 
          name = line.split( ":" )[ 1 ].strip().replace( "'" , "")
          category_index[ id ] = { 'name' : name}

mscoco_label_map.pbtxt文件包含检测到的对象标签。我们将使用类别索引将对象检测输出映射到人类可读的标签。现在,让我们定义检测函数:

# 定义检测对象函数
def  detect_objects ( image_path, graph, category_index, min_score_thresh= .5 ): 
    # 加载图像
    image = cv2.imread(image_path) 
    image_np = np.array(image) 

    # 将图像转换为灰度
    gray = cv2. cvtColor(image_np, cv2.COLOR_BGR2GRAY) 

    # 使用 Haar Cascade 分类器检测人脸
    faces = face_cascade.detectMultiScale(gray, 1.3 , 5 ) 

    # 遍历每个人脸并在其周围绘制一个矩形
    for (x,y,w,h) in面孔:
        cv2.rectangle(image_np,(x,y),(x+w,y+h),( 0 , 255, 0 ), 2 ) 

    # 显示图像
    cv2.imshow( 'Face Detection' , image_np) 
    cv2.waitKey( 0 ) 
    cv2.destroyAllWindows()

现在我们定义IMAGE_PATH并使用上面的函数检测人脸。

# 定义图像的路径
IMAGE_PATH = 'test_image.jpg' 

# 检测图像中的人脸
detect_objects(IMAGE_PATH, detection_graph, category_index, min_score_thresh= .5 )

简要介绍我们在代码中所做的事情。

  1. 我们导入必要的库——cv2 用于 OpenCV、numpy数值计算和tensorflow TensorFlow 对象检测模型。
  2. 我们从名为“ haarcascade_frontalface_default.xml ”的预训练 XML 文件中加载 Haar Cascade 分类器。该分类器用于检测图像中的人脸。
  3. 我们通过定义冻结推理图 ( PATH_TO_CKPT) 的路径、标签图 ( ) 的路径PATH_TO_LABELS和模型中的类数 ( NUM_CLASSES) 来加载 TensorFlow 对象检测模型。
  4. 我们定义了一个名为的函数,detect_objects它采用图像路径、TensorFlow 检测图、类别索引(用于将类 ID 映射到名称)和检测的最小分数阈值。该函数首先加载图像并将其转换为灰度图,然后使用 Haar Cascade 分类器检测图像中的人脸。然后该函数遍历每个检测到的人脸并在其周围绘制一个矩形。最后,该函数显示带有检测到的人脸的图像。
  5. 我们定义输入图像 ( ) 的路径IMAGE_PATH
  6. 我们使用detect_objects输入图像路径、TensorFlow 检测图、类别索引和 0.5 的最小分数阈值调用该函数。该函数检测输入图像中的人脸,并突出显示检测到的人脸。