admin 管理员组

文章数量: 887021


2023年12月19日发(作者:低代码平台有哪些)

题目 基于OpenCV和Python模式识别系统的设计与实现

1.1 题目的主要研究内容

(1)工作的主要描述(宋体小四号不加粗1.5倍行距)

利用python中自带的opencv库中的人脸识别算法制作一个简易的模式识别系统,使用自己搜集到的数据集对模型进行训练,最终完成特征提取、分类等工作,并且在最后的推理过程中,实现了人脸识别的工作。

(2)系统流程图

导入所需模块

准备训练数据集

训练人脸识别器

推理

1.2 题目研究的工作基础或实验条件

软件环境:cv2:是用于Python的OpenCV模块,我们将用于人脸检测和人脸识别。操作系统:将使用此 Python 模块读取我们的训练目录和文件名。numpy:将使用此模块将Python列表转换为numpy数组,因为OpenCV人脸识别器接受numpy数组。

1.3 数据集描述

训练中使用的图像越多越好。通常,许多图像用于训练面部识别器,以便它可以学习同一个人的不同外观,例如戴眼镜,不戴眼镜,大笑,悲伤,快乐,哭泣,留胡子,无胡须等。为了使训练保持简单,将为每个人仅使用12张图像。因此,训练数据总共由2个人组成,每人有12张图像。所有训练数据都training-data文件夹中。training-data文件夹包含每个人的一个文件夹,每个文件夹都以sLabel格式命名(例如s1,s2),其中标签实际上是分配给该人的整数标签。例如,名为 s1 的文件夹表示此文件夹包含人员 1 的图像。训练数据的目录结构树如下所示:

training-data

|-------------- s1

| |--

| |-- ...

| |--

|-------------- s2

| |--

| |-- ...

| |--

1.4 特征提取过程描述

该系统中采用的特征提取算法是局部二值模式直方图(LBPH)算法,而原始的LBP算子定义为在3*3的窗口内以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数(通常

转换为十进制数即LBP码,共256种),即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。提取的LBP算子在每个像素点都可以得到一个LBP“编码”,那么,对一幅图像(记录的是每个像素点的灰度值)提取其原始的LBP算子之后,得到的原始LBP特征依然是“一幅图片”(记录的是每个像素点的LBP值)。

对LBP特征向量进行提取的步骤:

(1)首先将检测窗口划分为16×16的小区域(cell);

(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值。

1.5 分类过程描述

该系统用到的分类器是opencv中提供训练好的级联分类器,该分类器是一种Harr级联分类器,Harr级联分类器的具体分类过程为:

1. 提取类Haar特征;

2. 利用积分图法对类Haar特征提取进行加速;

3. 使用Adaboost算法训练强分类器,区分出人脸和非人脸;

4. 使用筛选式级联把强的分类器级联在一起,从而提高检测准确度。

opencv中提供的Harr级联分类器共有20多种,它们都以xml文件的格式保存在opencv中的data文件夹下,这些级联分类器可以检测人脸,以及人脸的不同特征,或者人类和其它物体等等,本项目中保存的分类器除了Harr级联分类器还保存了LBP级联分类器,这两个分类器的分类过程本质基本相似,所以在此不对LBP级联分类器的分类过程做具体叙述。综上,我们选择对正面人脸为特征做检测的Haar和LBP级联分类器,在项目中以haarcascade_frontalface_文件和lbpcascade_frontalface_alt,xml文件存在。

1.6 主要程序代码

import cv2

#导入opencv模块

import os

#导入os模块用于读取训练数据目录和路径

import numpy as np

#导入numpy将ython列表转换为numpy数组

subjects = ["", "Ramiz Raja", "Elvis Presley"]

#定义需要分类目标的名字

def detect_face(img):

#定义使用opencv用来检测脸部的函数

gray = or(img, _BGR2GRAY)

#将测试图像转换为灰度图像

face_cascade = eClassifier('opencv-files/lbpcascade_')

#加载opencv人脸检测器

faces = face_MultiScale(gray, scaleFactor=1.2, minNeighbors=5);

#结果是一张脸的列表

if (len(faces) == 0):

#如果未检测到面部,则返回原始图像

return None, None

(x, y, w, h) = faces[0]

#只有一张脸,提取面部区域

return gray[y:y+w, x:x+h], faces[0]

#只返回图像正面部分

def prepare_training_data(data_folder_path):

#该函数用于读取所有人的训练图像,从每个图像检测人脸,并将返回两个完全相同大小的列表,参数为目录的路径

dirs = r(data_folder_path)

faces = []

#列表来保存所有主题的面孔

labels = []

#列表来保存所有主题的标签

for dir_name in dirs:

if not dir_with("s"):

continue;

label = int(dir_e("s", ""))

subject_dir_path = data_folder_path + "/" + dir_name

subject_images_names = r(subject_dir_path)

for image_name in subject_images_names:

#检测脸部并将脸部添加到脸部列表

if image_with("."):

#忽略.DS_Store之类的系统文件

continue;

image_path = subject_dir_path + "/" + image_name

#建立图像路径

image = (image_path)

#阅读图像

("Training ", (image, (400, 500)))

y(100) #显示图像窗口以显示图像

face, rect = detect_face(image)

#侦测脸部

if face is not None:

#忽略未检测到的脸部

(face)

#将这张脸添加到脸部列表

(label)

#为这张脸添加标签

yAllWindows()

y(1)

yAllWindows()

return faces, labels

#准备好训练数据,数据将在两个大小相同的列表中,一个列表包含所有的面孔:

print("")

faces, labels = prepare_training_data("training-data")

print("Data prepared")

#打印总面和标签:

print("Total faces: ", len(faces))

print("Total labels: ", len(labels))

#训练人脸识别器,使用LBPH人脸识别器

face_recognizer = ceRecognizer_create()

#创建LBPH人脸识别器

face_(faces, (labels))

#训练人脸识别器

#此函数用于在图像上绘制矩形,根据给定的(x,y)坐标和给定的宽度和高度来绘制:

def draw_rectangle(img, rect):

(x, y, w, h) = rect

gle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)

#函数在此图像开始绘制文本,通过(x,y)坐标

def draw_text(img, text, x, y):

t(img, text, (x, y), _HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)

def predict(test_img):

img = test_()

#制作图像的副本,不更改原始图像

face, rect = detect_face(img)

#从图像中检测到脸部

label, confidence = face_t(face)

#使用脸部识别器预测图像

label_text = subjects[label]

#获取由人脸识别器返回的相应标签名称

draw_rectangle(img, rect)

#在检测到的脸部周围画一个矩形

draw_text(img, label_text, rect[0], rect[1]-5)

#画预计人的名字

return img

print("")

#输入测试图像:

test_img1 = ("test-data/")

test_img2 = ("test-data/")

#输入推理图像:

predicted_img1 = predict(test_img1)

predicted_img2 = predict(test_img2)

#代码结束时输出“Prediction complete”:

print("Prediction complete")

#显示两个图像:

(subjects[1], (predicted_img1, (400, 500)))

(subjects[2], (predicted_img2, (400, 500)))

y(0)

yAllWindows()

y(1)

yAllWindows()

1.7 运行结果及分析

可以清晰地看到两个推理图片的结果满足我们的预期效果,在他们的脸部周围绘制出了预测框,并且分好了类别。


本文标签: 图像 训练 分类器 级联 脸部