基于AdaBoost算法的人脸检测原理与实现
一、AdaBoost人脸检测原理
1.1 基本思想
AdaBoost(Adaptive Boosting)是一种集成学习算法,通过组合多个弱分类器来构建一个强分类器。在人脸检测中,每个弱分类器基于简单的Haar-like特征进行决策。
1.2 Haar-like特征
Haar-like特征是通过计算图像中相邻矩形区域的像素和之差得到的,能够捕捉人脸的局部特征:
- 边缘特征
- 线性特征
- 中心环绕特征
1.3 AdaBoost训练过程
- 初始化权重:为每个训练样本分配相等的权重
- 迭代训练:
- 训练弱分类器(基于单个Haar特征)
- 选择错误率最小的弱分类器
- 更新样本权重(增加错分样本的权重)
- 计算该弱分类器的权重
- 组合强分类器:加权组合所有弱分类器
1.4 级联分类器
为提高检测效率,使用级联结构:
- 前几层用少量特征快速排除非人脸区域
- 后续层用更多特征进行精细判断
二、MATLAB实现代码
%% 基于AdaBoost的人脸检测MATLAB实现
clear; close all; clc;
%% 参数设置
numWeakClassifiers = 100; % 弱分类器数量
positiveSamples = 100; % 正样本数量(人脸)
negativeSamples = 200; % 负样本数量(非人脸)
imageSize = [24, 24]; % 图像尺寸
%% 生成训练数据(示例)
fprintf('生成训练数据...\n');
[trainFeatures, trainLabels] = generateTrainingData(positiveSamples, negativeSamples, imageSize);
%% 训练AdaBoost分类器
fprintf('训练AdaBoost分类器...\n');
[classifiers, alphas] = trainAdaBoost(trainFeatures, trainLabels, numWeakClassifiers);
%% 测试分类器
fprintf('测试分类器...\n');
testAccuracy = testClassifier(classifiers, alphas, trainFeatures, trainLabels);
fprintf('训练集准确率: %.2f%%\n', testAccuracy * 100);
%% 在测试图像上进行人脸检测
fprintf('进行人脸检测...\n');
testImageDetection(classifiers, alphas, imageSize);
%% 生成训练数据函数
function [features, labels] = generateTrainingData(posSamples, negSamples, imgSize)
% 这里应该从实际数据集中加载
% 为演示目的,生成模拟数据
totalSamples = posSamples + negSamples;
features = zeros(totalSamples, prod(imgSize));
labels = zeros(totalSamples, 1);
% 生成正样本(简单的人脸模式)
for i = 1:posSamples
img = generateFacePattern(imgSize);
features(i, :) = img(:);
labels(i) = 1;
end
% 生成负样本(随机纹理)
for i = posSamples+1:totalSamples
img = rand(imgSize);
features(i, :) = img(:);
labels(i) = -1;
end
end
%% 生成简单的人脸模式
function faceImg = generateFacePattern(imgSize)
faceImg = zeros(imgSize);
center = imgSize / 2;
radius = min(imgSize) * 0.3;
% 创建椭圆人脸
[X, Y] = meshgrid(1:imgSize(2), 1:imgSize(1));
distance = sqrt((X - center(2)).^2 + (Y - center(1)).^2);
faceImg(distance <= radius) = 1;
% 添加噪声
faceImg = faceImg + 0.1 * randn(imgSize);
end
%% AdaBoost训练函数
function [classifiers, alphas] = trainAdaBoost(features, labels, numClassifiers)
[nSamples, nFeatures] = size(features);
% 初始化样本权重
weights = ones(nSamples, 1) / nSamples;
classifiers = cell(numClassifiers, 1);
alphas = zeros(numClassifiers, 1);
for t = 1:numClassifiers
% 归一化权重
weights = weights / sum(weights);
% 训练弱分类器(决策树桩)
weakClassifier = trainWeakClassifier(features, labels, weights);
% 计算分类误差
predictions = predictWeakClassifier(weakClassifier, features);
error = sum(weights .* (predictions ~= labels));
% 计算分类器权重
alpha = 0.5 * log((1 - error) / max(error, eps));
% 更新样本权重
weights = weights .* exp(-alpha * labels .* predictions);
% 存储分类器
classifiers{t} = weakClassifier;
alphas(t) = alpha;
if mod(t, 10) == 0
fprintf('已完成 %d/%d 个弱分类器训练\n', t, numClassifiers);
end
end
end
%% 训练弱分类器(决策树桩)
function weakClassifier = trainWeakClassifier(features, labels, weights)
[nSamples, nFeatures] = size(features);
bestError = inf;
bestClassifier = struct();
% 随机选择部分特征进行搜索
numFeaturesToTry = min(50, nFeatures);
featureIndices = randperm(nFeatures, numFeaturesToTry);
for i = 1:numFeaturesToTry
featureIdx = featureIndices(i);
featureValues = features(:, featureIdx);
% 尝试不同的阈值
thresholds = linspace(min(featureValues), max(featureValues), 20);
for threshold = thresholds
for polarity = [-1, 1]
% 计算预测结果
predictions = polarity * (2*(featureValues > threshold) - 1);
% 计算加权误差
error = sum(weights .* (predictions ~= labels));
if error < bestError
bestError = error;
bestClassifier.featureIdx = featureIdx;
bestClassifier.threshold = threshold;
bestClassifier.polarity = polarity;
end
end
end
end
weakClassifier = bestClassifier;
end
%% 弱分类器预测
function predictions = predictWeakClassifier(classifier, features)
featureValues = features(:, classifier.featureIdx);
predictions = classifier.polarity * (2*(featureValues > classifier.threshold) - 1);
end
%% 强分类器预测
function predictions = predictStrongClassifier(classifiers, alphas, features)
nSamples = size(features, 1);
nClassifiers = length(classifiers);
finalScore = zeros(nSamples, 1);
for t = 1:nClassifiers
weakPredictions = predictWeakClassifier(classifiers{t}, features);
finalScore = finalScore + alphas(t) * weakPredictions;
end
predictions = sign(finalScore);
end
%% 测试分类器
function accuracy = testClassifier(classifiers, alphas, features, labels)
predictions = predictStrongClassifier(classifiers, alphas, features);
accuracy = mean(predictions == labels);
end
%% 图像中的人脸检测
function testImageDetection(classifiers, alphas, trainingSize)
% 读取测试图像
try
testImg = imread('test_face.jpg');
catch
% 如果没有测试图像,创建示例图像
testImg = createSampleTestImage();
end
if size(testImg, 3) == 3
testImg = rgb2gray(testImg);
end
testImg = im2double(testImg);
figure;
subplot(1, 2, 1);
imshow(testImg);
title('原始图像');
% 多尺度检测
scales = 0.8:0.1:1.5;
detectedFaces = [];
for scale = scales
scaledImg = imresize(testImg, scale);
[height, width] = size(scaledImg);
windowSize = trainingSize;
% 滑动窗口检测
for y = 1:2:height - windowSize(1)
for x = 1:2:width - windowSize(2)
window = scaledImg(y:y+windowSize(1)-1, x:x+windowSize(2)-1);
% 提取特征并分类
features = window(:)';
prediction = predictStrongClassifier(classifiers, alphas, features);
if prediction == 1
% 转换回原始图像坐标
origX = round(x / scale);
origY = round(y / scale);
origWidth = round(windowSize(2) / scale);
origHeight = round(windowSize(1) / scale);
detectedFaces = [detectedFaces; origX, origY, origWidth, origHeight];
end
end
end
end
% 显示检测结果
subplot(1, 2, 2);
imshow(testImg);
title('人脸检测结果');
hold on;
% 非极大值抑制
if ~isempty(detectedFaces)
keptFaces = nonMaxSuppression(detectedFaces);
for i = 1:size(keptFaces, 1)
face = keptFaces(i, :);
rectangle('Position', face, 'EdgeColor', 'r', 'LineWidth', 2);
end
end
fprintf('检测到 %d 个人脸\n', size(keptFaces, 1));
end
%% 非极大值抑制
function keptBoxes = nonMaxSuppression(boxes, threshold)
if nargin < 2
threshold = 0.3;
end
if isempty(boxes)
keptBoxes = [];
return;
end
x = boxes(:, 1);
y = boxes(:, 2);
w = boxes(:, 3);
h = boxes(:, 4);
areas = w .* h;
[~, order] = sort(areas, 'descend');
kept = true(size(boxes, 1), 1);
for i = 1:length(order)
if ~kept(order(i))
continue;
end
for j = i+1:length(order)
if ~kept(order(j))
continue;
end
box1 = [x(order(i)), y(order(i)), w(order(i)), h(order(i))];
box2 = [x(order(j)), y(order(j)), w(order(j)), h(order(j))];
intersectionArea = rectint(box1, box2);
unionArea = areas(order(i)) + areas(order(j)) - intersectionArea;
overlap = intersectionArea / unionArea;
if overlap > threshold
kept(order(j)) = false;
end
end
end
keptBoxes = boxes(kept, :);
end
%% 创建示例测试图像
function sampleImg = createSampleTestImage()
sampleImg = zeros(200, 200);
% 添加多个人脸模式
face1 = generateFacePattern([40, 40]);
sampleImg(30:69, 50:89) = face1;
face2 = generateFacePattern([35, 35]);
sampleImg(100:134, 120:154) = face2;
% 添加噪声
sampleImg = sampleImg + 0.1 * randn(200, 200);
sampleImg = im2uint8(mat2gray(sampleImg));
end
三、代码说明
3.1 主要函数
- generateTrainingData: 生成训练数据(实际应用中应从真实数据集加载)
- trainAdaBoost: AdaBoost主训练函数
- trainWeakClassifier: 训练弱分类器(决策树桩)
- testImageDetection: 在图像中进行多尺度人脸检测
3.2 关键特点
- 多尺度检测: 在不同尺度下搜索人脸
- 滑动窗口: 使用滑动窗口遍历图像
- 非极大值抑制: 消除重叠的检测框
3.3 使用建议
- 使用真实的人脸数据集(如LFW、FDDB)替换模拟数据
- 使用积分图加速Haar特征计算
- 实现真正的Haar-like特征提取
- 使用更复杂的弱分类器结构
参考代码 基于AdaBoost算法的人脸检测原理+matlab代码 www.youwenfan.com/contentcnl/65477.html
这个实现展示了AdaBoost人脸检测的基本原理,在实际应用中需要结合OpenCV等库的优化实现以获得更好的性能。

浙公网安备 33010602011771号