当前位置: 首页 > news >正文

嵌入式人工智能应用-第三章 opencv操作8 图像特征之 Haar 特征

1 Haar 特征

Haar 特征”(Haar Features)是一种在计算机视觉中常用的特征,用于图像识别任务,尤其是在 人脸检测 中非常著名。这个概念最初由 Paul Viola 和 Michael Jones 在 2001 年提出,他们提出的基于 Haar 特征和 AdaBoost 的级联分类器方法实现了非常高效的人脸检测

1.1 背景介绍

Haar-like 特征最早是由 Papageorgiou 等应用于人脸表示,Viola 和 Jones 在此基础上,使用 3 种类型 4种形式的特征。

Haar 特征分为三类:边缘特征、线性特征、中心特征和对角线特征,组合成特征模板。

  1. 边缘特征(Edge Features)
    比如:一个白色矩形和一个相邻的黑色矩形。
    用于检测亮度突然变化的位置,例如眼睛的上下边缘。
    2.线条特征(Line Features):
    比如:白-黑-白 三个矩形排列,用来检测图像中的线条结构。
  2. 中心-周围特征(Center-surround Features):
    比如:中间一个矩形区域和它周围一圈区域做差值,检测人脸中央区域和边缘区域的亮度差异。

特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白 色矩形像素和减去黑色矩形像素和。Haar 特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。
在这里插入图片描述
对于图中的 A, B 和 D 这类特征,特征数值计算公式为:v=Sum 白-Sum 黑,而对于 C 来说,计算公式如下:v=Sum 白-2Sum 黑;之所以将黑色区域像素和乘以 2,是为了使两种矩形区域中像素数目一致。通过改变特征模板的大小和位置,可在图像子窗口中穷举出大量的特征。上图的特征模板称为“特征原型”;特征原型在图像子窗口中扩展(平移伸缩)得到的特征称为“矩形特征”;矩形特征的值称为“特征值”。
矩形特征可位于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征,如:在 24
24 像素大小的检测窗口内矩形特征数量可以达到 16 万个。这样就有两个问题需要解决了:
(1)如何快速计算那么多的特征?积分图
(2)哪些矩形特征才是对分类器分类最有效的?通
过 AdaBoost 算法来训练。积分图就是只遍历一次图像就可以求出图像中所有区域像素和的快速算法,大大的提高了图像特征值计算的效率。积分图主要的思想是将图像从起点开始到各个点所形成的矩形区域像素之和作为一个数组的元素保存在内存中,当要计算某个区域的像素和时可以直接索引 数组的元素,不用重新计算这个区域的像素和,从而加快了计算(这有个相应的称呼,叫做动态规划算法)。积分图能够在多种尺度下,使用相同的时间(常数时 间)来计算不同的特征,因此大大提高了检测速度。

1.2 如何计算 Haar 特征?

1.首先将图像转为灰度。

2.利用 积分图(Integral Image) 快速计算任意矩形区域的像素和。

  1. 将 Haar 特征应用到图像的不同位置和尺度,提取出大量特征。

  2. 使用 AdaBoost 算法 选择最有效的一小部分特征,并训练成一个分类器。

2 Haar 特征

  1. 计算积分图(Integral Image)

  2. 计算 Haar 特征,比如边缘、线条等。

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;// 计算积分图
void computeIntegralImage(const Mat& src, Mat& integralImage) {integral(src, integralImage, CV_32S);
}// 计算 Haar 特征(简单的边缘特征举例)
int computeHaarFeature(const Mat& integralImage, int x, int y, int width, int height) {// 假设 Haar 特征是一个横向的边缘特征,计算两个矩形区域的像素和差异int topLeft = integralImage.at<int>(y, x);int topRight = integralImage.at<int>(y, x + width);int bottomLeft = integralImage.at<int>(y + height, x);int bottomRight = integralImage.at<int>(y + height, x + width);// 计算矩形区域的差异(边缘特征)int featureValue = (topLeft + bottomRight) - (topRight + bottomLeft);return featureValue;
}int main() {// 加载图像并转换为灰度图Mat img = imread("face.jpg", IMREAD_GRAYSCALE);if (img.empty()) {cout << "Image not found!" << endl;return -1;}// 计算积分图Mat integralImg;computeIntegralImage(img, integralImg);// 计算 Haar 特征(例如边缘特征)int x = 50, y = 50; // 特征计算的起始坐标int width = 20, height = 10; // 特征矩形区域的宽度和高度int haarFeature = computeHaarFeature(integralImg, x, y, width, height);cout << "Haar Feature Value: " << haarFeature << endl;// 可视化积分图Mat visualized;normalize(integralImg, visualized, 0, 255, NORM_MINMAX);visualized.convertTo(visualized, CV_8U);imshow("Integral Image", visualized);waitKey(0);return 0;
}
  1. 计算积分图:integral() 函数计算出图像的积分图,帮助你快速计算任意矩形区域的像素和。积分图可以让你在常数时间内得到任意矩形区域的和。

  2. 计算 Haar 特征:假设我们计算一个简单的横向边缘特征,即通过两个矩形区域的像素和差异来区分图像中物体的边缘。

  3. 在代码中,computeHaarFeature 计算的是一个简化的 Haar 特征(两个矩形区域差异)。你可以根据需要扩展更多类型的 Haar 特征,如垂直边缘、中心-周围差异等。

  4. 可视化积分图:最后我们用 imshow() 来显示积分图,帮助你理解积分图的效果。
    在这里插入图片描述

