惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
PCI Perspectives
PCI Perspectives
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google Online Security Blog
Google Online Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The GitHub Blog
The GitHub Blog
S
Secure Thoughts
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
WordPress大学
WordPress大学
SecWiki News
SecWiki News
B
Blog
小众软件
小众软件
Hacker News - Newest:
Hacker News - Newest: "LLM"
Webroot Blog
Webroot Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
L
LINUX DO - 热门话题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
F
Fortinet All Blogs
W
WeLiveSecurity
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
The Last Watchdog
The Last Watchdog
S
Schneier on Security
爱范儿
爱范儿
V
V2EX - 技术
L
LINUX DO - 最新话题
月光博客
月光博客
博客园 - 【当耐特】
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志
博客园 - 司徒正美
U
Unit 42
Schneier on Security
Schneier on Security
E
Exploit-DB.com RSS Feed
J
Java Code Geeks
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss
TaoSecurity Blog
TaoSecurity Blog
博客园 - 叶小钗
T
Troy Hunt's Blog
大猫的无限游戏
大猫的无限游戏
AI
AI
Security Latest
Security Latest

又见苍岚

COLMAP PatchMatch Stereo 算法详解 事件驱动的状态机框架:从理论到工程实践 Git 在国内网络环境下无法 Push 的排查与修复 —— 配置 Clash 代理 分段五次多项式插值原理详解 路径插值方法深度对比研究 Claude Code 使用指南 OpenClaw 记忆管理与技能创建指南 CBS(Conflict-Based Search)算法详解 A* 算法及其变种详解 OpenClaw 配置多 Agents Windows Powershell 无法加载文件,因为在此系统上禁止运行脚本问题的解决方案 MaxClaw 安装流程 大模型 AI 名词介绍 AList 网盘聚合工具简介 Protobuf 简介与测试 Claude Code 简介以及 GLM 4.7 模型接入 Github 歌词下载工具 163MusicLyrics Python __getattr__ 懒加载 Python TypedDict 机器人仿真平台 Gazebo 安装记录 机器人仿真平台 Gazebo 简介 多机器人路径规划问题(Multi-Agent Path Finding, MAPF)简介 Python exifread 读取修改过的 jpeg 信息错误问题修复 3D 坐标系变换的理解 3D 旋转矩阵基本概念 MongoDB Compass 介绍 Python 环境管理工具 uv Flutter 开发指南 Snipaste 安装下载与黑屏问题解决方案 全局路径规划算法记录 2025 Python 版本性能测试 Flutter Hello World Flutter 安装环境配置 Ubuntu VMware 硬盘扩容后 SMBus Host controller not enabled 报错问题解决 Python NetworkX 教程 Docker GPU 报错 - Failed to initialize NVML Unknown Error 解决方案 Python matplotlib 图表绘制 cuda-toolkit 安装替代 Cuda 与 Cudnn Jinja2 Python 利用 docxtpl 和 Jinja2 生成基于模板的 Word 文档 Docker 实现 CPU 核心隔离 LoFTR 基于 Transformer 的特征提取匹配算法 OmniGlue 特征匹配 SuperGlue 使用图神经网络学习特征匹配 Ubuntu 下将 xlsx 文件按照 sheet 转换为 图片 Python 使用 SQLAlchemy Python FastAPI 教程 openwrt 软路由配置安装 Nav2 地图文件(PGM/YAML)规范标准 3D OBJ 模型转换为 glb 瓦片格式 Python 源码 Redis 数据库介绍 Ubuntu 22.04 内核自动升级导致 MongoDB 7.0.12 错误记录 ubuntu 20.04 安装 ROS Noetic ubuntu 18.04 安装 ROS Melodic VMware Workstation Pro 个人免费版下载、安装、使用指南 Hybrid A-star 路径规划 Reeds-Shepp 曲线 Dubins 曲线 Linux kvm 虚拟机网络不通的问题解决方法 Ubuntu 自动内存清理 BiliBili 缓存视频转 mp4 Python 求解线性规划 3D Gaussian Splatting 官方源码实践记录 ImageMagick 教程 Ubuntu 22.04 安装 Colmap 对数几率 odds Ubuntu nmcli 网络管理工具使用指南 SuperPoint 自监督深度学习特征点提取 SyncTV Music Tag Web 在线音乐信息整理工具 ncm 格式转 mp3 MusicBrainz 音乐元数据百科数据库 Ubuntu 网络流量监控工具 私人云音乐平台 Navidrome 入门 手眼标定 四元数(Quaternions) OHTTPS 实现免费自动 https 证书申请、更新、部署 ubuntu 22.04 安装 CloudCompare 单机 KVM 虚拟机冷迁移 Ubuntu 22.04 使用 mdadm 实现软 raid 小鱼 一键安装 ROS-humble Fluid -46- 基于 Simpletex API 构建公式识别页面 公式识别 API 简介 -- Simpletex 使用 Python web 部署库 waitress 3D Gaussian Splatting for Real-Time Radiance Field Rendering Ubuntu Swap 简介与空间扩展 Ubuntu 24.04 安装 forticlient Clash Verge 使用 MongoDB 7.0.17 集群 Docker 构建源码 Error code - 2013. Lost connection to MySQL server during query 问题解决 Python 日志记录库 loguru 使用指北 Python 实现 Web 日志查看服务 MySQL LOAD DATA LOCAL INFILE 极速数据加载 Image size exceeds limit of 89478485 pixels 解决方案 Docker 使用 NVIDIA GPU 驱动错误解决 阿里云 docker 镜像仓库 Ubuntu中没有wired connected的解决方案 MinIO 简介 subconverter 代理订阅格式转换 修复 node –openssl-legacy-provider is not allowed in NODE_OPTIONS 错误
图像方向梯度直方图 HOG 特征
Yiwei Zhang · 2022-10-08 · via 又见苍岚

