基于机器学习的目标检测方法详解
在计算机视觉领域,目标检测是一个重要的研究方向,它涉及到识别图像或视频中特定类别的目标。本文将详细介绍两种常用的目标检测方法:基于Haar特征的级联分类器和基于支持向量机(SVM)与方向梯度直方图(HOG)的分类器。
基于Haar特征的级联分类器
级联分类器的核心思想
级联分类器背后有两个核心思想。首先,一个强分类器可以通过组合多个弱分类器(基于简单特征)来构建。其次,在机器视觉中,负样本比正样本更常见,因此可以分阶段进行有效的分类。早期阶段快速排除明显的负样本,后期阶段对更难的样本做出更精确的决策。
学习算法的基本步骤
- 特征选择 :使用Haar特征构建弱分类器。当应用一个特定类型、大小和位置的Haar特征时,会得到一个值。通过找到基于该特征值对正负样本进行最佳分类的阈值,得到一个简单分类器。
- 迭代构建弱分类器 :由于有大量可能的Haar特征,我们会检查所有特征并选择对样本集分类效果最好的特征。显然,这种基本分类器会产生错误,因此需要迭代地构建多个这样的分类器。每次迭代时,我们会关注当前被错误分类的样本,通过给这些样本更高的权重来衡量分类性能。
- 构建强分类器 :通过对这些弱分类器进行加权求和,得到一个强分类器,性能更好的分类器会被赋予更高的权重。通过组合几百个简单特征,可以得到性能良好的强分类器。
级联分类器的训练参数
在训练级联分类器时,需要设置一些重要的参数:
| 参数 | 含义 | 默认值 |
| ---- | ---- | ---- |
| -numPos | 正样本数量 | 无 |
| -numNeg | 负样本数量 | 无 |
| -minHitRate | 最小命中率 | 0.995 |
| -maxFalseAlarmRate | 最大误报率 | 0.5 |
| -maxWeakCount | 每阶段最大弱分类器数量 | 100 |
| -numStages | 阶段数量 | 20 |
训练过程中的注意事项
- 早期拒绝机制 :为了实现早期拒绝,我们需要找到只使用少量Haar特征的小分类器,以便快速排除明显的负样本,同时保留所有正样本。
- 性能标准 :在训练每个阶段时,需要设置最小命中率和最大误报率两个标准。最小命中率应设置得较高,以确保正样本能够进入下一阶段;最大误报率应相对较高,以促进生成低复杂度的分类器。
- 负样本收集 :在新的阶段开始训练时,需要从提供的背景图像中提取新的负样本。这些负样本应该是能够通过所有先前阶段的样本,因此提供多样化的背景图像非常重要。
全局性能分析
一个由n个阶段组成的级联分类器,其全局性能至少优于每个阶段的最小命中率的n次方和最大误报率的n次方。例如,使用默认参数时,分类器的准确率(命中率)为0.995的20次方,误报率为0.5的20次方,即90%的正样本将被正确识别,0.001%的负样本将被错误分类为正样本。
样本数量的选择
训练时使用的样本数量是一个重要问题。正样本集必须足够大,以覆盖目标类别的各种可能外观。背景图像也应该相关。通常的经验法则是负样本数量是正样本数量的2倍,但这需要在自己的数据集上进行验证。
使用预训练级联分类器进行人脸检测
OpenCV库提供了许多预训练的级联分类器,可用于检测人脸、面部特征、人等。以下是使用Haar级联分类器进行人脸检测的示例代码:
cv::CascadeClassifier faceCascade;
if (!faceCascade.load("haarcascade_frontalface_default.xml")) {
std::cout << "Error when loading the face cascade classifier!" << std::endl;
return -1;
}
// 检测人脸
std::vector<cv::Rect> detections;
faceCascade.detectMultiScale(picture, detections, 1.1, 3, 0, cv::Size(48, 48), cv::Size(128, 128));
// 在图像上绘制检测结果
for (int i = 0; i < detections.size(); i++)
cv::rectangle(picture, detections[i], cv::Scalar(255, 255, 255), 2);
基于支持向量机(SVM)与方向梯度直方图(HOG)的分类器
方向梯度直方图(HOG)
图像的目标主要由其形状和纹理内容来表征,这正是方向梯度直方图(HOG)表示所捕捉的方面。HOG表示基于从图像梯度构建直方图,特别是分析梯度方向的分布。为了考虑梯度的空间分布,会在将图像划分为多个区域的网格上计算多个直方图。
HOG表示的构建步骤
- 计算图像梯度 :首先计算图像的梯度。
- 划分单元格并构建直方图 :将图像细分为小单元格(例如8×8像素),并为每个单元格构建梯度方向直方图。通常只考虑梯度方向而不考虑其方向(无符号梯度),将可能的方向范围划分为多个区间(例如9个区间,每个区间20度)。每个单元格中的梯度向量根据其幅度为相应的区间贡献权重。
- 分组为块并归一化 :将单元格分组为块,块可以重叠。例如,由2×2个单元格组成的块,块步长为1个单元格时,每个单元格(除了每行的最后一个)将对2个块有贡献。将块内的单元格直方图连接成一个长向量,并进行归一化处理,以使其对对比度变化具有不变性。
- 连接所有块的向量 :最后将图像中所有块的向量连接成一个非常大的向量,该向量表征了图像,可以用于对不同类别的图像进行分类。
使用SVM和HOG构建分类器的步骤
- 样本收集 :收集用于训练的正样本和负样本。
- HOG描述符计算 :使用HOG描述符表示样本。例如,使用由2×2个单元格组成的8×8块,块步长为1个单元格,9个区间的直方图。对于64×64的样本,这种配置会产生大小为8100的HOG向量。
cv::HOGDescriptor hogDesc(positive.size(), cv::Size(8, 8), cv::Size(4, 4), cv::Size(4, 4), 9);
std::vector<float> desc;
hogDesc.compute(positives[0], desc);
int featureSize = desc.size();
int numberOfSamples = positives.size() + negatives.size();
cv::Mat samples(numberOfSamples, featureSize, CV_32FC1);
for (int i = 0; i < featureSize; i++)
samples.ptr<float>(0)[i] = desc[i];
for (int j = 1; j < positives.size(); j++) {
hogDesc.compute(positives[j], desc);
for (int i = 0; i < featureSize; i++)
samples.ptr<float>(j)[i] = desc[i];
}
for (int j = 0; j < negatives.size(); j++) {
hogDesc.compute(negatives[j], desc);
for (int i = 0; i < featureSize; i++)
samples.ptr<float>(j + positives.size())[i] = desc[i];
}
- 标签矩阵创建 :创建一个矩阵来包含每个样本的标签,正样本标签为1,负样本标签为-1。
cv::Mat labels(numberOfSamples, 1, CV_32SC1);
labels.rowRange(0, positives.size()) = 1.0;
labels.rowRange(positives.size(), numberOfSamples) = -1.0;
- SVM分类器创建与训练 :创建SVM分类器并选择SVM类型和核函数。
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
svm->setType(cv::ml::SVM::C_SVC);
svm->setKernel(cv::ml::SVM::LINEAR);
cv::Ptr<cv::ml::TrainData> trainingData = cv::ml::TrainData::create(samples, cv::ml::SampleTypes::ROW_SAMPLE, labels);
svm->train(trainingData);
- 测试分类器 :将未知类别的样本提交给分类器,预测其所属类别。
cv::Mat queries(4, featureSize, CV_32FC1);
hogDesc.compute(cv::imread("stop08.png", cv::IMREAD_GRAYSCALE), desc);
for (int i = 0; i < featureSize; i++)
queries.ptr<float>(0)[i] = desc[i];
hogDesc.compute(cv::imread("stop09.png", cv::IMREAD_GRAYSCALE), desc);
for (int i = 0; i < featureSize; i++)
queries.ptr<float>(1)[i] = desc[i];
hogDesc.compute(cv::imread("neg08.png", cv::IMREAD_GRAYSCALE), desc);
for (int i = 0; i < featureSize; i++)
queries.ptr<float>(2)[i] = desc[i];
hogDesc.compute(cv::imread("neg09.png", cv::IMREAD_GRAYSCALE), desc);
for (int i = 0; i < featureSize; i++)
queries.ptr<float>(3)[i] = desc[i];
cv::Mat predictions;
svm->predict(queries, predictions);
for (int i = 0; i < 4; i++)
std::cout << "query: " << i << ": " << ((predictions.at<float>(i,) < 0.0)? "Negative" : "Positive") << std::endl;
SVM的工作原理
在我们的停车标志识别示例中,每个样本在8100维的HOG空间中表示为一个点。支持向量机的思想是在这个空间中绘制一个边界,将属于一个类别的点与属于另一个类别的点分开。这个边界实际上是一个简单的超平面。
在二维空间中,超平面是一条简单的线。然而,在实际应用中,我们通常处理的是高维空间。为了选择最佳的超平面,我们希望它能够在未来的实例上做出最佳决策,即具有良好的泛化能力。SVM通过最大化定义边界周围的间隔来实现这一点,间隔定义为分隔超平面与正样本集中最近点的最小距离加上超平面与负样本集中最近点的距离。最近的点(定义间隔的点)称为支持向量。
当样本点的分布不能用简单的超平面分开时,SVM通过引入人工变量,通过非线性变换将问题转换到更高维的空间中。为了避免显式地将所有点转换到新空间,SVM定义了核函数,允许在更高维空间中测量点到超平面的距离,而无需显式计算点在该空间中的坐标。
在处理高维特征时,样本可能可以用简单的超平面分开,因此使用线性核(cv::ml::SVM::LINEAR)并在原始特征空间中工作仍然是有意义的。
综上所述,基于Haar特征的级联分类器和基于SVM与HOG的分类器都是有效的目标检测方法,它们各有优缺点,可以根据具体的应用场景选择合适的方法。
两种分类器的对比与应用场景分析
两种分类器的特点对比
| 分类器类型 | 优点 | 缺点 |
|---|---|---|
| 基于Haar特征的级联分类器 | 训练速度相对较快,对于特定目标(如人脸)检测效果较好,能够利用早期拒绝机制快速排除大量负样本,计算效率较高。 | 需要大量的正负样本进行训练,对背景图像的多样性要求较高,对于复杂场景下的目标检测效果可能不佳。 |
| 基于SVM与HOG的分类器 | 能够处理高维特征,对于复杂形状和纹理的目标检测具有较好的鲁棒性,在处理非线性可分问题时可以通过核函数进行转换。 | 训练时间较长,计算复杂度较高,对样本的质量和代表性要求较高。 |
应用场景分析
- 基于Haar特征的级联分类器 :适用于目标相对固定、背景相对简单的场景,如人脸检测、特定标志检测等。在这些场景中,由于目标的特征相对稳定,Haar特征能够较好地捕捉目标的特征,并且早期拒绝机制可以快速提高检测效率。
- 基于SVM与HOG的分类器 :适用于目标形状和纹理复杂、背景多变的场景,如行人检测、车辆检测等。在这些场景中,HOG能够有效地描述目标的形状和纹理特征,SVM能够在高维空间中找到最优的分类边界,从而实现准确的目标检测。
流程图:目标检测方法选择
graph TD;
A[目标检测任务] --> B{目标特征是否固定};
B -- 是 --> C{背景是否简单};
C -- 是 --> D[基于Haar特征的级联分类器];
C -- 否 --> E[基于SVM与HOG的分类器];
B -- 否 --> E[基于SVM与HOG的分类器];
实际应用中的优化建议
基于Haar特征的级联分类器优化
- 样本选择 :确保正样本集覆盖目标的各种可能外观,负样本集包含多样化的背景图像。可以通过数据增强的方法增加样本的多样性,如旋转、缩放、翻转等。
- 参数调整 :根据实际应用场景调整训练参数,如最小命中率、最大误报率、每阶段最大弱分类器数量和阶段数量等。可以通过交叉验证的方法选择最优的参数组合。
- 多尺度检测 :在不同尺度上对图像进行检测,以提高对不同大小目标的检测能力。可以通过调整检测窗口的大小和步长来实现多尺度检测。
基于SVM与HOG的分类器优化
- 特征选择 :除了HOG特征外,可以结合其他特征,如颜色特征、纹理特征等,以提高分类器的性能。可以通过特征选择算法选择最具代表性的特征。
- 核函数选择 :根据样本的分布情况选择合适的核函数,如线性核、多项式核、高斯核等。可以通过实验比较不同核函数的性能,选择最优的核函数。
- 模型融合 :可以将多个SVM分类器进行融合,以提高分类器的鲁棒性和准确性。可以通过投票、平均等方法进行模型融合。
总结
本文详细介绍了基于Haar特征的级联分类器和基于SVM与HOG的分类器这两种常用的目标检测方法。通过对它们的原理、构建步骤、工作机制的介绍,以及特点对比和应用场景分析,我们可以看出这两种方法各有优缺点。在实际应用中,需要根据具体的目标检测任务和场景,选择合适的方法,并通过优化建议进一步提高检测性能。
同时,随着计算机视觉技术的不断发展,新的目标检测方法也在不断涌现,如深度学习方法。这些方法在准确性和鲁棒性方面取得了显著的进展,但也面临着计算资源需求大、训练数据要求高等问题。因此,在实际应用中,需要综合考虑各种因素,选择最适合的方法来实现目标检测任务。
希望本文能够为读者在目标检测领域的研究和应用提供有价值的参考。
超级会员免费看
9234

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



