sahi切片辅助训练推理

news/2024/7/10 2:44:17 标签: 深度学习, 人工智能, 目标检测, YOLO, pytorch

本文的目的切片yolov5标注格式的数据,并保存图片和标注文件

代码实现步骤如下

  1. 把yolov5格式转换成coco格式标签;
  2. 切片图片和coco标签;
  3. 把切片出来的coco标签转换回yolov5标签格式
# 1. 把yolov5格式转换成coco格式标签;
# 2. 切片图片和coco标签;
# 3. 把切片出来的coco标签转换回yolov5标签格式

import os
import numpy as np
import cv2
from sahi.utils.coco import Coco, CocoCategory, CocoImage, CocoAnnotation
from sahi.slicing import slice_coco
from sahi.utils.file import save_json

def convert2coco(img_path,h,w,yololabel):

    coco = Coco()
    maps = {
        0 : 'person',
        1 : 'soccer'
    }
    coco.add_category(CocoCategory(id=0, name='person')) # 两个类别
    coco.add_category(CocoCategory(id=1, name='soccer'))

    coco_image = CocoImage(file_name=img_path, height=h, width=w)
    
    for label in yololabel:

        coco_image.add_annotation(
        CocoAnnotation(
            bbox=[label[1], label[2], label[3], label[4]],
            category_id=int(label[0]),
            category_name=maps[label[0]]
        )
        )
    
    coco.add_image(coco_image)
    coco_json = coco.json
    save_json(coco_json, "coco_dataset.json")
    return coco_json

def convert2xywh(l,h,w): # 把(class cx xy w h)转换成左上角wh
    new_l = np.zeros_like(l)
    l[:,1] = l[:,1]*w
    l[:,3] = l[:,3]*w
    l[:,2] = l[:,2]*h
    l[:,4] = l[:,4]*h
    
    new_l[:,0] = l[:,0]
    new_l[:,1] = l[:,1] - l[:,3]/2
    new_l[:,2] = l[:,2] - l[:,4]/2
    new_l[:,3] = l[:,3] 
    new_l[:,4] = l[:,4]
    
    return new_l

def slice_img(save_img_dir):
    
    coco_dict, coco_path = slice_coco(
                coco_annotation_file_path="coco_dataset.json",
                image_dir='',
                slice_height=640,
                slice_width=640,
                overlap_height_ratio=0.2,
                overlap_width_ratio=0.2,
                output_dir = save_img_dir,
                output_coco_annotation_file_name = 'sliced'
            )
    return 

def convert2yolov5(coco_dir,save_img_dir,save_label_dir):
    
    coco = Coco.from_coco_dict_or_path(coco_dir, save_img_dir)
    # export converted YoloV5 formatted dataset into given output_dir with a 85% train/15% val split
    coco.export_as_yolov5(
    output_dir=save_label_dir,
    disable_symlink = True
    )
    
    return 

if __name__ == '__main__':
    file = 'SNMOT-061'
    img_dir = f'datasets/soccernet/tracking/images/train/{file}/img1/'
    anno_dir = f'datasets/soccernet/tracking/labels/train/{file}/img1/'
    save_img_dir = 'datasets/sliced_soccernet/images/train/' + f'{file}/' # 把切分的图片保存到这里
    save_label_dir = 'datasets/sliced_soccernet/labels/train/' + f'{file}/'
    os.makedirs(save_img_dir,exist_ok=True)
    os.makedirs(save_label_dir,exist_ok=True)
    labels = os.listdir(anno_dir)
    for label in labels:
        if 'old' not in label:
            try:
                os.remove('coco_dataset.json') # 删除中间文件
                os.remove(save_img_dir+'sliced_coco.json')
            except:
                pass
            l = np.loadtxt(anno_dir+label,delimiter=' ') # class cx xy w h
            img_path = img_dir+label.replace('txt','jpg')
            img = cv2.imread(img_path)
            h,w,_ = img.shape
            new_l = convert2xywh(l,h,w)
            coco_json = convert2coco(img_path,h,w,new_l)
            slice_img(save_img_dir)  # 切分图片并保存
            convert2yolov5(save_img_dir+'sliced_coco.json', save_img_dir,save_label_dir) # 把切分完的coco标签转换回yolo格式并保存
            
            
    
            # for ll in new_l: # 验证是否转换正确
            #     if int(ll[0]) == 0:
            #         cv2.rectangle(img,(int(ll[1]),int(ll[2])),(int(ll[1]+ll[3]),int(ll[2]+ll[4])),(255,0,255),2)
            #     else:
            #         cv2.rectangle(img,(int(ll[1]),int(ll[2])),(int(ll[1]+ll[3]),int(ll[2]+ll[4])),(255,0,2),2)         
            # cv2.imwrite('./test.jpg',img)
            
            

在上述的基础上需要修改一下sahi的源码,它默认会保存图片的,注释掉:
在这里插入图片描述

在这里插入图片描述

