【工业机器视觉】基于深度学习的水表盘读数识别(3-数据标注与转换)

【工业机器视觉】基于深度学习的仪表盘识读(2)-CSDN博客

数据标注

标注扩展

Labelme 和 LabelImg 都是用于创建机器学习和计算机视觉项目所需标注数据的工具。它们都允许用户通过图形界面手动标注图像,但各自有其特点和适用场景。

Labelme

  • 开发语言:Python
  • 标注类型:Labelme 支持多种标注类型,包括但不限于多边形(polygon)、矩形(rectangle)、线段(line)、点(point)等。它非常适合需要精确标注物体边界的情况,比如在医疗影像、自动驾驶等领域。
  • 文件格式:标注结果通常保存为 JSON 文件,其中包含每个标注对象的坐标信息、标签名称等。
  • 灵活性:Labelme 提供了插件系统,可以扩展其功能,如支持更多的图像格式或添加自定义的标注类型。
  • 跨平台:基于 Python 的 Qt 库构建,可以在 Windows、macOS 和 Linux 上运行。

LabelImg

  • 开发语言:Python
  • 标注类型:主要支持矩形框(bounding box)标注,适合于目标检测任务。对于需要简单快速地对多个对象进行框选标注的任务来说非常方便。
  • 文件格式:标注结果可以保存为 Pascal VOC XML 格式或者 YOLO txt 格式,这两种格式都是目标检测任务中常用的标注文件格式。
  • 轻量化:相比于 Labelme,LabelImg 更加轻量化,易于安装和使用,尤其适合初学者。
  • 跨平台:同样基于 Python 的 Qt 库,可以在不同操作系统上运行。

安装扩展包:

pip install labelme labelimg

指针区域

使用labelimg进行BOX标注,标签类别:{'area_p', 'p0', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'},p0~p9为最低位x0.001标签类别,area_p为其他高位指针区域标签类别。

示例:

标签文件是VOC XML文件数据,后面再通过脚本转换成YOLO格式数据。

梅花针分割

使用labelme进行实例切割,标签类别:{'pointer', 'circle_area'},pointer是红色梅花针区域,circel_area是刻度圆。

示例:

标签文件是JSON格式文件数据,后面再通过脚本转换成YOLO格式数据。

字轮区域

使用labelimg进行BOX标注,标签类别:{'d0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9',  'd10', 'd11', 'd12', 'd13', 'd14', 'd15', 'd16', 'd17', 'd18', 'd19'},d0~9表示数字刚好在字轮窗口中心位置,也就是非过渡状态,d10~19表示各个数字的过渡状态。

示例:

标签文件是VOC XML文件数据,后面再通过脚本转换成YOLO格式数据。

数据划分

在深度学习中,训练集和验证集是用于模型开发过程中的两个重要数据集。它们各自扮演着不同的角色,确保最终模型的性能和泛化能力。

训练集(Training Set)

  • 用途:训练集主要用于训练模型。即,在这个数据集上调整模型的权重或参数,使模型能够学习到数据中的特征和模式。
  • 特点:通常包含大量带标签的数据样本,这些数据样本应该尽可能地代表实际应用环境中的数据分布。
  • 影响:如果训练集的质量不高(如数据量不足、标注不准确或偏差),可能会导致模型过拟合或欠拟合,从而影响其性能。

验证集(Validation Set)

  • 用途:验证集用于在训练过程中评估模型的表现,帮助选择模型的最佳配置(例如,超参数调优)。它提供了一个独立于训练集的反馈机制,用以监测模型是否开始过拟合训练数据。
  • 特点:与训练集类似,验证集也应该是有代表性的,并且它的标签也是已知的。但是,它不应该被用来直接更新模型参数;相反,它是用来决定何时停止训练(早停法)或选择最佳模型架构/超参数。
  • 影响:通过验证集可以有效防止过拟合,确保模型不仅在训练数据上表现良好,而且在未见过的数据上也能保持良好的性能。

注意事项

  • 划分比例:常见的是将数据划分为70%训练集和30%验证集,或者采用交叉验证的方法来更充分利用有限的数据。具体的比例可以根据实际情况调整
  • 测试集:除了训练集和验证集之外,有时还会有一个测试集(Test Set),用于最终评估模型的真实性能。测试集在整个训练和验证过程中都应该保持完全独立,直到最后评估时才使用。

正确管理和使用训练集和验证集对于构建一个有效的深度学习模型至关重要。这有助于确保模型不仅能很好地适应训练数据,还能对新数据做出准确预测。

数据划分代码:

import argparse
import os
import random
from os import getcwd# root = getcwd() + '\\my_datas\\pointer-seg\\'
root = getcwd() + '\\my_datas\\detect-pointer\\'
# root = getcwd() + '\\my_datas\\detect-digit\\'
parser = argparse.ArgumentParser()parser.add_argument('--img_path', default='IMAGES', type=str,help='input images file path')
parser.add_argument('--txt_path', default='TXT_LABELS', type=str,help='output txt label path')
opt = parser.parse_args()trainval_percent = 1.0
train_percent = 0.9
imgfilepath = root + opt.img_path
txtsavepath = root + opt.txt_path
total_img = os.listdir(imgfilepath)
if not os.path.exists(txtsavepath):os.makedirs(txtsavepath)num = len(total_img)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)try:os.remove(txtsavepath + '/trainval.txt')os.remove(txtsavepath + '/train.txt')os.remove(txtsavepath + '/valid.txt')
except:pass
file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/valid.txt', 'w')for i in list_index:name = total_img[i] + '\n'if i in trainval:file_trainval.write(imgfilepath + '/' + name)if i in train:file_train.write(imgfilepath + '/' + name)else:file_val.write(imgfilepath + '/' + name)file_trainval.close()
file_train.close()
file_val.close()

