一、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:posSamplesimg = generateFacePattern(imgSize);features(i, :) = img(:);labels(i) = 1;end% 生成负样本(随机纹理)for i = posSamples+1:totalSamplesimg = 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) == 0fprintf('已完成 %d/%d 个弱分类器训练\n', t, numClassifiers);endend
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:numFeaturesToTryfeatureIdx = featureIndices(i);featureValues = features(:, featureIdx);% 尝试不同的阈值thresholds = linspace(min(featureValues), max(featureValues), 20);for threshold = thresholdsfor polarity = [-1, 1]% 计算预测结果predictions = polarity * (2*(featureValues > threshold) - 1);% 计算加权误差error = sum(weights .* (predictions ~= labels));if error < bestErrorbestError = error;bestClassifier.featureIdx = featureIdx;bestClassifier.threshold = threshold;bestClassifier.polarity = polarity;endendendendweakClassifier = 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:nClassifiersweakPredictions = predictWeakClassifier(classifiers{t}, features);finalScore = finalScore + alphas(t) * weakPredictions;endpredictions = 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)% 读取测试图像trytestImg = imread('test_face.jpg');catch% 如果没有测试图像,创建示例图像testImg = createSampleTestImage();endif size(testImg, 3) == 3testImg = rgb2gray(testImg);endtestImg = im2double(testImg);figure;subplot(1, 2, 1);imshow(testImg);title('原始图像');% 多尺度检测scales = 0.8:0.1:1.5;detectedFaces = [];for scale = scalesscaledImg = 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];endendendend% 显示检测结果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);endendfprintf('检测到 %d 个人脸\n', size(keptFaces, 1));
end%% 非极大值抑制
function keptBoxes = nonMaxSuppression(boxes, threshold)if nargin < 2threshold = 0.3;endif isempty(boxes)keptBoxes = [];return;endx = 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;endfor j = i+1:length(order)if ~kept(order(j))continue;endbox1 = [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 > thresholdkept(order(j)) = false;endendendkeptBoxes = 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等库的优化实现以获得更好的性能。