最终结果
在这里插入图片描述
在这里插入图片描述
转换完成后,可视化代码:

import os
import cv2


# train_lists = os.listdir('datasets/soccernet/tracking/images/train')

# for tl in train_lists:

root = 'datasets/sliced_soccernet/images/train/' + 'SNMOT-061/'
# root2 = 'datasets/soccernet/tracking/images2/train/'+'Vision_State.v4i.yolov8'+'/images/'
sum = 0
train_list = os.listdir(root)

for img in train_list:
    if not img.endswith('jpg'):
        continue
    res = []
    ball_bbox = []
    data = cv2.imread(root+img)
    ih,iw,c = data.shape
    try:
        anno = open(root.replace('images','labels')+img[:-4]+'.txt').read().splitlines()
    except:
        continue
    for an in anno:
        a = an.split(' ')
        cls,x,y,w,h = int(a[0]),float(a[1]),float(a[2]),float(a[3]),float(a[4])
        x = int(iw*x)
        y = int(ih*y)
        w = int(w*iw)
        h = int(h*ih)
        if int(cls)==1:
            cv2.rectangle(data,(x-w//2,y-h//2),(x+w//2,y+h//2),(255,255,0),2)
            ball_bbox.append([x-w//2,y-h//2,w,h])
            pass
        else:
            res.append([x-w//2,y-h//2,x+w//2,y+h//2])
            cv2.rectangle(data,(x-w//2,y-h//2),(x+w//2,y+h//2),(0,0,255),2)
            pass
    # if len(ball_bbox) > 0:
    #     crop_img = data[max(0,ball_bbox[0][1]-50):ball_bbox[0][1]+ball_bbox[0][3]+50,max(0,ball_bbox[0][0]-50):ball_bbox[0][0]+ball_bbox[0][2]+50]

        save_dir = 'outimg/' + root
        os.makedirs(save_dir,exist_ok=True)
        cv2.imwrite(os.path.join(save_dir,img),data)
    

http://www.niftyadmin.cn/n/5104378.html

相关文章

mysql宋红康第一篇

mysql宋红康第一篇 索引的数据结构 为什么使用索引? 索引是存储引擎用于快速找到数据记录的一种数据结构,就好比一本教科书的目录部分,通过目录中找到对应文章的页码,便可快速定位到需要的文章。MySQL中也是一样的道理&#xf…

最详细的Keycloak教程(建议收藏):Keycloak实现手机号、验证码登陆——(二)Keycloak与SpringBoot的集成

上一篇已经介绍了keycloak的下载与使用: Keycloak的下载与使用 本文章和大家分享keycloak怎么去集成springboot项目,以及怎么去做接口权限的校验。 PS:根据红帽的公告,目前在springboot 3.x版本已经不支持keycloak适配器,所以本章…

WWW-Authenticate 头字段和 Authorization 头字段的区别

WWW-Authenticate 头字段和 Authorization 头字段是 SIP 摘要认证中的两个不同的头字段,它们在认证过程中扮演不同的角色: WWW-Authenticate 头字段: WWW-Authenticate 头字段由 SIP 服务器或代理发送给客户端(通常是 SIP User Ag…

扫描全能王文档矫正逆向记录

背景 扫描全能王有个功能是将弯曲的文本拉直成平直的文本。在扫描全能王的app上,这个功能的入口在拍书籍的tab。同时在图片编辑页面,也有个按钮可以触发这个功能。它的效果大概如下。 这篇文章主要介绍如何逆向这个算法 初步定位 对扫描王apk初步逆向…

HTML中, 在同一行上出现高低不一样的文字,处理对齐效果

<!doctype html> <html><head><meta charset"utf-8"><title>vertical-align属性</title><style type"text/css">span{font-size:8px;}</style></head><body><p>参考内容<span style…

1811_spacemacs从v.0.200.13升级到v.0.200.14的几点变化感受

全部学习汇总&#xff1a; GreyZhang/editors_skills: Summary for some common editor skills I used. (github.com) 安装了全新的spacemacs的配置&#xff0c;查看了一下版本是v.0.200.14。在此之前&#xff0c;我使用的版本是v.0.200.13。现在还没有在这个配置上完成我所有的…

十六章:Java8的其它新特性

16.1&#xff1a;Lambda表达式 package com.jiayifeng.java;import org.junit.Test;import java.util.Comparator; import java.util.function.Consumer;/*** author 爱编程的小贾* create 2023-10-19 12:29** 一&#xff1a;Lambda表达式的使用* 1.举例&#xff1a;(o1,…

微信小程序开发之自定义组件(会议OA项目其他页面搭建)

目录 前言 一、WeChat中的自定义组件 1. 基本概述 2. 包含文件及作用 3. 自定义组件的作用 4.使用步骤&#xff1a; 二、tabs组件及会议管理布局 tabs组件 1. 创建组件 准备 创建 使用组件 会议管理布局 tabs.wxml指定组件模版 tabs.wxss完成样式设计 tabs.js定义属…