制作数据集
收集相关图片:
可以使用爬虫在百度爬取。爬虫代码如下:
# -*- coding: UTF-8 -*-"""
import requests
import tqdmdef configs(search, page, number):""":param search::param page::param number::return:"""url = 'https://image.baidu.com/search/acjson'params = {"tn": "resultjson_com","logid": "11555092689241190059","ipn": "rj","ct": "201326592","is": "","fp": "result","queryWord": search,"cl": "2","lm": "-1","ie": "utf-8","oe": "utf-8","adpicid": "","st": "-1","z": "","ic": "0","hd": "","latest": "","copyright": "","word": search,"s": "","se": "","tab": "","width": "","height": "","face": "0","istype": "2","qc": "","nc": "1","fr": "","expermode": "","force": "","pn": str(60 * page),"rn": number,"gsm": "1e","1617626956685": ""}return url, paramsdef loadpic(number, page):""":param number::param page::return:"""while (True):if number == 0:breakurl, params = configs(search, page, number)result = requests.get(url, headers=header, params=params).json()url_list = []for data in result['data'][:-1]:url_list.append(data['thumbURL'])for i in range(len(url_list)):getImg(url_list[i], 60 * page + i, path)bar.update(1)number -= 1if number == 0:breakpage += 1print("\nfinish!")def getImg(url, idx, path):""":param url::param idx::param path::return:"""img = requests.get(url, headers=header)file = open(path + 'maintenanceWorker21_' + str(idx + 1) + '.jpg', 'wb')file.write(img.content)file.close()if __name__ == '__main__':search = input("请输入搜索内容:")number = int(input("请输入需求数量:"))path = './car'header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'}bar = tqdm.tqdm(total=number)page = 0loadpic(number, page)
安装标注工具labelme
pip insatll lablelme
cmd中输入命令label.exe打开软件。
标注技巧
常用快捷键:D(打开上一张图片),A(打开下一张图片),Ctrl+Z撤销上一个点。
最好将图片和标记后的json文件放在一个文件夹下。
转换格式
安装labelme2yolo工具:pip install labelme2yolo
通过labelme2yolo --help可以查看用法:
在cmd中使用如下命令即可以完成转换:
labelme2yolo --json_dir="json文件的路径" --val_size=0.2 --test_size=0 --output_format="bbox"
转换完成就就会在json文件的目录下生成已经划分好的数据集:YOLODataset
下载yoloV5
github下载yoloV5
安装相关的库:
在安装前,如果环境以及安装了torch,就将requirements.txt中的torch部分注释掉,如果尚未安装torch,也不要使用国内镜像取安装torch,国内镜像安装的是cpu版本。
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
下面直接使用命令行来实现训练,就不需要取改文件的路径;
- 使用YOLOv5的train.py脚本来训练模型,具体命令如下:
python3 train.py --img 640 --batch 16 --epochs 50 --data data.yaml --weights yolov5s.pt --device 0
–img:输入图像大小(这里为640x640)。
–batch:批次大小(这里为16)。
–epochs:训练轮数(这里为50)。
–data:数据集配置文件路径(这里为data.yaml)。
–weights:预训练模型权重文件(这里为yolov5s.pt)。
–device:设备编号(0表示使用第一个GPU)。
- 使用YOLOv5的val.py脚本来验证模型性能,具体命令如下:
python3 val.py --img 640 --batch 16 --data data.yaml --weights runs/train/exp/weights/best.pt --device 0
–weights:训练好的模型权重文件路径(这里为runs/train/exp/weights/best.pt)
- 使用YOLOv5的detect.py脚本来进行目标检测,具体命令如下:
python3 detect.py --source ../coco/val2017 --weights runs/train/exp/weights/best.pt --img 640 --conf 0.25 --device 0
–source:待检测的图像或视频文件路径(这里为…/coco/val2017)。
–conf:置信度阈值(这里为0.25)。
将训练好的YOLOv5模型转换为ONNX格式
确保你已经安装了必要的依赖项,尤其是onnx和onnx-simplifier:
pip install onnx onnx-simplifier
- 使用export.py脚本导出ONNX模型
在YOLOv5目录中运行以下命令,将训练好的模型转换为ONNX格式:
python3 export.py --weights runs/train/exp/weights/best.pt --img 640 --batch 1 --device 0 --simplify
–weights:训练好的模型权重文件路径(这里为runs/train/exp/weights/best.pt)。
–img:输入图像大小(这里为640x640)。
–batch:批次大小(通常为1)。
–device:设备编号(0表示使用第一个GPU)。
–simplify:使用ONNX Simplifier来简化模型。
加载.onnx代码
import onnxruntime as ort
import numpy as np
import cv2def preprocess(image_path, input_size):# 加载图像img = cv2.imread(image_path)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 调整图像大小img = cv2.resize(img, (input_size, input_size))# 标准化图像img = img / 255.0# 转换为NCHW格式img = np.transpose(img, (2, 0, 1)).astype(np.float32)# 添加批次维度img = np.expand_dims(img, axis=0)return imgdef postprocess(output, conf_threshold=0.5, iou_threshold=0.4):# 假设输出为 (1, num_boxes, 6) 形状,6 包含 (x, y, w, h, conf, class_id)output = output[0] # 提取第一个批次的输出boxes = output[:, :4]scores = output[:, 4]class_ids = output[:, 5].astype(np.int32)# 过滤低置信度检测mask = scores > conf_thresholdboxes = boxes[mask]scores = scores[mask]class_ids = class_ids[mask]# 非极大值抑制indices = cv2.dnn.NMSBoxes(boxes.tolist(), scores.tolist(), conf_threshold, iou_threshold)boxes = [boxes[i] for i in indices]scores = [scores[i] for i in indices]class_ids = [class_ids[i] for i in indices]return boxes, scores, class_idsdef infer(image_path, model_path, input_size=640):# 加载ONNX模型session = ort.InferenceSession(model_path)# 获取模型输入名称input_name = session.get_inputs()[0].name# 预处理图像img = preprocess(image_path, input_size)# 推理outputs = session.run(None, {input_name: img})# 打印输出内容for i, output in enumerate(outputs):print(f"Output {i}: {output.shape}")# 后处理boxes, scores, class_ids = postprocess(outputs[0])return boxes, scores, class_ids# 推理示例
image_path = './image.jpg'
model_path = './model.onnx'boxes, scores, class_ids = infer(image_path, model_path)# 打印检测结果
for box, score, class_id in zip(boxes, scores, class_ids):print(f"Class ID: {class_id}, Score: {score}, Box: {box}")
详细解释
- Class ID:这是检测到的对象的类别ID。在你的例子中,所有检测的对象类别ID为0。你可以根据你训练模型时的类别列表(data.yaml文件中的names字段)来确定类别ID对应的实际对象名称。
- Score:这是置信度分数,表示模型认为这个检测框中包含对象的概率。在你的例子中,置信度分数分别是0.838, 0.784, 0.700, 0.534。
- Box:这是检测框的坐标和尺寸。格式为 [中心点x坐标, 中心点y坐标, 宽度, 高度]。