IMAGES为所有需要学习的数据图片目录 

数据转换

VOC XML 转 YOLO

import os
import shutil
import xml.etree.ElementTree as ET
from tqdm import tqdmsets = ['train', 'valid']
project_name = 'detect-pointer'
classes = ['area_p', 'p0', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9']
# project_name = 'detect-digit'
# classes = ['d0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9',
#            'd10', 'd11', 'd12', 'd13', 'd14', 'd15', 'd16', 'd17', 'd18', 'd19']abs_path = os.getcwd()def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, hdef convert_annotation(image_id, image_set):in_file = open(r'my_datas\%s\ANNOTATIONS\%s.xml' % (project_name, image_id), encoding='UTF-8')out_file = open(r'my_datas\%s\%s\labels\%s.txt' % (project_name, image_set, image_id), 'w')tree = ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))b1, b2, b3, b4 = b# 标注越界修正if b2 > w:b2 = wif b4 > h:b4 = hb = (b1, b2, b3, b4)bb = convert((w, h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# 删除文件夹中所有文件
def del_all_file(path):for root, dirs, files in os.walk(path):for f in files:os.remove(os.path.join(root, f))del_all_file(f'my_datas\\{project_name}\\train\images')
print('train\images delete success.')
del_all_file(f'my_datas\\{project_name}\\train\labels')
print('train\labels delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\images')
print('valid\images delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\labels')
print('valid\labels delete success.')for image_set in sets:image_files = open(r'my_datas\%s\TXT_LABELS\%s.txt' % (project_name, image_set)).read().strip().split()for image_file in tqdm(image_files):image_id = os.path.basename(image_file)[:-4]convert_annotation(image_id, image_set)shutil.copyfile(image_file, r'my_datas\%s\%s\images\%s' % (project_name,image_set, os.path.basename(image_file)))

JSON 转 YOLO

import json
import os
import shutil
from tqdm import tqdmimport numpy as npproject_name = 'pointer-seg'
sets = ['train', 'valid']
classes = ['pointer', 'circle_area']
abs_path = os.getcwd()def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, hdef pointer_distance(x1, y1, x2, y2):dis = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)return disdef json_to_yolo(path):with open(path, encoding='UTF-8') as f:labelme_data = json.load(f)width = labelme_data["imageWidth"]height = labelme_data["imageHeight"]yolo_lines = []for shape in labelme_data["shapes"]:if shape['shape_type'] == 'polygon':# 多边形label = shape["label"]points = shape["points"]class_idx = classes.index(label)txt_string = f"{class_idx} "for x, y in points:x /= widthy /= heighttxt_string += f"{x} {y} "yolo_lines.append(txt_string.strip() + "\n")elif shape['shape_type'] == 'circle':# 圆label = shape["label"]points = shape["points"]class_idx = classes.index(label)txt_string = f"{class_idx} "# 圆心a, b = points[0]# 计算半径r = pointer_distance(a, b, points[1][0], points[1][1])# 生成一些在圆上的点X = np.linspace(a - r, a + r - 1, 15)f = lambda x: np.sqrt(r ** 2 - (x - a) ** 2) + by1 = f(X)y2 = 2 * b - y1c_points = []for i, x in enumerate(X):c_points.append([x, y1[i]])c_points.append([x, y2[i]])for x, y in c_points:x /= widthy /= heighttxt_string += f"{x} {y} "yolo_lines.append(txt_string.strip() + "\n")return yolo_linesdef convert_annotation(image_id, image_set):lines = json_to_yolo(r'my_datas\%s\ANNOTATIONS\%s.json' % (project_name, image_id))with open(r'my_datas\%s\%s\labels\%s.txt' % (project_name, image_set, image_id), 'w') as out_file:out_file.writelines(lines)def del_all_file(path):for root, dirs, files in os.walk(path):for f in files:os.remove(os.path.join(root, f))del_all_file(f'my_datas\\{project_name}\\train\images')
print('train\images delete success.')
del_all_file(f'my_datas\\{project_name}\\train\labels')
print('train\labels delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\images')
print('valid\images delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\labels')
print('valid\labels delete success.')for image_set in sets:image_files = open(r'my_datas\%s\TXT_LABELS\%s.txt' % (project_name, image_set)).read().strip().split()for image_file in tqdm(image_files):image_id = os.path.basename(image_file)[:-4]convert_annotation(image_id, image_set)shutil.copyfile(image_file, r'my_datas\%s\%s\images\%s' % (project_name,image_set, os.path.basename(image_file)))