HOG全称histogram of oriented gradients.如果翻译成中文就是方向梯度直方图。它可以用来表示图像的物体特征,因此能够检测出这类物体。。

简介

  • 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。

  • 特征在对象识别与模式匹配中是一种常见的特征提取算法,是基于本地像素块进行特征直方图提取的一种算法,对象局部的变形与光照影响有很好的稳定性。

  • 它通过计算和统计图像局部区域的梯度方向直方图来构成特征。Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。

  • 论文链接:Histogram of oriented gradients for human detection

主要思想

  • HOG 的本质是 梯度的统计信息
  • 在一副图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。

核心步骤

HOG特征提取算法的过程主要分为四大步骤:

  1. 输入图像,对图像进行颜色空间的归一化;
  2. 计算图像的梯度;
  3. 为每个cell单元构建梯度方向直方图
  4. 把cell单元组合成block,块内归一化梯度直方图。

优点

  • 由于HOG是在图像的局部方格单元上操作,所以它对图像几何的和光学的形变都能保持很好的不变性,这两种形变只会出现在更大的空间领域上。
  • 在粗的空域抽样、精细的方向抽样以及较强的局部光学归一化等条件下,只要行人大体上能够保持直立的姿势,可以容许行人有一些细微的肢体动作,这些细微的动作可以被忽略而不影响检测效果。

梯度方向

  • 梯度方向指的是图像梯度的方向或朝向。Hog就是一张有关图像梯度方向的直方图。首先HOG会接受一张图像,然后计算每个像素的梯度幅度和方向

  • 获取梯度方向后 HOG 根据特征角度统计直方图

HOG 特征提取

图像预处理

Gamma矫正

可选操作

  • 为了减少光照因素的影响,首先需要将整个图像进行归一化。由于在图像纹理强度中,局部的表层曝光贡献的比重较大,所以进行Gamma归一化处理,可以有效地降低图像局部阴影和光照的变化,还可以抑制噪音的干扰。
  • 常用的 Gamma 归一化处理可以是:
    1. 对每个颜色通道分别计算平方根
    2. 对每个颜色通道分别求log
灰度化

可选操作

  • 灰度化是将彩色图片变成灰度图。其实彩色图片也可以直接处理。不过是分别对三通道的颜色值进行梯度计算,最后选择梯度最大的那个。

