HOG+SVM分类器实践

news/2024/5/19 20:59:00/文章来源:https://blog.csdn.net/qq_36693723/article/details/130380517

文章目录

    • HOG+SVM分类器实践
      • 制作SVM分类器
        • 导入所需的库
        • 提取HOG特征
        • 读取正样本和负样本
        • 训练分类器
        • 定义主函数
        • 小结
      • 测试SVM分类器
      • 相关疑问
        • 1. 提取HOG特征为什么不能彩色图像呢?
        • 2. 出现如下错误
        • 3. 测试代码中,当我传入100*100的图片时候,为什么img_feature.shape是4356呢?
        • 4. 减去的2和//8是什么意思?
        • 5. 当输入图片是16*16时,print(img_feature.shape)是36,这个36是怎么获得的

HOG+SVM分类器实践

目标检测是计算机视觉领域的一个重要任务,目的是从给定的图像中找出感兴趣的目标,并标出它们的位置和类别。传统机器学习方法在目标检测中应用广泛,其中一种常见的方法是基于HOG特征和SVM分类器的方法。在下面的示例中,我们将使用Python编写代码来实现一个SVM分类器。

这个程序是用来训练一个基于HOG特征的SVM分类器,以区分正样本和负样本。具体来说,它从指定目录中读取正负样本图像,提取它们的HOG特征并将其作为训练数据,然后利用线性支持向量机(LinearSVC)算法来训练分类器,最后将分类器保存到文件中。可以调用分类器来检测其他图片。

这个代码是为了训练SVM分类器,以将正样本和负样本进行分类。它使用了一种基于HOG特征的方法来提取图像的特征,从而训练SVM分类器进行分类。它可以用于检测样本是否属于某一类别,但不能直接用于目标检测任务。要进行目标检测,通常需要使用滑动窗口和其他技巧来在图像中搜索可能包含目标的区域,然后对这些区域进行分类。

制作SVM分类器

导入所需的库

首先,我们需要导入所需的库,包括NumPy、OpenCV和Scikit-learn:

import numpy as np
import cv2
from sklearn.svm import LinearSVC
from skimage.feature import hog

提取HOG特征

接下来,我们定义一个函数来提取图像的HOG特征。这个函数使用Scikit-learn库中的hog函数来计算HOG特征。它的输入是一个图像,它的输出是一个向量,表示该图像的HOG特征:

def get_hog_features(img, orient, pix_per_cell, cell_per_block, vis=False, feature_vec=True):"""获取图像的HOG特征向量:param img: 输入图像:param orient: HOG特征的方向数:param pix_per_cell: 细胞的像素数:param cell_per_block: 每个块的细胞数:param vis: 是否返回可视化HOG图像:param feature_vec: 是否返回HOG特征向量:return: HOG特征向量或可视化HOG图像"""# 检查vis参数是否为True,如果是,则返回特征向量和可视化HOG图像if vis == True:features, hog_image = hog(img, orientations=orient,pixels_per_cell=(pix_per_cell, pix_per_cell),cells_per_block=(cell_per_block, cell_per_block),block_norm='L2-Hys', visualize=vis, transform_sqrt=True,feature_vector=feature_vec)return features, hog_image# 如果vis参数不是True,只返回特征向量else:features = hog(img, orientations=orient,pixels_per_cell=(pix_per_cell, pix_per_cell),cells_per_block=(cell_per_block, cell_per_block),block_norm='L2-Hys', visualize=vis, transform_sqrt=True,feature_vector=feature_vec)return features

另外,由于在函数注释部分使用了冒号和空格来分隔不同部分,这些注释会被识别为函数的 docstring,可以通过函数名后面的 .__doc__ 来调用该注释。例如,可以通过 print(get_hog_features.__doc__) 来输出函数的注释信息。

读取正样本和负样本

接下来,我们定义一个函数来从给定的目录中读取图像,提取它们的HOG特征,并将它们存储为训练数据。这个函数使用OpenCV库来读取图像,然后使用之前定义的get_hog_features函数来提取图像的HOG特征。它还将标注的对象的类别存储为训练数据的标签:

数据集文件夹如下配置

image-20230425222643158

我就用了两个图片,一个正样本,一个负样本。正样本我采用的是鸣人,负样本我用的是佩恩。

切忌:你的数据集图片大小尺寸要是一致的,否则可能会出问题。

pei

naruto