完整目录结构:

至此,用于深度学习所需的所有训练、验证数据已准备好,下一篇开始基于Utralytics YOLO系列进行训练和预测。

【工业机器视觉】基于深度学习的仪表盘识读(读数识别)(4)-CSDN博客

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

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

相关文章

静态路由与交换机配置实验

1.建立网络拓扑 添加2台计算机,标签名为PC0、PC1;添加2台二层交换机2960,标签名为S0、S1;添加2台路由器2811,标签名为R0、R1;交换机划分的VLAN及端口根据如下拓扑图,使用直通线、DCE串口线连接…

【Spark】Spark Join类型及Join实现方式

Spark Join类型 1. Inner Join (内连接) 示例:val result df1.join(df2, df1("id") df2("id"), "inner")执行逻辑:只返回那些在两个表中都有匹配的行。 2. Left Join (左外连接) 示例:val result df1.jo…

php:完整部署Grid++Report到php项目,并实现模板打印

一、下载Grid++Report软件 路径:开发者安装包下载 - 锐浪报表工具 二、 安装软件 1、对下载的压缩包运行内部的exe文件 2、选择语言 3、 完成安装引导 下一步即可 4、接收许可协议 点击“我接受” 5、选择安装路径 “浏览”选择安装路径,点击"安装" 6、完成…

web安全攻防入门教程

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻…

前端node环境安装:nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

需求:在做前端开发的时候,有的时候 这个项目需要 node 14 那个项目需要 node 16,我们也不能卸载 安装 。这岂不是很麻烦。这个时候 就需要 一个工具 来管理我们的 node 版本和 npm 版本。 下面就分享一个 nvm 工具 用来管理 node 版本。 这个…

Unity在运行状态下,当物体Mesh网格发生变化时,如何让MeshCollider碰撞体也随之实时同步变化?

旧版源代码地址:https://download.csdn.net/download/qq_41603955/90087225?spm1001.2014.3001.5501 旧版效果展示: 新版加上MeshCollider后的效果: 注意:在Unity中,当你动态地更改物体的Mesh时,通常期望…

AR眼镜_消费级工业AR智能眼镜主板硬件解决方案

AR眼镜的研发是一项复杂的软硬件集成工程,它需要在摄影、音频、交互和连接等多个方面提供卓越的基础体验,因此产品的每个细节都显得尤为重要。 在设计AR眼镜时,重量、体积和散热性能都是必须认真考量的关键因素。在芯片平台的选择上&#xff…

【OpenCV】Canny边缘检测

理论 Canny 边缘检测是一种流行的边缘检测算法。它是由 John F. Canny 在 1986 年提出。 这是一个多阶段算法,我们将介绍算法的每一个步骤。 降噪 由于边缘检测易受图像中的噪声影响,因此第一步是使用 5x5 高斯滤波器去除图像中的噪声。我们在前面的章…