计算图像梯度

  • 计算图像的梯度主要是为了通过梯度信息来描述图像中物体的边缘、轮廓、形状等纹理信息。在这个步骤中,首先需要计算图像的横纵坐标方向的梯度,然后根据计算出的图像横坐标和纵坐标方向梯度算出每个像素位置的梯度方向值。
  • 假设一张图像中像素点用$(x,y)$表示,则该像素点的水平梯度和垂直梯度分别为$G_x(x,y)$和$G_y(x,y)$,计算如公式如下:

$$ \begin{array}{c} G_{x}(x, y)=H(x+1, y)-H(x-1, y) \\ G_{y}(x, y)=H(x, y+1)-H(x, y-1) \end{array} $$

  • 其中$H(x,y)$表示输入的图像在像素点(x,y)的像素值。根据得到的像素点水平梯度和垂直梯度就可以得到图像中素点$(x,y)$处的梯度幅值$G(x,y)$和梯度方向$α(x,y)$如下所示:

$$ \begin{array}{c} G(x, y)=\sqrt{G(x, y)^{2}+G_{y}(x, y)^{2}} \\ \alpha(x, y)=\tan ^{-1}\left(\frac{G_{y}(x, y)}{G_{x}(x, y)}\right) \end{array} $$

Opencv 实现
  • 使用 Opencv 中的 sobel 算子可以出水平和垂直方向的梯度:
1
2
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=1)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=1)
  • 利用公式求取梯度幅值和方向:
  • Opencv 中使用 cartToPolar 可以计算角度:
1
mag, angle = cv2.cartToPolar(gx, gy, angleInDegrees=True)

为每个cell单元构建梯度方向直方图

此步骤主要是为局部图像区域提供一个编码,同时能够保持对图像中人体对象的姿势和外观的弱敏感性。

  • 首先将图像划分成若干个块(Block),每个块又由若干个细胞单元(cell)组成,细胞单元由更小的单位像素(Pixel)组成,然后把所有cell单元的全部像素通过梯度方向在直方图中执行加权投影的操作,则可获得每个cell单元格的梯度方向直方图。

计算算例

  • 按照梯度计算的结果,每一个像素点都会有两个值:梯度强度/梯度方向。

  • 梯度直方图是在一个 $8\times8$ 的cell里面计算的。那么在8*8的cell里面就会有 $8\times8\times2=128$ 个值(2 是包括了梯度强度和梯度方向)。

  • 通过统计形成梯度直方图,128 个值将会变成 9 个值,大大降低了计算量,同时又对光照等环境变化更加地robust。

计算方法
  • 首先,将 $0-180$ 度分成 9 个bins,分别是 $0,20,40…160$。然后统计每一个像素点所在的 bin。
  • 根据梯度方向选择当前梯度会投影在哪个bin 里,根据梯度方向距 bin 的距离加权分配梯度强度值到对应的 bin 中

  • 左上图是 $8\times8$ 的梯度方向值,右上图是 $8\times8$ 的梯度强度值,下图是 9 个bins。

  • 蓝色圈圈: 蓝圈的方向是 80 度,大小是 2,所以该点就将梯度强度 —— 2 投给 80 这 个bin;

  • 红色圈圈: 红色圈圈的方向是10,大小是4,因为 10 距 0 度的 bin距离 为10,距 20度的 bin 距离也为10,那么有一半的大小是投给 0-bin,还有一半的大小(即是2)投给20-bin。

统计直方图
  • 那么统计完64个点的投票数以后,每个bin就会得到一个数值,可以得到一个直方图,在计算机里面就是一个大小为9的数组。

  • 从上图可以看到,更多的点的梯度方向是倾向于0度和160度,也就是说这些点的梯度方向是向上或者向下,表明图像这个位置存在比较明显的横向边缘。因此HOG是对边角敏感的,由于这样的统计方法,也是对部分像素值变化不敏感的,所以能够适应不同的环境。

把cell单元组合成block,块内归一化梯度直方图

  • 由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。所以必须归一化梯度强度,归一化梯度强度可以实现对边缘、光照和阴影的压缩。最后再合并每个块的特征描述子就能够获得这张图像的 HOG 特征描述子,也就是 HOG 特征向量。
  • 每个 block 可以得到 4 个 9 维的向量,需要再次进行一次归一化,这样可以进一步提高泛化能力,使用 L2-nrom 进行归一化 (还有L1-norm, L1-sqrt,etc.)

