前言
前段时间,YOLOv5推出7.0版本,主要更新点是在目标检测的同时引入了实例分割。
目前,YOLOv5团队已经转向了YOLOv8的更新,因此,7.0版本大概率是YOLOv5的最终稳定版。
更新信息
官方公告中给出了YOLOv5-7.0的更新要点:
推出了基于coco-seg的实例分割预训练模型
Yolov5-seg的变动
仔细对比yolov5的目标检测与分类的代码框架,主要的改动点在以下几个方面:
1. 训练、测试、验证等的代码入口;
2. 数据加载和预处理;
3. 网络变动;
4. loss的变动;
5. 评价指标。
下载预训练模型
官方仓库有不同模型大小的预训练模型,这里以yolov5m-seg为例。
下载链接:https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5m-seg.pt
数据集的文件结构如下:
- screen-seg
- images
- train2017
- labels
- train2017
- images
其中第一个为类别标签,后面的两个为一组,即(x1,y1),(x2,y2)…意为一个个点,这些点连线即为所框选的实例。
模型训练
下面以coco128-seg数据集训练为例,首先修改screen-seg.yaml
配置文件,修改相应路径:
-
path: screen-seg
-
train: images/train2017
-
val: images/train2017
之后终端运行:
数据集制作:
github地址:https://github.com/vietanhdev/anylabeling
在 YOLO 和 Segment Anything 的 AI 支持下轻松进行数据标记!
AnyLabeling = LabelImg + Labelme + Improved UI + Auto-labeling
任何标签 = 标签Img + 标签我 + 改进的用户界面 + 自动标签
油管演示:https://www.youtube.com/watch?v=xLVz-f6OeUY
- 安装和运行
- 下载并运行可执行文件
从版本下载并运行最新版本。
创建环境:
conda create -n anylabeling python=3.8
conda activate anylabeling
安装任何标签:
pip install anylabeling
运行应用:
anylabeling
使用教程:
shapes:保存着bbox的类别和坐标(左上角,右下角);
imagePath:json文件对应的原图名称;
imageHeight:原图的高度;
imageWidth:原图的宽度;
我们现在要将json文件中的标注信息提取到txt文件中,代码实现如下:
import os
import json
import numpy as np
# 类和索引
CLASSES=["person","horse"]
def convert(size,box):
'''''
input:
size:(width,height);
box:(x1,x2,y1,y2)
output:
(x,y,w,h)
'''
dw=1./size[0]
dh=1./size[1]
x=(box[0]+box[1])/2.0
y=(box[2]+box[3])/2.0
w=box[1]-box[0]
h=box[3]-box[2]
x=x*dw
w=w*dw
y=y*dh
h=h*dh
return (x,y,w,h)
# json -> txt
def json2txt(path_json,path_txt):
with open(path_json,"r") as path_json:
jsonx=json.load(path_json)
width=int(jsonx["imageWidth"]) # 原图的宽
height=int(jsonx["imageHeight"]) # 原图的高
with open(path_txt,"w+") as ftxt:
# 遍历每一个bbox对象
for shape in jsonx["shapes"]:
obj_cls=str(shape["label"]) # 获取类别
cls_id=CLASSES.index(obj_cls) # 获取类别索引
points=np.array(shape["points"]) # 获取(x1,y1,x2,y2)
x1=int(points[0][0])
y1=int(points[0][1])
x2=int(points[1][0])
y2=int(points[1][1])
# (左上角,右下角) -> (中心点,宽高) 归一化
bb=convert((width,height),(x1,x2,y1,y2))
ftxt.write(str(cls_id)+" "+" ".join([str(a) for a in bb])+"\n")
if __name__=="__main__":
# json文件夹
dir_json="C:\\Users\\26818\\Desktop\\test\\input\\"
# txt文件夹
dir_txt="C:\\Users\\26818\\Desktop\\test\\out\\"
if not os.path.exists(dir_txt):
os.makedirs(dir_txt)
# 得到所有json文件
list_json=os.listdir(dir_json)
# 遍历每一个json文件,转成txt文件
for cnt,json_name in enumerate(list_json):
print("cnt=%d,name=%s"%(cnt,json_name))
path_json=dir_json+json_name
path_txt=dir_txt+json_name.replace(".json",".txt")
# (x1,y1,x2,y2)->(x,y,w,h)
json2txt(path_json,path_txt)
生成的txt文件如下图所示,格式包括(类别索引,x,y,w,h)