Python实操|用OpenCV+HOG提取图像特征,代码可直接复制运行
在计算机视觉领域,HOG(方向梯度直方图)是一个非常经典的特征提取算法,常用于目标检测(比如行人检测、人脸检测)、图像识别等场景。
它的核心是通过统计图像局部区域的梯度方向分布,捕捉图像的纹理和轮廓特征,比单纯的像素值更具区分度。
今天就给大家分享一段可直接运行的HOG特征提取代码,基于OpenCV、NumPy和scikit-image实现,从图像读取到特征可视化一步到位,新手也能轻松上手~
unsetunset一、完整可运行代码(直接复制即用)unsetunset
先上干货!以下代码包含了图像读取、路径校验、特征提取、可视化保存全流程,解决了新手常踩的“路径报错”“参数弃用”“保存空白图”等问题,复制到PyCharm或Jupyter中,替换图片路径即可运行。
import cv2import numpy as npimport matplotlib.pyplot as pltfrom skimage.feature import hogimport os# 自动创建保存目录(避免路径不存在报错)os.makedirs('../tmp', exist_ok=True)# 1. 读取灰度图像(HOG特征提取常用灰度图,简化计算)image = cv2.imread('../data/lena.jpg', 0)if image isNone:raise FileNotFoundError("请检查图片路径:../data/lena.jpg 是否存在!")# 2. 归一化到 [0,1](HOG计算推荐浮点型数据,提升特征稳定性)image = np.float32(image) / 255.0# 3. 提取HOG特征 + 生成可视化图像fd, hog_image = hog( image, orientations=8, # 方向梯度的 bins 数量(分组数) pixels_per_cell=(16,16),# 单个细胞单元的像素尺寸(16x16像素为一个细胞) cells_per_block=(1,1), # 每个块包含的细胞单元数量 visualize=True, # 是否生成HOG特征可视化图像 channel_axis=None# 灰度图无通道,彩色图需设为 2(关键参数,避免报错))# 4. 可视化HOG特征(直观查看提取效果)plt.figure(figsize=(8, 8))plt.imshow(hog_image, cmap='gray')plt.axis('off') # 关闭坐标轴,让可视化更简洁# 5. 先保存图片,再显示(关键!避免保存空白图)plt.savefig('../tmp/hog.png', dpi=300, bbox_inches='tight')plt.show()# 打印特征维度(可选,查看提取的特征向量长度)print(f"HOG特征向量长度: {len(fd)}")
unsetunset二、代码逐行拆解(新手必看)unsetunset
很多新手复制代码后只会运行,却不懂每一步的意义,这里逐行拆解核心逻辑,帮你真正理解HOG特征提取的流程。
1. 导入依赖库
代码开头导入了5个核心库,各自的作用的如下:
numpy:数值计算库,用于图像数据的归一化和数组处理;
matplotlib.pyplot:绘图库,用于可视化HOG特征图像;
skimage.feature.hog:scikit-image库中的HOG特征提取函数,核心工具;
2. 规避路径报错:自动创建保存目录
3. 读取灰度图像并校验
cv2.imread(../data/lena.jpg, 0) 中,第二个参数0表示读取灰度图像——HOG特征提取通常用灰度图,能减少通道带来的冗余计算,提升效率。
后面的if image is None 判断,是为了校验图片路径是否正确,如果路径错误(比如文件不存在、路径写错),会直接提示错误,避免代码无意义报错。
4. 图像归一化(关键步骤)
image = np.float32(image) / 255.0 将图像像素值从[0,255] 归一化到 [0,1]。
为什么要归一化?因为HOG特征对像素值的范围敏感,归一化后能让特征提取更稳定,避免因像素值过大导致的计算偏差,这是提升特征准确性的小技巧。
5. HOG特征提取(核心代码)
这部分是整个代码的核心,hog() 函数返回两个值:
fd:HOG特征向量,是一个一维数组,长度由参数设置决定(后面会讲);
hog_image:HOG特征的可视化图像,能直观看到提取的纹理轮廓。
重点讲解5个关键参数(新手必懂),调整这些参数能改变特征提取效果:
| | |
|---|
| | 8/9/12(数值越多,特征越精细,但计算量越大) |
| | (8,8)/(16,16)(16x16最常用,兼顾效率和效果) |
| | (1,1)/(2,2)(1x1适合快速测试,2x2特征更鲁棒) |
| | |
| | |
⚠️ 关键提醒:旧版本skimage中的multichannel参数已被弃用,改用channel_axis,否则会报错——这是很多新手踩过的坑,代码中已规避。
6. 可视化与保存(避免空白图)
新手常犯的错误:把plt.savefig() 写在plt.show() 后面,导致保存的图片是空白的!
原因:plt.show() 会清空画布,所以必须先保存(plt.savefig()),再显示图像(plt.show())。
补充参数:dpi=300 确保保存的图片高清,bbox_inches=tight 去除图片周围的白边,让可视化效果更整洁。
unsetunset三、运行依赖安装(新手必看)unsetunset
pip install opencv-python numpy matplotlib scikit-image
如果是Python3,建议用pip3 替换pip,避免环境冲突。
unsetunset四、常见问题排查(踩坑指南)unsetunset
问题1:报错“FileNotFoundError: 请检查图片路径”——解决方案:修改cv2.imread() 中的图片路径,确保图片存在(相对路径、绝对路径都可以);
问题2:报错“ValueError: channel_axis must be specified”——解决方案:检查channel_axis 参数,灰度图设为None,彩色图设为2;
问题3:保存的图片是空白的——解决方案:把plt.savefig() 移到plt.show() 前面;
问题4:特征向量长度不符合预期——解决方案:调整orientations、pixels_per_cell 参数,三者共同决定特征向量长度。
unsetunset五、补充说明(进阶参考)unsetunset
HOG特征的用途:除了目标检测,还可用于图像匹配、纹理识别,是很多经典算法(如SVM目标检测)的核心特征;
参数调整技巧:如果需要更精细的特征,可增大orientations、减小pixels_per_cell,但会增加计算量;如果追求效率,可适当简化参数;
彩色图适配:如果要处理彩色图像,只需将cv2.imread() 的第二个参数改为1(读取彩色图),并将channel_axis 设为2 即可。
unsetunset总结unsetunset
这篇代码的核心优势的是“开箱即用”,规避了新手常踩的所有坑,同时兼顾了专业性和易懂性。无论是用于课程作业、项目开发,还是入门计算机视觉,这段代码都能帮你快速上手HOG特征提取。
大家可以尝试替换不同的图片,调整参数,观察HOG特征的变化,加深对算法的理解~ 有任何问题,欢迎在评论区留言交流!