3 人脸检测

3.1 步骤

  1. 创建一个 Haar 级联分类器对象
  2. 加载 OpenCV 提供的人脸检测模型文件(基于 Haar 特征训练的 XML)
  3. 把彩色图像 frame 转为灰度图,因为 Haar 特征只需要灰度,不处理颜色。

3.2 函数介绍

face_cascade.detectMultiScale(frame_gray,   // 输入图像faces,        // 输出检测到的人脸位置1.1,          // 缩放比例(每次图像缩小的比例)4,            // 最小邻近框数(越大越严格)0,            // 标志位,一般为0Size(30,30)   // 最小检测窗口大小
);

3.3 具体代码实现

		CascadeClassifier face_cascade;                                                                                                                57     face_cascade.load("//usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml");58 59     Mat frame = imread(argv[1]);60     if (frame.empty()) {61         cout << "Image not found!" << endl;62         return -1;63     }64 65     Mat frame_gray;66     cvtColor(frame, frame_gray, COLOR_BGR2GRAY);67     equalizeHist(frame_gray, frame_gray);  // 🌟 提高对比度(可选,但提升检测准确率)68 69     vector<Rect> faces;70     face_cascade.detectMultiScale(frame_gray, faces, 1.1, 4, 0, Size(30, 30));71 72     for (size_t i = 0; i < faces.size(); i++) {73         rectangle(frame, faces[i], Scalar(255, 0, 0), 2);74     }75 76     imshow("Detected Faces", frame);77     waitKey(0);78     return 0; 79     waitKey(0);80     return 0;

在这里插入图片描述

4 特点

✅ 优点
非常快,适合实时应用。

对亮度变化不敏感。

❌ 缺点
对复杂背景或光照变化不太鲁棒。

相比于深度学习方法,准确率较低。

相关文章:

  • 整平机:精密制造的“隐形守护者”
  • 使用PyTorch如何配置一个简单的GTP
  • Window11系统删除掉你需要TrustedInstaller提供的权限才能对此文件进行更改的文件(图文详解)
  • TensorFlow Keras“安全模式”真的安全吗?绕过 safe_mode 缓解措施,实现任意代码执行
  • Java的进阶学习
  • 理想MindVLA学习解读
  • 豆包桌面版 1.47.4 可做浏览器,免安装绿色版
  • QT创建软件登录界面(14)
  • 【MQ篇】初识RabbitMQ保证消息可靠性
  • Freertos----中断管理
  • Visual Studio Code 使用tab键往左和往右缩进内容
  • 水域陆地两相宜,便携漏电探测仪
  • 大数据驱动公共交通系统的智慧化革命
  • React19源码阅读之commitRoot
  • 架构-系统工程与信息系统基础
  • 提升内容创作效率:AI原创文章批量生成工具优势
  • CentOS 7.9升级OpenSSH到9.9p2
  • 专家系统的一般结构解析——基于《人工智能原理与方法》的深度拓展
  • DRF凭什么更高效?Django原生API与DRF框架开发对比解析
  • 要从给定的数据结构中提取所有的 itemList 并将其放入一个新的数组中
  • 中国与肯尼亚签署共同发展经济伙伴关系框架协定
  • 魔都眼·上海车展⑤|被主播包围的新车
  • 华夏银行青岛分行另类处置不良债权,德州近百亩土地被神奇操作抵押贷款
  • 南宁市委常委、组织部部长陈川已任广西医科大学党委书记
  • 凯撒旅业:2024年营业收入约6.53亿元,同比增长12.25%
  • 我国翻译从业人员达680.8万人,行业总需求仍在上升