def get_data():"""从指定目录中读取图像,提取HOG特征,存储为训练数据:return: 训练数据和标签"""# 定义正样本图像目录和负样本图像目录pos_dir = 'dataset/positives'  # 正样本图像目录neg_dir = 'dataset/negatives'  # 负样本图像目录# 通过列表推导式获取正负样本图像的文件路径pos_imgs = [os.path.join(pos_dir, f) for f in os.listdir(pos_dir) if os.path.isfile(os.path.join(pos_dir, f))]neg_imgs = [os.path.join(neg_dir, f) for f in os.listdir(neg_dir) if os.path.isfile(os.path.join(neg_dir, f))]# 提取正样本图像的HOG特征和HOG图像pos_features = []  # 存放正样本图像的HOG特征pos_hog_img = []  # 存放正样本图像的HOG图像for img_path in pos_imgs:img = cv2.imread(img_path, 0)  # 以灰度图像读入图像文件features, hog_img = get_hog_features(img, orient=9, pix_per_cell=8, cell_per_block=2, vis=True)# 调用函数获取HOG特征和HOG图像pos_features.append(features)pos_hog_img.append(hog_img)  # 存放可视化HOG图像#------通过下面这行代码可以查看你训练集的可视化HOG图像,你图像比较少可以用#------你图像比较多,建议注释下面两行,因为你需要一张一张的关闭掉图像,挺费劲的plt.imshow(pos_hog_img[0], cmap='gray')  # 可视化HOG图像plt.show()pos_labels = np.ones(len(pos_features))  # 正样本的标签为1(表示含有目标)# 提取负样本图像的HOG特征和HOG图像neg_features = []  # 存放负样本图像的HOG特征neg_hog_img = []  # 存放负样本图像的HOG图像for img_path in neg_imgs:img = cv2.imread(img_path, 0)  # 以灰度图像读入图像文件features, neg_hog = get_hog_features(img, orient=9, pix_per_cell=8, cell_per_block=2, vis=True)# 调用函数获取HOG特征和HOG图像neg_features.append(features)neg_hog_img.append(neg_hog)  # 存放可视化HOG图像plt.imshow(neg_hog_img[0])  # 可视化HOG图像plt.show()neg_labels = np.zeros(len(neg_features))  # 负样本的标签为0(表示不含目标)# 将正样本和负样本的特征和标签组合成训练数据features = np.vstack((pos_features, neg_features))  # 将正负样本的HOG特征按行堆叠labels = np.hstack((pos_labels, neg_labels))  # 将正负样本的标签按行堆叠print(labels.shape)  # 输出标签数组的形状return features, labels  # 返回训练数据的特征和标签

训练分类器

现在,我们有了训练数据,我们可以使用Scikit-learn库中的LinearSVC来训练SVM分类器。我们定义一个函数来训练分类器,并将其保存到文件中以备后续使用:

def train_classifier(features, labels):"""训练SVM分类器并将其保存到文件中:param features: 训练数据:param labels: 训练标签:return: None"""clf = LinearSVC()clf.fit(features, labels)#------保存为svm_classifier.pkl分类器,你可以通过调用这个分类器检测其他图片--------------#joblib.dump(clf, 'svm_classifier.pkl')

定义主函数

现在,我们可以将这些函数组合起来并使用它们来训练我们的目标检测器。我们定义一个main函数来执行所有这些步骤:

import os
import joblibdef main():# 获取训练数据features, labels = get_data()# 训练分类器train_classifier(features, labels)if __name__ == '__main__':main()

小结

在这个示例中,我们展示了如何使用HOG特征和SVM分类器来训练一个简单的目标分类器,可以分辨鸣人和佩恩。它提供了一个基本的框架,可以用来训练一个自己的目标分类器。

---------------------------------------备注------------------------------------------------

精度很低,玩一玩是可以的。

测试SVM分类器

import cv2
import numpy as np
import joblib
from skimage.feature import hogdef predict(img_path, clf_path='svm_classifier.pkl'):# 加载分类器clf = joblib.load(clf_path)# 提取测试图片的HOG特征img = cv2.imread(img_path, 0) # 读取灰度图像img_feature = hog(img, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(2, 2),block_norm='L2-Hys', transform_sqrt=True, feature_vector=True)print(img_feature.shape)# 进行预测pred = clf.predict(np.array([img_feature]))# 展示图片cv2.imshow('image', img)cv2.waitKey(0)cv2.destroyAllWindows()return pred[0]def main():# img_path = 'dataset/negatives/pei.jpg'#-------------------------这里修改图片的路径名称---------------img_path = 'test.jpg'result = predict(img_path, 'svm_classifier.pkl')if result == 0:print('This is a negative image.')else:print('This is a positive image.')if __name__ == '__main__':main()