Ubuntu 安装 web 服务器

安装 apach sudo apt install apache2 -y 查看 apach2 版本号 apache2 -v 检查是否启动服务器 sudo service apache2 status 检查可用的 ufw 防火墙应用程序配置 sudo ufw app list 关闭防火墙 sudo ufw disable 更改允许通过端口流量 sudo ufw allow Apache Full 开启…

如何落地文件即服务?--- 基于makeself封装服务并启动

我通常想能不能给客户一个文件,然后客户通过执行这个简单的指令就可以吧,一个服务在本地起来? 这是一种文件即服务的思想,不知道你有没有类似的想法,当我发现https://makeself.io/ ,我觉得它能很好的解决我…

IDEA方法注释模板设置

目录 创建模板 新建模板:命名为* 设置模板内容-IDEA格式模板 设置模板应用场景 设置参数 创建模板 /**Enter这里我们也按照这种习惯来设置IDEA的方法注释:File-->Settings-->Editor-->Live Templates 先新建模板组,然后在模板组中…

深度学习笔记之BERT(五)TinyBERT

深度学习笔记之TinyBERT 引言回顾:DistilBERT模型TinyBERT模型结构TinyBERT模型策略Transformer层蒸馏嵌入层蒸馏预测层蒸馏 TinyBERT模型的训练效果展示 引言 上一节介绍了 DistilBERT \text{DistilBERT} DistilBERT模型,本节将继续介绍优化性更强的知…

正则表达式——参考视频B站《奇乐编程学院》

智能指针 一、背景🎈1.1. 模式匹配🎈1.2. 文本替换🎈1.3. 数据验证🎈1.4. 信息提取🎈1.5. 拆分字符串🎈1.6. 高级搜索功能 二、原料2.1 参考视频2.2 验证网址 三、用法3.1 限定符3.1.1 ?3.1.2 *3.1.3 3.1.…

appium学习之二:adb命令

1、查看设备 adb devices 2、连接 adb connect IP:端口 3、安装 adb install xxx.apk 4、卸载 adb uninstall 【包名】 5、把对应目录下的1.txt文件传到手机sdcard下 adb push 1.txt /sdcard 6、进入对应的设备里 adb shell 7、切入sdcard目录 cd /sdcard 8、ls 查…

Tablesaw封装Plot.ly实现数据可视化

上文介绍tablesaw的数据处理功能,本文向你展示其数据可视化功能,并通过几个常用图表示例进行说明。 Plot.ly包装 可视化是数据分析的重要组成部分,无论你只是“查看”新数据集还是验证机器学习算法的结果。Tablesaw是一个开源、高性能的Java…

Python实现中国象棋

探索中国象棋 Python 代码实现:从规则逻辑到游戏呈现 中国象棋,这款源远流长的棋类游戏,承载着深厚的文化底蕴与策略智慧。如今,借助 Python 与 Pygame 库,我们能够在数字世界中复刻其魅力,深入探究代码背后…

互联网、物联网的相关标准

互联网的相关标准 网络通信协议: HTTP(Hypertext Transfer Protocol):用于在网络中传输文本、图像、音频和视频等数据的协议。它基于请求-响应模型,客户端发送请求给服务器,服务器返回响应。HTTPS&a…

学习Ajax (概述,应用场景,使用jQury 实现ajax)

目录 前言 概述 什么是Ajax? 同步交互与异步交互的区别是什么呢? 应用场景 场景1 在搜索框搜索 资源 场景2 登录业务的对用户名处理 AJAX的优缺点 优点: 缺点: 使用jQury 实现ajax 使用步骤 1 引入jQury 文件 2 使用Ajax 函数…

网迅通推出新一代智能家居拓展网关

Zigbee 型智能家居拓展网关 产品概述 A、概述 Zigbee 是一种短距离、低功耗的无线通信技术名称。其特点是近距离、低复杂度、低功耗、低数据速率、低成本。ZigBee 模块是一种物联网无线数据终端,利用 ZigBee 网络为用户提供无线数据传输功能。该产品采用高性能的…

ArcGIS字符串补零与去零

我们有时候需要 对属性表中字符串的补零与去零操作 我们下面直接视频教学 下面看视频教学 ArcGIS字符串去零与补零 推荐学习 ArcGIS全系列实战视频教程——9个单一课程组合 ArcGIS10.X入门实战视频教程(GIS思维) ArcGIS之模型构建器(Mod…