$$ v=\frac{v}{\sqrt{\|v\|_{2}^{2}+\varepsilon^{2}}} $$

  • 其中范数操作定义为:

$$ \|x\|_{p}:=\left(\sum_{i=1}^{n}\left|x_{i}\right|^{p}\right)^{1 / p} $$

归一化图示

block 归一化

  • 绿色方块是 $8\times8$ 大小的 cell,蓝色方块就是由 4 个 cell 组成的 block。
  • 作者提出要对 block 进行 normalize。那么由于一个cell就会有大小为9的vector,4 个 cell 就有 36 大小的vector。
  • 对 block 进行 normalize 就是对这大小为 36 的 vector 进行归一化。

整体流程图

HOG提取流程

整体图示

  • 默认HOG的描述子窗口为 $64\times128$, 窗口移动步长为 $8\times8$
  • 每个窗口的 cell 为 $8\times8$,每个block由4个cell组成,block移动步长为一个cell,因此可以得到 $7\times15$个 block

HOG

  • 直方图把 180 度分为 9 个 bin,每个区间为 20 度,如果像素落在某个区间,就把该像素的直方图累计到对应区间的直方图上

  • 每个 block 有 4 个cell,每个 cell 有 9 个向量值,即每个 block 有 36 个向量,所以整个窗口有 $7\times15\times36=3780$ 个特征描述子。

OpenCV 实现 HOG 示例

行人检测代码示例

  1. hog = cv2.HOGDescriptor() :创建HOG特征描述;
  2. hog.setSVMDetector(cv.HOGDescriptor_getDefaultPeopleDetector()) :创建HOG+SVM行人检测器;
  3. 多尺度检测API:
1
2
3
4
5
6
rects, weights = hog.detectMultiScale(img, foundLocations,
hitThreshold = 0,
winStride, padding,
scale = 1.05,
finalThreshold = 2.0,
useMeanshiftGrouping = false)
  • 输入
参数 含义
Img 输入图像
foundLocations 发现对象矩形框
hitThreshold SVM距离度量(特征与SVM分类超平面之间距离),默认0表示
winStride 窗口步长
padding 填充
scale 尺度空间
finalThreshold 最终阈值,默认为2.0
useMeanshiftGrouping 不建议使用,速度太慢

PS:其中窗口步长与Scale对结果影响最大,特别是 Scale ,小的尺度变化有利于检出低分辨率对象,同时也会导致FP发生,高的可以避免FP但是会产生FN(对象漏检)。

  • 示例图像(来自度娘)

  • 示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import cv2 as cv

src = cv.imread("people.jpg")
cv.imshow("input", src)
# hog特征描述
hog = cv.HOGDescriptor()
# 创建SVM检测器
hog.setSVMDetector(cv.HOGDescriptor_getDefaultPeopleDetector())
# 检测行人
(rects, weights) = hog.detectMultiScale(src,
winStride=(4, 4),
padding=(8, 8),
scale=1.25,
useMeanshiftGrouping=False)
for (x, y, w, h) in rects:
cv.rectangle(src, (x, y), (x + w, y + h), (0, 255, 0), 2)

cv.imshow("hog-people", src)
cv.waitKey(0)
cv.destroyAllWindows()

  • 识别结果

事实上这个算法还是挺挑图像和参数的,只是恰好这张数据比较好看

HOG 特征提取示例

  • 更灵活的用法是亲自提取数据的 HOG 特征
  • 示例代码
1
2
3
4
5
6
7
8
9
import cv2
import numpy as np

data = (np.random.rand(128, 64) * 255).astype('uint8')
hog = cv2.HOGDescriptor()
descriptors = hog.compute(data, winStride=(8, 8), padding=(0, 0))
print(descriptors.shape)

>> (3780,)

参考资料

文章链接:
https://www.zywvvd.com/notes/study/image-processing/feature-extraction/hog/hog/