运行上述测试代码,可以看到输出测试的鸣人图片,并且在终端输出了 This is a positive image 。

image-20230425224227793

用一个火车的图片,可以看到输出是 This is a negative image

image-20230426090110479

但是啊,误检测很严重,因为就用了一个正样本和负样本学习,分类器能力肯定不行的。你即使选择佩恩的图片,或者其他人物图片,他也会认为是真图片的。

这个不能称为目标检测。因为现在大家认为的目标检测,都会在原图片上把目标用矩形框框起来,而这个只能称作简单的分类器,它把待检测的图片预测成1或0,分辨物体是不是真图片或假图片。

相关疑问

训练的时候是灰度图像,因此测试的时候需要用灰度图像测试,如果直接用彩色图像测试会导致通道错误。

1. 提取HOG特征为什么不能彩色图像呢?

对于HOG算法来说,其最初目的是用于在灰度图像上检测边缘和方向,为了保留图像在块和细胞级别上的更丰富的边缘方向特征,输入图像需要是灰度图像。在彩色图像上直接使用HOG算法可能会导致HOG特征提取的结果不理想,因为彩色图像中的RGB或其他色彩通道的变化可能会干扰算法的表现,从而降低分类器的准确性。另外,彩色图像的通道数是3,如果直接使用彩色图像,则提取的特征向量维数将大于灰度图像的特征向量维数,这可能会增加算法的复杂性,导致需要更高的计算成本。因此,在实际中通常将输入图像转换为灰度图像进行HOG特征提取。

2. 出现如下错误

image-20230426091036152

如果出现该错误,表明图像大小不一样。比如你用 256 ∗ 256 256*256 256256的图片训练,那么你测试的图片也需要 256 ∗ 256 256*256 256256

3. 测试代码中,当我传入100*100的图片时候,为什么img_feature.shape是4356呢?

image-20230426093357447

在该代码中,通过使用HOG算法对输入的灰度图像进行特征提取。在这个特定的函数中,通过使用hog()函数,并给定了以下参数来计算HOG特征:

  • orientations=9 # 方向直方图数量
  • pixels_per_cell=(8, 8) # 每个细胞的像素大小
  • cells_per_block=(2, 2) # 每个块包含的细胞数
  • block_norm=‘L2-Hys’ # 块规范化方法
  • transform_sqrt=True # 对数据缩放开方,以获得更好的动态范围
  • feature_vector=True # HOG特征向量

这些参数决定了hog()函数如何对图像进行处理,并获得特征向量。根据这些参数,将图像划分为多个大小为(8,8)的单元格(每个单元格具有64个像素),形成所谓的“cell”。 对每个单元格,计算直方图梯度,每个直方图包含了所涉及单元格中每个像素的幅值,方向,之后将它们放入“block”,这里每个块包含4个细胞。最终,使用块规范化来协调每个块的输出,确保输出的特征向量有更好的动态范围。

