全自动打标签工具开发过程(以yolo_obbmaster为例)

       经过对各个版本的调查发现我目前用的这套yolo十分的,简陋,所以功能实现会比正常版本复杂的多,所以如果你用的结构和我不同,我不建议认真对待这个文章,因为真的很草,建议你找找更相关的东东

        或者你可以从这个解决问题实现功能的过程汲取一下灵感

        如果你碰巧用上了和我这个结构类似的yolo,那么我为你感到悲哀,但是至少你还能找到我这篇文章,也算是不幸中的万幸。我这一套带角度识别且运行速度较原yolo快些,代码也更简洁,所以也不完全一无是处,需要的话可以留言私信要

我是个懒人,搞上一套数据集的时候用了近两万张,现在要进行数据集拓展和修正,有点不想弄了,于是就想着整个全自动打标签工具吧。我们用的yolo版本或者结构可能不同,但是应该也不会差多少,我这里提供一个思路,供大家学习和参考。

        但是说实话,我用的这套yolo算是十分简陋的了,只有最基本的功能所以需要改很多地方,如果你用的是基本的yolov5之类的,那会很简单只需要改个参数之类的就可以

        注:如果要进行全自动打标签,必须要有一个相对完善且完备的模型(数据集),如果没有,请先整一个,如果懒,可以使用半自动打标签方法

        可以参考以下链接

快速给语义分割任务打标签----eiseg教程_eiseg安装-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_36079986/article/details/128467417?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%8D%8A%E8%87%AA%E5%8A%A8%E6%A0%87%E6%B3%A8eiseg&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-128467417.142%5Ev100%5Epc_search_result_base9&spm=1018.2226.3001.4187        完成标注后,正常json转txt就可,如果你是用的obb,可以先json转正常txt然后进行计算得到obb的txt,代码太长我就不放了,如果你需要可以留言。

         然后是我用的yolo_mater项目的来源,但是现在源码没法下载了,想要的可以留言我给你发一份

YOLO5 旋转模型图片标注及训练_yolov5旋转框模型训练-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/My_Precision/article/details/128177301        下面开始全自动打标签的  大致  教程

        首先你要明白原理,全自动打标签,说白了就是用你原有的模型进行识别,如果你把置信度阈值放的很低,即便是没有标注过的东西也会多少识别出来一点,这样识别到你想要的东西之后,保存识别的图片,并且保存相关参数与信息,然后你就可以再进行二次修改让它成为可以训练的数据集然后就Ok了。

        运行初始代码的话也会保存图片和数据,但是运行后识别图像会覆盖,到最后只剩一张,且所有识别内容都保存在同一个txt里,很大便

        正常yolov5只需要在这里修改就可以实现功能,但是这个不可以,你从他简陋的参数选择就可以看出(save-txt我修改过,没用)

  审视全部代码后,最核心的代码部分就在这里

其中rbox2txt是对识别到的东西的数据进行处理和记录

plot_one _rotated_box是对识别到的东西进行识别框绘制,如果你要进行数据集处理,那么最后保存的图片最好是不带识别框的,防止影响训练,可以在labelme之类的里面通过记录的数据进行查看和修改,所以如果你想这样,就直接把这个删掉。

然后顺着引用去找rbox2txt,为如下

