目录
前言
📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。
🚀对毕设有任何疑问都可以问学长哦!
选题指导:
大家好,这里是海浪学长毕设专题,本次分享的课题是
🎯基于机器学习的表盘指针数字识别系统
课题背景和意义
随着技术的进步和数字化的发展,表盘指针数字识别系统在各个领域中得到了广泛应用。例如,在工业生产中,准确识别仪表盘上的指针数字可以帮助操作员及时监测和控制生产过程;在交通领域,正确识别车辆仪表盘上的数字是车辆安全和驾驶员信息获取的重要基础。然而,由于表盘指针数字形态多样、尺寸不一,以及环境光照、噪声等干扰因素的存在,传统的图像处理和模式识别方法在表盘指针数字识别方面面临一定的挑战。因此,基于机器学习的表盘指针数字识别系统的研究和应用具有重要的意义。该系统可以通过训练模型,从复杂的表盘图像中准确提取和识别数字,提高识别准确率和效率,为各个领域提供可靠的数字识别技术支持。
实现技术思路
一、算法理论基础
1.1 图像处理
边缘检测算法在图像处理中通过利用图像和背景边缘地带像素的纹理、颜色等特征突变的现象来检测图像边界。这些算法通常使用一阶和二阶导数来求取图像的梯度变化,并根据导数的变化来判断是否为边缘像素。Canny边缘检测算法是一种常用的边缘检测方法,它不属于一阶或二阶导数算子,而是一种非微分的算子。Canny算法的主要步骤包括:
- 滤波降噪:使用高斯滤波函数对图像进行降噪处理。
- 计算梯度:在水平和垂直方向上计算图像的梯度差分。通常使用一个3x3的卷积模板来计算图像在两个方向上的差分。通过计算得到图像的水平梯度Gx和垂直梯度Gy,并使用幅值公式和方向公式计算图像的整体梯度幅值G和方向θ。
- 非极大值抑制:由于背景图像和前景图像之间存在梯度跳跃,边缘的幅值总是最大的。因此,通过非极大值抑制,只保留梯度幅值最大的像素点,以过滤非边缘点。
- 边界检测与连通:设定梯度幅值的上下边界,大于上边界的像素被视为边界,小于下边界的像素为非边界。对于位于上下边界之间的像素,根据其是否与其他边界相连来确定是否为边界。
1.2 深度学习
卷积神经网络(CNN)是一种在深度学习中广泛使用的网络结构,它通过卷积操作和参数共享的方式,在图像和其他二维数据上实现了高效的特征提取和学习能力。相比于传统的全连接网络,CNN通过局部连接和卷积核的使用,大大减少了网络的参数数量,并且通过池化层和非线性激活函数增强了网络的表达能力。CNN的核心思想是利用卷积核在局部感受野内提取特征,并通过层层堆叠和学习来实现对输入数据的层次化表征。这种网络结构在计算机视觉任务中取得了巨大成功,如图像分类、目标检测和图像生成等。随着深度学习的发展,CNN不断演化和改进,成为解决各种复杂问题的重要工具和基础架构。
池化层在卷积神经网络中扮演着重要的角色,主要用于下采样和特征压缩。常见的池化方式包括最大池化和平均池化。最大池化通过选取滑动窗口内的最大值作为特征输出,而平均池化则是将滑动窗口内的值求平均作为特征输出。池化层的作用主要有三个方面:首先,它可以降低特征图的维度,从而减少网络的参数量,提高计算效率;其次,池化操作具有平移不变性,能够在一定程度上保持特征的空间不变性;最后,池化层是一种非线性操作,有助于提取图像的非线性特征。非线性激活函数在卷积神经网络中也起着重要的作用,它可以引入非线性变换,增强网络的表达能力。常用的非线性激活函数包括sigmoid、ReLU、Tanh和Leaky ReLU等。全连接层通常作为网络的输出层,将获取到的多维特征向量展开成一维特征向量,并进行分类或其他任务的处理。
MobileNet系列网络是轻量级卷积神经网络,在其中引入了深度可分离卷积的概念。深度可分离卷积将传统卷积拆分为深度卷积和逐点卷积两步进行,通过这种方式大大减少了参数量,实现了网络的轻量化。MobileNetV3在前代的基础上引入了SE模块,用于轻量级的通道注意力,同时使用h-swish函数替代了sigmoid激活函数以减轻计算资源消耗。经过一系列改进,MobileNet在轻量化目标检测领域取得了不错的准确率和识别速度。因此,在部署模型到嵌入式设备上时,采用了MobileNet系列网络的部分结构并进行了改进,以提高检测速度。
1.3目标检测算法
网络由三部分组成:骨干特征提取网络(CSPDarknet53-tiny)、特征金字塔(FPN)和Yolo Head。首先,骨干特征提取网络负责对输入图像进行特征提取,通过卷积模块和残差模块对图像进行处理,其中卷积模块包括标准化和激活函数,而残差模块将特征层分成两部分,经过处理后进行残差连接。然后,特征金字塔模块对骨干网络的输出进行加强特征提取,通过从不同维度提取特征并进行融合,得到更有利的特征表示。最后,Yolo Head解析网络的输出,对加强特征提取后的特征图进行解码,生成预测结果。Yolo Head将特征层进行reshape,并输出位置信息、置信度和分类结果,通过反向传播进行参数优化,在预测时将位置信息映射到原图上并利用非极大值抑制生成最终的预测框。
为了进一步丰富训练集数据,引入了实时Mosaic数据增强方法。该方法的流程如下:在每次训练之前,从训练集中随机选择一个batch的图片。然后,从这个batch中随机选择4张图片进行裁剪和拼接,重复batch size次,生成一个新的batch的图片用于网络训练。通过这种随机组合拼接的方式,实现了目标检测物体背景的多样性,增加了数据集中不同尺度目标的数量。通过实时Mosaic数据增强,能够有效提高训练集的多样性和数量,进而改善模型的泛化能力和检测性能。
对原特征提取网络进行了改进,引入了注意力机制,构建了Attention-CSPDarknet53-tiny网络。在CSPDarknet53-tiny网络的第一个特征残差模块后加入了双重注意力模块(CBAM),该网络结构中的改进部分被称为CBAM_Block(蓝色部分)。注意力机制的目的是通过筛选出有效特征并增加其权重,同时过滤掉无效特征并减弱其权重。CBAM注意模块的结构包括两个子模块:通道注意力模块和空间注意力模块。通道注意力模块首先将输入特征图经过通道注意力的处理,通过对通道维度的特征进行加权结合,提高关键特征的重要性。然后,将经过通道注意力的特征图与原始输入特征图重新加权结合。空间注意力模块接收经过通道注意力模块处理后的特征图,通过对空间维度的特征进行加权结合,进一步提升关键信息的权重。最后,经过空间注意力模块的特征图再次与初始输入特征图进行加权结合,并经过ReLU激活函数处理后输出。
为了减少网络参数,特征提取网络仅使用了两个尺度的加强特征层输出,分别是13×13和26×26。这意味着原图被分为13×13和26×26大小的网格,并在网格内进行目标检测。13×13的特征层具有更大的感受野,而26×26的特征层感受野较小。在特征金字塔中,13×13的特征图通过卷积和上采样与26×26的特征图拼接在一起,以增加上层特征的感受野,从而获得更好的检测效果,实现多尺度的特征检测。
经过多次卷积后得到的下层特征虽然具有更大的感受野,但也会丢失部分特征信息。为了进一步加强下层特征的检测效果,本文引入了改进部分,即在特征金字塔的上层特征进行卷积和下采样,并与下层特征拼接,形成新的特征图。这样做的目的是在新的特征层中既包含了下层特征的大感受野信息,又包含了上层特征在卷积前的原始信息。通过包含更多的特征信息,网络模型能够更好地发挥特征提取能力,进一步提高目标检测的精度。
二、 数据集
2.1 数据集
由于网络上缺乏现有的适用于表盘指针数字识别的数据集,我决定自己进行数据收集和标注工作,构建一个全新的数据集。通过网络爬虫程序,我能够从开放网络中获取大量的表盘图像,并进行数字标注和分类。这个自制的数据集包含了各种类型和样式的表盘图像,其中包括不同尺寸、颜色和数字样式的指针数字。
2.2 数据扩充
为了增加数据集的多样性和鲁棒性,我对自制数据集进行了扩充。首先,我采用数据增强技术对图像进行处理,包括旋转、缩放、平移和镜像等操作,以模拟不同角度和尺度下的表盘图像。其次,我收集了更多不同型号和品牌的表盘图像,以拓展数据集的覆盖范围。此外,我还对图像中的光照、噪声和模糊等干扰因素进行模拟和添加,以增加数据集对复杂环境的鲁棒性。
三、实验及结果分析
3.1 实验环境搭建
实验的训练和测试环境如下:使用Windows 10操作系统,搭配Intel Core i7-9700 3.00GHz的中央处理器和32GB的内存。图形显卡采用NVIDIA GeForce RTX 2070 8GB。深度学习框架选择TensorFlow 2.0作为实验平台。这个环境提供了强大的计算能力和适用于深度学习任务的硬件加速,为实验的训练和测试提供了充足的资源支持。
3.2 模型训练
损失函数包括置信度损失函数、预测种类损失函数和IoU损失函数,用于度量检测准确性。学习率采用ReduceLROnPlateau方法逐步降低,以提高模型收敛速度。训练策略包括权重冻结、Dropout和Earlystop策略,用于保留迁移学习特征、减少参数和提前结束训练。评价指标使用mAP、查准率和查全率来评估算法性能。
相关代码示例:
def separate_pointer(image):
# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 霍夫圆检测
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1, minDist=100, param1=50, param2=30, minRadius=10, maxRadius=100)
# 提取指针区域
if circles is not None:
for circle in circles[0]:
center = (circle[0], circle[1])
radius = circle[2]
# 在原图上绘制指针圆形区域
cv2.circle(image, center, radius, (0, 255, 0), 2)
# 提取指针区域
pointer = image[int(center[1]-radius):int(center[1]+radius), int(center[0]-radius):int(center[0]+radius)]
# 进行轮廓检测
gray_pointer = cv2.cvtColor(pointer, cv2.COLOR_BGR2GRAY)
_, threshold = cv2.threshold(gray_pointer, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
contours, _ = cv2.findContours(threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制指针轮廓
cv2.drawContours(pointer, contours, -1, (0, 0, 255), 2)
# 在原图上绘制指针区域
image[int(center[1]-radius):int(center[1]+radius), int(center[0]-radius):int(center[0]+radius)] = pointer
return image
海浪学长项目示例:
最后
我是海浪学长,创作不易,欢迎点赞、关注、收藏。
毕设帮助,疑难解答,欢迎打扰!