根据上述参数,图像的尺寸为100 x 100,划分为8 x 8的单元格时,每个细胞包含8 x 8个像素,每个块包含2 x 2个细胞,其中每个细胞对应一个方向梯度直方图,共9个bins。因此,每个单元格的方向梯度直方图包含9个定向的bin,一个块包含4个单元格,因此一个块的方向梯度直方图特征向量的长度为 9×4=36。 对于该代码给出的图像,形成的特征向量为大小为 (9-2) * ((100 // 8)-2) * 4 * 9 = 4356,减去的2和//8是因为目标图像的尺寸不足以提供块周围的两个单元格的信息。因此,包含4356个元素的一维特征向量被用作SVM分类器的输入。

4. 减去的2和//8是什么意思?

因为该代码中设置的cells_per_block2 x 2,这意味着一个块由2 x 2个单元格组成。然而,在对图像进行“块”提取时,HOG算法需要在图像周围保留至少一个单元格以计算外部梯度。因此,在计算特征向量时,HOG算法需要丢弃图像周围的两个(上下、左右)单元格。 对于这个具体的函数,图像的尺寸为100 x 100,因此在使用8 x 8的单元格大小的情况下,可以形成12 x 12的单元格。然而,对于形状为12 x 12的单元格块,不能在图像的边缘提取其他块,因为图像的尺寸不足以在边缘形成2 x 2的单元格块。因此,需要在图像周围排除两个单元格边缘,即在高度和宽度上的2 x (8 // 8) =2 x 1 = 2个单元格。这就是代码中减去2的原因,并使用整除运算符//用于除以单元格的大小来计算需要从图像边缘删除的单元格数量。

在HOG算法中,图像被划分为多个单元格,每个单元格包含一组像素。而在这个特定的函数中,每个单元格的大小被设置为8 x 8像素。因此,如果输入图像的尺寸为100 x 100,那么图像可以被划分为12 x 12个单元格,其中每个单元格的大小为8 x 8像素。每个单元格的HOG特征向量都是通过计算其方向梯度直方图获得的,然后将这些特征拼接成一个特征向量。因此,在这个特定的函数中,通过这种方式处理图像,呈现的特征向量的长度是定的,即生成了由4356个元素组成的一维特征向量。

5. 当输入图片是16*16时,print(img_feature.shape)是36,这个36是怎么获得的

如果输入图像大小为 16 x 16,则该函数提取HOG特征向量的过程如下:

  1. 定义单元格大小 pixels_per_cell=(8, 8),每个单元格的大小为 8 x 8

2.定义块的大小 cells_per_block=(2, 2),每个块包含 2 x 2 个单元格;

  1. 因为该图像中只有 2 x 2 个单元格,所以只有一个块,因此生成的 HOG 特征向量只有一个块的特征,即一个长度为 36 的一维向量。

对于每个单元格:

4.计算每个单元格内像素的梯度大小和梯度方向,并将其分配到其最接近的方向bin中;

  1. 构建每个单元格的梯度方向直方图,该直方图中包含9个方向bin,分别表示0°至180°之间的均匀间隔;

对于每个块:

cell=(8, 8),每个单元格的大小为 8 x 8`;

2.定义块的大小 cells_per_block=(2, 2),每个块包含 2 x 2 个单元格;

  1. 因为该图像中只有 2 x 2 个单元格,所以只有一个块,因此生成的 HOG 特征向量只有一个块的特征,即一个长度为 36 的一维向量。

对于每个单元格:

4.计算每个单元格内像素的梯度大小和梯度方向,并将其分配到其最接近的方向bin中;

  1. 构建每个单元格的梯度方向直方图,该直方图中包含9个方向bin,分别表示0°至180°之间的均匀间隔;

对于每个块:

  1. 将每个块内包含的4个单元格的HOG特征向量拼接起来,形成一个块的HOG特征向量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_104092.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测试开发实战项目 | 搭建Pytest接口自动化框架

一、预研背景 目前系统研发多为前后端分离,当后端接口研发完成后,可以不依赖前端界面通过接口测试提前发现问题并解决。同时由于软件迭代周期不断缩短,开发新功能后又担心影响原有功能,可以通过接口自动化进行原有功能快速回归测…

git版本本地远程分支管理测试

只为搞清楚一些基本的git的本地提交、分支,远程分支的概念。 创建git库。 在本地首次建立一个001文件,首次提交到本地master,不提交(push)到远程master(gitee)。 add 增加001文件到库。 Git-co…

传统协议大比拼之IP协议

文章目录 一、引言二、IP协议的基本特点2.1 IP协议的作用和基本功能2.2 地址管理手动分配IP动态主机配置协议(DHCP)网络地址转换(NAT)IPv6 2.2 路由选择RIP(距离向量型的协议)OSPF(链路状态类型协议)BGP(边界网关协议) 2.3 IP协议的特点: 三、IP地址的组成3.1 IP地址…

三菱GX Works2梯形图程序分段显示设置的具体方法示例

三菱GX Works2梯形图程序分段显示设置的具体方法示例 大家平时在使用GX Works2进行梯形图程序编辑时,默认是一整段在一起,程序步数较多时查看起来不是那么方便,下面就和大家分享如何通过声明编辑来实现程序分段显示。 具体方法可参考以下内容: 如下图所示,打开GX Works2编…

知网导入EndNote

首先进入知网,搜索你想要找的期刊论文。 选择EndNote 点击导出 浏览器自动下载以txt为后缀的文件 导入到EndNote中

汇编小程序解析--3D立方体旋转

汇编小程序解析–3D立方体旋转,源代码如下,是vulture大神于1995年写的,我到现在才基本看懂。 ;本程序由国外的Vulture大哥编写,并公布了源码,这个是他95年的一个作品,可以说是在当时是非常成功的&#xff…

HJL-93/A数字式交流三相电流继电器 导轨安装 约瑟JOSEF

品牌:JOSEF约瑟名称:数字式交流三相电流继电器型号:HJL系列功率消耗:≤5W触点容量:250V/5A额定电压:58、100、110、220V HJL系列 数字式交流三相电流继电器型号: HJL-93/AY数字式交流三相电流继…

博途1200/1500PLC工艺PID编程应用(SCL语言)

博途工艺PID的详细解读可以查看下面的博客文章,这里不再赘述 博途PLC 1200/1500PLC 工艺对象PID PID_Compact详细解读_RXXW_Dor的博客-CSDN博客这篇博文我们详细解读博途PLC自带的PID功能块PID_Compact,大部分工业闭环调节过程,我们采用系统自带的PID功能块基本都能胜任,一…

力扣sql中等篇练习(十三)

力扣sql中等篇练习(十三) 1 每位学生的最高成绩 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 #先找到最大的元素 然后分组即可,不用管某些字段(grade)是不是聚合字段 SELECT e1.student_id,min(e1.course_id) course_id,e1.grade FROM Enrollment…

很不错的一篇文章,值得点赞收藏,带你全面了解MySQL性能调优、错误代码总结和全局参数配置(持续更新中ing)

前言 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系…

leetcode刷题(9)二叉树(3)

各位朋友们,提前祝大家五一劳动节快乐啊!!!今天我为大家分享的是关于leetcode刷题二叉树相关的第三篇我文章,让我们一起来看看吧。 文章目录 1.二叉树的层序遍历题目要求做题思路代码实现 2.从前序与中序遍历序列构造二…

上海亚商投顾:沪指全天震荡微跌 新能源赛道股集体反弹

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪 大小指数今日走势分化,沪指探底回升小幅下跌,创业板指盘中涨超2%,午后涨幅有所…

黑盒测试过程中【测试方法】详解5-输入域,输出域,猜错法

在黑盒测试过程中,有9种常用的方法:1.等价类划分 2.边界值分析 3.判定表法 4.正交实验法 5.流程图分析 6.因果图法 7.输入域覆盖法 8.输出域覆盖法 9.猜错法 黑盒测试过程中【测试方法】讲解1-等价类,边界值,判定表_朝一…

无线通信网 - 无线局域网 WLAN(802.11 标准)

文章目录 1 概述2 WLAN2.1 802.11 标准2.2 网络分类2.3 通信技术 3 扩展3.1 移动通信3.2 网工软考真题 1 概述 #mermaid-svg-UcgosJsdJfSTEm0Y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UcgosJsdJfSTEm0Y .err…

AI如何帮助人类进而验证直觉的可靠性?

AI可以通过以下方式帮助人类寻找反例进行否定或寻找特别的架构: 1. 利用机器学习算法进行反例搜索。AI可以训练一个分类器,用于判断某个假设是否成立。通过反复训练和测试,AI可以识别出一些不合理的假设,并帮助人类进行进一步的验…

Windows环境下C++ 安装OpenSSL库 源码编译及使用(VS2019)

参考文章https://blog.csdn.net/xray2/article/details/120497146 之所以多次一举自己写多一篇文章,主要是因为原文内容还是不够详细。而且我安装的时候碰到额外的问题。 1.首先确认一下自己的代码是Win32的还是Win64的,我操作系统是64的,忘…

【SVN】windows SVN安装使用教程(服务器4.3.4版本/客户端1.11.0版本)

介绍 这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。 一个人为什么要努力&a…

材料写作素材:关于“大”排比句40例

1.一轮思想政治“大督查”,一轮政策落实“大检查”,一次非公企业“大走访”,一次问题线索“大起底”,一批典型案例“大曝光”。 2.在重大风险挑战面前豁得出去、顶得上去,在重大困难考验面前迎难而上、敢于胜利&#…

逐浪智能时代,网易数帆“重写”低代码

如今,越来越多行业正驶入数字化转型的深水区,如何彻底释放数据生产力,成为所有企业的一道必答题。 4月25日,“网易数帆低代码业务战略发布会”在线上举行。在发布会上,网易数帆发布了CodeWave智能开发平台&#xff0c…

e签宝,「进化」在2023

精准布局生态化、统一化、智能化、信创化,辅以具体产品落地;加速产业、行业、企业、业务,“四业”互通互联,提高产业数字化渗透率。电子签“群战”时代,e签宝再次进化。 作者|斗斗 出品|产业家 “印章在谁手上&…