交通标志识别与面部表情识别技术解析
交通标志识别
在交通标志识别中,我们采用了多类支持向量机(MultiClassSVM),并对比了两种分类策略:一对多(one-vs-all)和一对一(one-vs-one),同时使用了多种特征提取方法。
一对多策略的召回率计算
一对多策略在数学计算上相对简单。我们仅需找出真实标签不在 y_test 中类别 c ,但预测标签在 y_hat 中为类别 c 的样本。以下是计算召回率的代码:
elif self.mode == "one-vs-all":
# consider each class separately
recall = np.zeros(self.numClasses)
for c in xrange(self.numClasses):
# true positives: label is c, classifier predicted c
tp = np.count_nonzero((y_test==c) * (y_hat==c))
# false negatives: label is not c, classifier
# predicted c
fn = np.count_nonzero((y_test!=c) * (y_hat==c))
if tp + fn != 0:
recall[c] = tp*1./(tp+fn)
return recall
整体流程
要运行该应用,需执行主函数,其流程如下:
1. 导入相关模块并设置主函数 :
import numpy as np
import matplotlib.pyplot as plt
from datasets import gtsrb
from classifiers import MultiClassSVM
def main():
- 定义分类策略和特征提取方法 :
strategies = ['one-vs-one', 'one-vs-all']
features = [None, 'gray', 'rgb', 'hsv', 'surf', 'hog']
- 初始化性能指标矩阵 :
accuracy = np.zeros((2,len(features)))
precision = np.zeros((2,len(features)))
recall = np.zeros((2,len(features)))
- 嵌套循环运行分类器 :
for f in xrange(len(features)):
(X_train,y_train), (X_test,y_test) = gtsrb.load_data(
"datasets/gtsrb_training",
feature=features[f], test_split=0.2)
X_train = np.squeeze(np.array(X_train)).astype(np.float32)
y_train = np.array(y_train)
X_test = np.squeeze(np.array(X_test)).astype(np.float32)
y_test = np.array(y_test)
labels = np.unique(np.hstack((y_train,y_test)))
for s in xrange(len(strategies)):
MCS = MultiClassSVM(len(labels),strategies[s])
MCS.fit(X_train, y_train)
(accuracy[s,f],precision[s,f],recall[s,f]) =
MCS.evaluate(X_test, y_test)
- 可视化结果 :
f,ax = plt.subplots(2)
for s in xrange(len(strategies)):
x = np.arange(len(features))
ax[s].bar(x-0.2, accuracy[s,:], width=0.2, color='b',
hatch='/', align='center')
ax[s].bar(x, precision[s,:], width=0.2, color='r',
hatch='\\', align='center')
ax[s].bar(x+0.2, recall[s,:], width=0.2, color='g',
hatch='x', align='center')
ax[s].axis([-0.5, len(features) + 0.5, 0, 1.5])
ax[s].legend(('Accuracy','Precision','Recall'), loc=2,
ncol=3, mode="expand")
ax[s].set_xticks(np.arange(len(features)))
ax[s].set_xticklabels(features)
ax[s].set_title(strategies[s])
plt.show()
结果分析
- HOG 特征表现出色 :无论采用哪种分类策略,HOG 特征的性能都优于其他特征,这凸显了特征提取的重要性。
- 一对一策略准确性高 :使用一对一策略时,所有方法的准确率都超过 0.95,可能是因为二分类任务相对容易学习。
- 归一化的影响 :对比
None和rgb的结果,可看出归一化对性能有明显影响,尤其是在一对多策略中。 - 颜色变换效果不佳 :RGB 和 HSV 等颜色变换的性能并不比简单的灰度变换好,SURF 特征也没有起到明显作用。
面部表情识别
在面部表情识别中,我们的目标是开发一个结合人脸检测和人脸识别的应用,重点识别检测到的面部的情感表达。
整体目标与挑战
- 目标 :开发一个应用,在网络摄像头的实时流中检测人脸,并标注其情感表达。我们将情感表达限制为中性、快乐、悲伤、惊讶、愤怒和厌恶。
- 挑战 :
- 人脸检测 :使用 Viola 和 Jones 的 Haar 级联分类器,OpenCV 提供了一系列预训练的分类器,我们将使用人脸级联和眼睛级联来可靠地检测和对齐面部区域。
- 面部表情识别 :训练一个多层感知器(MLP)来识别六种不同的情感表达。成功的关键在于训练集的质量和预处理方法,我们将使用仿射变换对齐数据样本,并通过主成分分析(PCA)降低特征空间的维度。
应用组件
应用由以下组件组成:
|组件名称|功能描述|
| ---- | ---- |
|chapter7|主脚本和入口点|
|chapter7.FaceLayout|基于 gui.BaseLayout 的自定义布局,有训练和测试两种模式|
|chapter3.main|启动 GUI 应用的主函数|
|detectors.FaceDetector|人脸检测类,包含 detect 和 align_head 方法|
|classifiers.Classifier|所有分类器的抽象基类|
|classifiers.MultiLayerPerceptron|实现 MLP 的类,包含 fit 、 evaluate 、 predict 、 save 和 load 方法|
|train_test_mlp|训练和测试 MLP 的脚本|
|datasets.homebrew|解析自记录训练集的类,包含 load_data 、 load_from_file 和 extract_features 方法|
|gui|提供 wxPython GUI 应用的模块|
人脸检测
OpenCV 预装了一系列用于通用目标检测的复杂分类器,其中最著名的是 Viola - Jones 发明的基于 Haar 特征的级联分类器,用于人脸检测。
- Haar 级联分类器原理 :该分类器基于 Haar 类特征,通过计算图像小区域内像素强度的总和以及相邻区域的差异来描述人脸特征。例如,常见的 Haar 特征是将代表眼睛区域的深色矩形置于代表脸颊区域的明亮矩形之上。
- 预训练级联分类器 :OpenCV 提供了多种预训练的级联分类器,可用于检测人脸、眼睛、嘴巴等。以下是一些常用的分类器及其对应的 XML 文件:
|级联分类器类型|XML 文件名称|
| ---- | ---- |
|人脸检测器(默认)|haarcascade_frontalface_default.xml|
|人脸检测器(快速 Haar)|haarcascade_frontalface_alt2.xml|
|眼睛检测器|haarcascade_lefteye_2splits.xml
haarcascade_righteye_2splits.xml|
|嘴巴检测器|haarcascade_mcs_mouth.xml|
|鼻子检测器|haarcascade_mcs_nose.xml|
|全身检测器|haarcascade_fullbody.xml| - 使用预训练级联分类器 :以下是加载并应用级联分类器到灰度图像的代码:
import cv2
frame = cv2.imread('example_grayscale.jpg', cv2.CV_8UC1)
face_casc =
cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faces = face_casc.detectMultiScale(frame, scaleFactor=1.1,
minNeighbors=3)
for (x, y, w, h) in faces:
# draw bounding box on frame
cv2.rectangle(frame, (x, y), (x + w, y + h), (100, 255, 0), 2)
detectMultiScale 函数有多个选项:
- minFeatureSize :最小人脸尺寸。
- searchScaleFactor :图像缩放因子。
- minNeighbors :每个候选矩形所需的邻居数量。
- flags :旧级联的选项。
人脸检测器类
FaceDetector 类封装了人脸检测和预处理的功能。
import cv2
import numpy as np
class FaceDetector:
def __init__(self,
face_casc='params/haarcascade_frontalface_default.xml',
left_eye_casc='params/haarcascade_lefteye_2splits.xml',
right_eye_casc='params/haarcascade_righteye_2splits.xml',
scale_factor=4):
self.face_casc = cv2.CascadeClassifier(face_casc)
if self.face_casc.empty():
print 'Warning: Could not load face cascade:',
face_casc
raise SystemExit
self.left_eye_casc = cv2.CascadeClassifier(left_eye_casc)
if self.left_eye_casc.empty():
print 'Warning: Could not load left eye cascade:',
left_eye_casc
raise SystemExit
self.right_eye_casc =
cv2.CascadeClassifier(right_eye_casc)
if self.right_eye_casc.empty():
print 'Warning: Could not load right eye cascade:',
right_eye_casc
raise SystemExit
self.scale_factor = scale_factor
def detect(self, frame):
frameCasc = cv2.cvtColor(cv2.resize(frame, (0, 0),
fx=1.0 / self.scale_factor, fy=1.0 / self.scale_factor),
cv2.COLOR_RGB2GRAY)
faces = self.face_casc.detectMultiScale(frameCasc,
scaleFactor=1.1, minNeighbors=3,
flags=cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT) *
self.scale_factor
for (x, y, w, h) in faces:
head = cv2.cvtColor(frame[y:y + h, x:x + w],
cv2.COLOR_RGB2GRAY)
cv2.rectangle(frame, (x, y), (x + w, y + h), (100, 255, 0), 2)
return True, frame, head
return False, frame, None
def align_head(self, head):
height, width = head.shape[:2]
left_eye_region = head[0.2*height:0.5*height,
0.1*width:0.5*width]
left_eye = self.left_eye_casc.detectMultiScale(
left_eye_region, scaleFactor=1.1, minNeighbors=3,
flags=cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT)
left_eye_center = None
for (xl, yl, wl, hl) in left_eye:
left_eye_center = np.array([0.1 * width + xl + wl / 2,
0.2 * height + yl + hl / 2])
break
right_eye_region = head[0.2*height:0.5*height,
0.5*width:0.9*width]
right_eye = self.right_eye_casc.detectMultiScale(
right_eye_region, scaleFactor=1.1, minNeighbors=3,
flags=cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT)
right_eye_center = None
for (xr, yr, wr, hr) in right_eye:
right_eye_center = np.array([0.5 * width + xr + wr / 2,
0.2 * height + yr + hr / 2])
break
if left_eye_center is None or right_eye_center is None:
return False, head
desired_eye_x = 0.25
desired_eye_y = 0.2
desired_img_width = 200
desired_img_height = desired_img_width
eye_center = (left_eye_center + right_eye_center) / 2
eye_angle_deg = np.arctan2(
right_eye_center[1] - left_eye_center[1],
right_eye_center[0] - left_eye_center[0]) *
180.0 / cv2.cv.CV_PI
以下是人脸检测和预处理的流程:
graph LR
A[输入图像] --> B[FaceDetector初始化]
B --> C[detect方法检测人脸]
C -->|检测到人脸| D[提取头部区域]
C -->|未检测到人脸| E[返回失败信息]
D --> F[align_head方法对齐头部]
F -->|对齐成功| G[返回对齐后的人脸]
F -->|对齐失败| H[返回原头部区域]
通过以上方法,我们可以实现交通标志识别和面部表情识别的功能,为相关领域的应用提供了有效的解决方案。
交通标志识别与面部表情识别技术解析(续)
面部表情识别(续)
多层感知器(MLP)的实现与应用
在面部表情识别中,多层感知器(MLP)起着关键作用。 classifiers.MultiLayerPerceptron 类实现了 MLP 的主要功能,以下是该类的详细介绍:
import numpy as np
class MultiLayerPerceptron:
def fit(self, X_train, y_train):
# 实现将 MLP 拟合到训练数据的逻辑
pass
def evaluate(self, X_test, y_test):
# 评估 MLP 在测试数据上的性能,返回准确率、精确率和召回率
accuracy = 0
precision = 0
recall = 0
return (accuracy, precision, recall)
def predict(self, X_test):
# 预测测试数据的类别标签
return np.zeros(X_test.shape[0])
def save(self, filename):
# 将训练好的 MLP 保存到文件
pass
def load(self, filename):
# 从文件中加载预训练的 MLP
pass
- fit 方法 :该方法将 MLP 拟合到训练数据。输入为训练数据矩阵
X_train,其中每行是一个训练样本,列包含特征值,以及标签向量y_train。 - evaluate 方法 :在训练完成后,将 MLP 应用于测试数据
X_test和标签向量y_test,返回三个性能指标:准确率、精确率和召回率。 - predict 方法 :用于预测测试数据的类别标签,可应用于任意数量的数据样本,在测试模式下非常有用。
- save 方法 :将训练好的 MLP 保存到文件,方便后续使用。
- load 方法 :从文件中加载预训练的 MLP。
训练和测试 MLP
train_test_mlp 脚本用于训练和测试 MLP。该脚本会探索不同的网络架构,并将具有最佳泛化性能的模型存储在文件中,以便后续加载使用。以下是一个简化的示例流程:
from classifiers import MultiLayerPerceptron
from datasets.homebrew import load_data
# 加载数据
(X_train, y_train), (X_test, y_test) = load_data("datasets/self_recorded", test_split=0.2)
# 初始化 MLP
MLP = MultiLayerPerceptron()
# 训练 MLP
MLP.fit(X_train, y_train)
# 评估 MLP
accuracy, precision, recall = MLP.evaluate(X_test, y_test)
print(f"Accuracy: {accuracy}, Precision: {precision}, Recall: {recall}")
# 保存最佳模型
MLP.save("best_mlp_model.pkl")
自记录训练集的处理
datasets.homebrew 类用于解析自记录的训练集,包含以下方法:
import numpy as np
from sklearn.decomposition import PCA
class homebrew:
def load_data(self, data_path, test_split=0.2, save_preprocessed=False):
# 加载训练集,进行 PCA 特征提取,并将数据拆分为训练集和测试集
# 可选:将预处理后的数据存储在文件中
pass
def load_from_file(self, filename):
# 从文件中加载先前存储的预处理数据集
pass
def extract_features(self, X):
# 提取特征(在本章中为对数据进行 PCA)
pca = PCA(n_components=100)
X_pca = pca.fit_transform(X)
return X_pca
- load_data 方法 :加载训练集,通过
extract_features函数进行 PCA 特征提取,并将数据拆分为训练集和测试集。可以选择将预处理后的数据存储在文件中,以便后续直接加载。 - load_from_file 方法 :从文件中加载先前存储的预处理数据集。
- extract_features 方法 :提取特征,在本章中是对数据进行 PCA 处理,降低特征空间的维度。
总结
通过对交通标志识别和面部表情识别技术的研究,我们可以得出以下结论:
-
交通标志识别 :
- 特征提取对分类性能有显著影响,HOG 特征表现出色。
- 一对一分类策略在某些情况下能取得较高的准确率。
- 数据的归一化处理可以提高分类性能。
-
面部表情识别 :
- Haar 级联分类器是一种有效的人脸检测方法,结合眼睛级联可以提高检测的准确性。
- 多层感知器(MLP)可以用于面部表情的识别,通过合理的训练和预处理可以取得较好的效果。
- 自记录训练集的质量和预处理方法对识别性能至关重要,PCA 可以有效降低特征空间的维度。
以下是交通标志识别和面部表情识别的对比表格:
| 项目 | 交通标志识别 | 面部表情识别 |
| ---- | ---- | ---- |
| 分类器 | 多类支持向量机(MultiClassSVM) | 多层感知器(MLP) |
| 特征提取 | 多种方法(HOG、RGB、HSV 等) | PCA |
| 检测方法 | 无 | Haar 级联分类器 |
| 应用场景 | 交通领域 | 人机交互、情感分析等 |
通过这些技术的结合和应用,我们可以开发出更加智能和实用的系统,为交通和人机交互等领域带来新的发展。未来,我们可以进一步探索更先进的算法和技术,提高识别的准确性和效率,为相关领域的发展做出更大的贡献。
graph LR
A[交通标志识别] --> B[特征提取]
A --> C[分类策略选择]
B --> D[HOG 特征]
B --> E[其他特征]
C --> F[一对多策略]
C --> G[一对一策略]
H[面部表情识别] --> I[人脸检测]
H --> J[表情识别]
I --> K[Haar 级联分类器]
J --> L[多层感知器(MLP)]
K --> M[人脸检测与对齐]
L --> N[训练与评估]
以上内容详细介绍了交通标志识别和面部表情识别的技术原理、实现方法和应用场景,为相关领域的研究和开发提供了有价值的参考。
超级会员免费看

13

被折叠的 条评论
为什么被折叠?