def rbox2txt(rbox, classname, conf, img_name, out_path, pi_format=False):
    """
    将分割图片的目标信息填入原始图片.txt中
    @param robx: rbox:[tensor(x),tensor(y),tensor(l),tensor(s),tensor(θ)]
    @param classname: string
    @param conf: string
    @param img_name: string
    @param path: 文件夹路径 str
    @param pi_format: θ是否为pi且 θ ∈ [-pi/2,pi/2)  False说明 θ∈[0,179]
    """
    if isinstance(rbox, torch.Tensor):
        rbox = rbox.cpu().float().numpy()

    #rbox = np.array(x)
    if pi_format:  # θ∈[-pi/2,pi/2)
        rbox[-1] = (rbox[-1] * 180 / np.pi) + 90  # θ∈[0,179]

    # rect=[(x_c,y_c),(w,h),Θ] Θ:flaot[0-179]  -> (-180,0)
    rect = longsideformat2cvminAreaRect(rbox[0], rbox[1], rbox[2], rbox[3], (rbox[4] - 179.9))
    # poly = [(x1,y1),(x2,y2),(x3,y3),(x4,y4)]
    poly = np.float32(cv2.boxPoints(rect))  # 返回rect对应的四个点的值
    poly = np.int0(poly).reshape(8)

    splitname = img_name.split('__')  # 分割待merge的图像的名称 eg:['P0706','1','0','_0']
    oriname = splitname[0]  # 获得待merge图像的原图像名称 eg:P706

    # 目标所属图片名称_分割id 置信度 poly classname
    lines = img_name + ' ' + conf + ' ' + ' '.join(list(map(str, poly))) + ' ' + classname
    # 移除之前的输出文件夹,并新建输出文件夹
    if not os.path.exists(out_path):
        os.makedirs(out_path)  # make new output folder

    with open(str(out_path + '/' + oriname) + '.txt', 'a') as f:
        f.writelines(lines + '\n')

通过观察可以知道这就是保存识别内容到txt的部分,但是由于识别图像始终在相互覆盖导致图片有且只有“0.png”,这个命名被引用到这里后所有的识别内容就都被写进同一个0.txt里了,所以首要目标是修改代码中的oriname引用来源

oriname来自于splitname[0],splitname[0]来自于img_name,所以一劳永逸的方法就是修改img_name,这个img_name引自源代码的Path(p).stem

已知最后保存的txt名称都是0.txt,根据 with open(str(out_path + '/' + oriname) + '.txt', 'a') as f:

可以直接推测oriname和splitname[0]和img_name和Path(p).stem就只是个纯名称或数字,所以可以直接把Path(p).stem随便改成个整数变量,然后再进行字符化保存,完成后整数+1,这样就能避免txt相互覆盖。

这里直接在全代码前面加一个ddd定义,然后在detect函数内gobal一下(不global会报错的)

然后把后面Path(p).stem改成ddd,执行完之后ddd+1就完成了第一步

还没完,回到txt部分会发现他对原命名进行了一些处理,这些处理直接用在我们的整数型变量上会报错,所以直接删了算了,即如下部分

splitname = img_name.split('__')  # 分割待merge的图像的名称 eg:['P0706','1','0','_0']
oriname = splitname[0]  # 获得待merge图像的原图像名称 eg:P706

,并且把最后的oriname改成img_name,并且由于整数型不能直接参与文件处理,所以加一个str化

with open(str(out_path + '/' + str(img_name)) + '.txt', 'a') as f:
        f.writelines(lines + '\n')

然后是对保存的数据进行修改,obb对数据的要求是

类别,x,y,长,宽,角度

就直接根据这个进行修改lines就好

到这txt部分就完事了,下一步需要整图片保存

图片保存是和save_path绑定的,所以就去找这部分

找到了

save_path = str(Path(out) / Path(p).name)  # 图片保存路径+图片名字

直接改成字符化的ddd就好

这下运行后就没啥问题了

然后,如果你想进行labelme的标签查看和修改,需要把txt改为xml格式,这个网上有很多教程

但是!

草的是,我要用的是rolabeimg,导致两者结构不一样,并且还差很多东西,所以需要自己手动对转换代码进行修改,改成恰当的格式后就能使用rolabelimg了

未训练肯定会有偏差,此时就可以手动进行识别框微调或者分类调整(忽略potato)

然后整完了再xml转txt,然后txt再使用官方的tranform转为训练格式即可。

ps:如果你用的是半自动打标签,那也是多边形json转txt,然后txt转xml,然后xml转txt,然后txt转训练格式,其中txt转xml的时候由于没有角度参数需要进行计算,这也是个大坑,有需要的我可以给资源或者教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值