复杂数据集,召回、精度等突破方法记录【以电科院过检识别模型为参考】

news2024/11/28 18:43:05

目录

一、数据分析与数据集构建

二、所有相关的脚本

三、模型效果


一、数据分析与数据集构建

由于电科院数据集有17w-18w张,标签错误的非常多,且漏标非常多,但是所有有效时间只有半个月左右,显卡是M60,训练速度特别慢,所以需要尽量留足训练时间,至少是1周左右,而且为了保证训练的轮数尽量多,还需要使得数据集尽量有效,减少冗余

数据复杂情况如下:

由于只训练缺陷类,效果难以达到较好的情况,所以这里考虑加入正常数据,作为辅助,做法流程是:

只筛选缺陷看看带出来多少正常——在里面剔除不需要的类(这里是6和19)——然后由于正常类不能和异常交叉存在,所以剔除和异常交叉的正常类的标,IOU阈值取0.5

得到数据情况如下:

 由于“绝缘子正常”太多,这里考虑删除一部分,使得绝缘子正常的数量也能在1000-2000,做法是先统计“5_class27_0518_接着剔除和异常交叉的正常_0.5_抽取绝缘子正常”,然后统计每个类和绝缘子共存的情况,看看哪些较多,能否剔除该类中共存的绝缘子达到目的,数据统计如下:

可见绝缘子并不是很大一部分分布在某一个或者几个类里面的,所以这里无法剔除,只是对“绝缘子破损”进行增强来弥补该类的数据不足

最终训练使用的数据是“6_2_class27_0518_接着剔除和异常交叉的正常_0.5_split”,然后将数据20-25%作为val,其余进行train,进行训练,寻找最佳的方法

数据集每类平衡的规则是:不足2000的增强到2000幅,补充的对照样本(绝缘子正常等)不足1000的增强到1000,尽量均衡的前提下正样本不能多

寻找到最佳方法后,所有是train,不留val,使得尽量多的数据参与训练,以得到最佳模型

二、所有相关的脚本

1_abcd当指定类和它相关类iou过大时剔除该指定类

import os

def calculate_iou(box1, box2):
    # 提取边界框的坐标和尺寸
    x1, y1, w1, h1 = box1[1:]
    x2, y2, w2, h2 = box2[1:]
    # 计算边界框的右下角坐标
    x1_right, y1_bottom = x1 + w1, y1 + h1
    x2_right, y2_bottom = x2 + w2, y2 + h2
    # 计算相交区域的坐标
    x_intersect = max(x1, x2)
    y_intersect = max(y1, y2)
    x_intersect_right = min(x1_right, x2_right)
    y_intersect_bottom = min(y1_bottom, y2_bottom)
    # 计算相交区域的宽度和高度
    intersect_width = max(0, x_intersect_right - x_intersect)
    intersect_height = max(0, y_intersect_bottom - y_intersect)
    # 计算相交区域的面积
    intersect_area = intersect_width * intersect_height
    if intersect_area<0.000001:
        return 1
    # 计算两个边界框的面积
    box1_area = w1 * h1
    box2_area = w2 * h2
    # 计算最小并集
    whole_area = float(box1_area + box2_area - intersect_area)
    min_area = float(min(box1_area,min(box2_area,whole_area)))
    # 计算IOU
    iou = intersect_area /min_area
    return iou

def filter_annotations(queding_id,id_list,filename):
    list1 = []
    list2 = []
    filtered_annotations = []
    with open(filename, 'r') as file:
        lines = file.readlines()
        print('all:\n',lines)
        for line in lines:
            class_label, x, y, width, height = line.split(' ')
            x, y, width, height = float(x), float(y), float(width), float(height)
            class_id = int(class_label)
            if int(class_id) == queding_id:
                list1.append([class_id, x, y, width, height])
            elif int(class_id) in id_list:
                list2.append([class_id, x, y, width, height])
            else:
                filtered_annotations.append(line)

        for annotation1 in list1:
            iou_greater_than_0_2 = False
            for annotation2 in list2:
                iou = calculate_iou(annotation1, annotation2)
                if iou > 0.2:
                    print('iou,',iou)
                    iou_greater_than_0_2 = True
                    break
            if not iou_greater_than_0_2:
                line_dst1 = str(annotation1[0])+" "+str(annotation1[1])+" "+str(annotation1[2])+" "+str(annotation1[3])+" "+str(annotation1[4])+"\n"
                filtered_annotations.append(line_dst1)
        for annotation2 in list2:
            line_dst2 = str(annotation2[0])+" "+str(annotation2[1])+" "+str(annotation2[2])+" "+str(annotation2[3])+" "+str(annotation2[4])+"\n"
            filtered_annotations.append(line_dst2)
    
    with open(filename,"w",encoding="utf-8") as f:
        for line in filtered_annotations:
            f.write(line)

    return filtered_annotations


if __name__=='__main__':
    """
    queding_id = 0
    id_list = [1,2,3,4]
    --------------------------
    queding_id = 5
    id_list = [6,7]
    --------------------------
    queding_id = 10
    id_list = [11,12,13]
    """
    queding_id = 10
    id_list = [11,12,13]
    folder_path='./1_class27'
    for root,_,files in os.walk(folder_path):
        if len(files)>0:
            for file in files:
                if file.endswith('.txt'):
                    print('---------------')
                    print(file)
                    file_path=os.path.join(root,file)
                    res = filter_annotations(queding_id,id_list,file_path)
                    for l in res:
                        print(l)

2splitImgAndLabelByLabelid

# -*- encoding:utf-8 -*- 
import os
import cv2
import sys
import shutil
from pathlib import Path

suffixs = [".png"]

if len(sys.argv) != 2:
    print("input as:\n python 1splitImgAndLabelByLabelid.py imgFolder")
    sys.exit()

path = sys.argv[1]

if not os.path.exists(path):
    print("sorry, you input empty floder ! ")
    sys.exit()

file_type_list = ['txt']

for name in os.listdir(path):
    print("-"*20)
    print("name,",name)
    file_path=os.path.join(path,name)
    file_type=file_path.split('.')[-1]

    for suffix in suffixs:
        file_name=file_path[0:file_path.rfind('.', 1)]+suffix
        if os.path.exists(file_name):
            image=cv2.imread(file_name)
            if image is None:
                continue
            else:
                break

    if(file_type in file_type_list):
        bef=open(file_path)
        ids=[]
        for line in bef.readlines():
            linenew = line.strip().split(" ")
            if len(linenew) == 5:
                ids.append(int(linenew[0]))
        ids_len=len(ids)
        if ids_len == 0:
            save_path = "empty"
            if not os.path.exists(save_path):
                os.mkdir(save_path)
            shutil.move(file_path,save_path)
            shutil.move(file_name,save_path)
        elif ids_len == 1:
            save_path = str(ids[0])
            if not os.path.exists(save_path):
                os.mkdir(save_path)
            shutil.move(file_path,save_path)
            shutil.move(file_name,save_path)
        else:
            ids.sort()
            if ids[0] == ids[-1]:
                save_path = str(ids[0])
                if not os.path.exists(save_path):
                    os.mkdir(save_path)
                shutil.move(file_path,save_path)
                shutil.move(file_name,save_path)
            else:
                save_path = "various"
                if not os.path.exists(save_path):
                    os.mkdir(save_path)
                shutil.move(file_path,save_path)
                shutil.move(file_name,save_path)
        print(ids)

3_copyfilesbyclassid

# encoding:utf-8

import os
import cv2
import shutil

suffixs = [".JPG",".PNG",".bmp",".jpeg",".jpg",".png"]

def backup_txt_files(src_dir, dst_dir):
    for root,_,files in os.walk(src_dir):
        for file in files:
            if file.endswith('.txt'):
                # select label
                src_path = os.path.join(root, file)
                rel_path = os.path.relpath(src_path,src_dir)
                dst_path = os.path.join(dst_dir, rel_path)
                new_label_data = []
                with open(src_path, "r", encoding="utf-8") as f:
                    for line in f:
                        line_tmp = line.strip().split(" ")
                        if len(line_tmp) == 5:
                            if int(line_tmp[0]) == 6 :
                                continue
                            line_dst = line_tmp[0]+" "+line_tmp[1]+" "+line_tmp[2]+" "+line_tmp[3]+" "+line_tmp[4]+"\n"
                            new_label_data.append(line_dst)
                if len(new_label_data)>0:
                    # process label
                    dst_folder=os.path.dirname(dst_path)
                    os.makedirs(dst_folder, exist_ok=True)
                    with open(dst_path,"w",encoding="utf-8") as f:
                        for line in new_label_data:
                            f.write(line)
                    # process image
                    for suffix in suffixs:
                        file_name=src_path[0:src_path.rfind('.', 1)]+suffix
                        if os.path.exists(file_name):
                            image=cv2.imread(file_name)
                            if image is not None:
                                shutil.copy(file_name, dst_folder)
                                break

# 指定源路径和备份路径(最好使用绝对路径)
src_dir = 'various'
dst_dir = 'various_6'

# 执行备份操作
backup_txt_files(src_dir, dst_dir)

4_ccccc补充various到单类中

# encoding:utf-8

import os
import shutil
from termios import PARODD
import cv2
import random


def backup_txt_files(src_dir, sample_dir,class_id,num_thresh):
    src_num_files = len([f for f in os.listdir(src_dir) if os.path.isfile(os.path.join(src_dir, f))])//2
    if src_num_files > num_thresh:
        exit()
    # 
    search_res=[]
    for root,_,files in os.walk(sample_dir):
        for file in files:
            if file.endswith('.txt'):
                flag = False
                label_path = os.path.join(root, file)
                with open(label_path, "r", encoding="utf-8") as f:
                    for line in f:
                        line_tmp = line.strip().split(" ")
                        if len(line_tmp) == 5:
                            if int(line_tmp[0]) == class_id :
                                flag = True
                if flag == False:
                    continue
                file_name=label_path[0:label_path.rfind('.', 1)]+".jpg"
                if os.path.exists(file_name):
                    image=cv2.imread(file_name)
                    if image is not None:
                        search_res.append((file_name,label_path))
    # shuf
    random.shuffle(search_res)
    sample_num_files = len(search_res)//2
    # 
    save_path=src_dir+"_various"
    os.makedirs(save_path,exist_ok=True)
    # 
    add_num = num_thresh - src_num_files
    print(src_dir,'    ',src_num_files,'    ',add_num)
    if sample_num_files < add_num:
        for file,label in search_res:
            shutil.move(file,save_path)
            shutil.move(label,save_path)
    else:
        for i in range(add_num):
            shutil.move(search_res[i][0],save_path)
            shutil.move(search_res[i][1],save_path)

# 指定源路径和备份路径(最好使用绝对路径)
src_dir = 'single'
sample_dir = 'various'
num_thresh = 3000

# 执行备份操作
for folder in os.listdir(src_dir):
    print('-'*40)
    backup_txt_files(os.path.join(src_dir,folder),sample_dir,int(folder),num_thresh)

5_dedadada当指定类标过多时删去标抹去标签区域

import os
import random
import cv2

def process(label_path,class_id):
    if label_path.endswith('.txt'):
        # select label
        # print('-'*40)
        # print('label_path,',label_path)
        new_label_data = []
        with open(label_path, "r", encoding="utf-8") as f:
            for line in f:
                line_tmp = line.strip().split(" ")
                if len(line_tmp) == 5:
                    if int(line_tmp[0]) == class_id :
                        # print(class_id)
                        # process image
                        file_name=label_path[0:label_path.rfind('.', 1)]+'.jpg'
                        if os.path.exists(file_name):
                            # print('draw&ignore   ',class_id,'    ',file_name)
                            image=cv2.imread(file_name)
                            if image is not None:
                                # class_label = line_tmp[0]
                                x, y, width, height = map(float, line_tmp[1:])
                                x_min = int((x - width/2) * image.shape[1])
                                y_min = int((y - height/2) * image.shape[0])
                                x_max = int((x + width/2) * image.shape[1])
                                y_max = int((y + height/2) * image.shape[0])
                                cv2.rectangle(image, (x_min, y_min), (x_max, y_max), (125, 125, 125), -1)
                                cv2.imwrite(file_name,image)
                        # ignore label
                        continue
                    line_dst = line_tmp[0]+" "+line_tmp[1]+" "+line_tmp[2]+" "+line_tmp[3]+" "+line_tmp[4]+"\n"
                    # print('~~~~liuxia,',int(line_tmp[0]),class_id,line_dst)
                    new_label_data.append(line_dst)

        # print('new_label_data,',new_label_data)
        with open(label_path,"w",encoding="utf-8") as f:
            for line in new_label_data:
                f.write(line)


def getfilelistbyclassid(path,class_id,ignoreid):
    file_list=[]
    for folder in os.listdir(path):
        if ignoreid==1:
            if str(class_id) in folder:
                continue
        elif ignoreid==2:
            if str(class_id)+"_various" != folder:
                continue

        folder_path=os.path.join(path,folder)
        for file in os.listdir(folder_path):
            if file.endswith('.txt'):
                label_path=os.path.join(folder_path,file)
                with open(label_path, "r", encoding="utf-8") as f:
                    for line in f:
                        line_tmp = line.strip().split(" ")
                        if len(line_tmp) == 5:
                            if int(line_tmp[0]) == class_id :
                                file_list.append(label_path)
                                break
    return file_list


if __name__=='__main__':
    id_list = [0,1]
    path='./images'

    for class_id in id_list:
        # print('-'*40)
        # print('dddd,',class_id)
        id_path=os.path.join(path,str(class_id))
        file_num=len([f for f in os.listdir(id_path) if os.path.isfile(os.path.join(id_path, f))])//2
        if file_num > 1000:
            # 当前超出限制,把当前之外的抹去(注意当前的还未处理,需要加,2023年05月20日11:44:58)
            for folder in os.listdir(path):
                if folder == str(class_id):
                    continue
                for file in os.listdir(os.path.join(path,folder)):
                    if file.endswith('.txt'):
                        label_path = os.path.join(os.path.join(path,folder), file)
                        process(label_path,class_id)
        else:
            various_id_path=os.path.join(path,str(class_id)+"_various")
            various_file_num=len([f for f in os.listdir(id_path) if os.path.isfile(os.path.join(id_path, f))])//2
            file_various_num=various_file_num+file_num
            if file_various_num < 1000:
                # 另外的超出的标抹去
                file_list=getfilelistbyclassid(path,class_id,ignoreid=1)
                if len(file_list)+file_various_num>1000:
                    random.shuffle(file_list)
                    for i in range(len(file_list)+file_various_num-1000):
                        process(file_list[i],class_id)
            else:
                # various超出的标抹去
                various_file_list=getfilelistbyclassid(path,class_id,ignoreid=2)
                random.shuffle(various_file_list)
                for i in range(len(various_file_list)+file_num-1000):
                    process(various_file_list[i],class_id)    
                # 另外的需要全部抹去
                other_file_list=getfilelistbyclassid(path,class_id,ignoreid=1)
                random.shuffle(other_file_list)
                for i in range(len(other_file_list)):
                    process(other_file_list[i],class_id)   


        # 抹去数据过多类的标:
        # 0,5,10,12,15,20,23
        # 1、如单类大于1000
        #     则删除various及其他中的标,同时抹去图像上的区域
        # 2、如单类小于1000,但是结合various大于1000
        #     则删除其他中的标,同时抹去图像上的区域
        # 3、单类+various还是小于1000
        #     则在其他中找到满足1000,则删除剩余的标,同时抹去图像上的区域

三、模型效果

待补充

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

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

相关文章

linux防火墙之iptables

一、iptables概述 Linux 系统的防火墙 &#xff1a;IP信息包过滤系统&#xff0c;它实际上由两个组件netfilter 和 iptables组成。 主要工作在网络层&#xff0c;针对IP数据包。体现在对包内的IP地址、端口、协议等信息的处理上。 netfilter&#xff1a; 属于“内核态”&…

Java基础重温巩固

方法 方法与方法之间是平级关系&#xff0c;不能嵌套return表示结束当前方法 基本数据类型和引用数据类型 基本数据类型&#xff1a;数据存储在自己的空间中 引用数据类型&#xff1a;数据存储在其他空间中&#xff0c;自己空间存储的是地址值 值传递 传递基本数据类型时&…

详解Windows系统安装TensorRT

目录 下载TensorRT安装TensorRT测试 TensorRT 是 NVIDIA 推出的一款高性能神经网络部署引擎.Windows系统下TensorRT目前不能简单直接通过pip指令自动下载安装, 安装之前还需要提前安装好 CUDA 和 CUDNN. CUDA和CUDNN安装可参考: 详解 Windows系统下安装 CUDA 与 CUDNN. &…

ES6之Module:export、import

文章目录 前言一、export命令1.export2.export default&#xff08;默认暴露&#xff09; 二、import命令1.通用导入方式2.解析赋值导入方式 三、结果总结 前言 ES6之前&#xff0c;JavaScript语言一直没有模块&#xff08;Module&#xff09;体系&#xff0c;无法将一个大型程…

《计算机网络——自顶向下方法》精炼——3.5.1-3.5.4

人生像攀登一座山,而找寻出路,却是一种学习的过程,我们应当在这过程中,学习稳定、冷静,学习如何从慌乱中找到生机。——席慕蓉 文章目录 TCPTCP协议概述报文段结构序号、确认号 超时问题计算RTT计算重传时间 可靠数据传输 TCP TCP协议概述 TCP是面向连接的协议&#xff0c;在…

nest笔记十一:一个完整的nestjs示例工程(nestjs_template)

概述 链接&#xff1a;nestjs_template 相关文章列表 nestjs系列笔记 示例工程说明 这个工程是我使用nestjs多个项目后&#xff0c;总结出来的模板。这是一个完整的工程&#xff0c;使用了yaml做为配置&#xff0c;使用了log4js和redis和typeorm&#xff0c;sawgger&#…

Less和sass安装及使用

CSS预处理器 由来 CSS本身不是一种编程语言。你可以用它开发网页样式&#xff0c;但是没法用它编程。换句话说&#xff0c;CSS基本上是设计师的工具&#xff0c;不是程序员的工具。它并不像其它程序语言&#xff0c;比如说JavaScript等&#xff0c;有自己的变量、常量、条件语…

手把手教你验证upd与tcp“端口”开发策略

系列文章目录 文章目录 系列文章目录前言一、问题&#xff1f;二、验证网络策略步骤三、增强验证网络策略总结 前言 这篇文章&#xff0c;本意是让大家了解除了常用的telnet之外&#xff0c;在运维过程中&#xff0c;如果在服务器中未发现相关命令还可以借用像ssh、wget 等命令…

震惊!我的电脑居然中病毒了,快来看看我是如何解决的

打开电脑就自动跳转到http://www.exinariuminix.info/ 问题背景 今天刚打开电脑&#xff0c;然后电脑莫名奇妙就自动跳转到http://www.exinariuminix.info/网页&#xff1a; 联网后加载&#xff0c;它就自动重定向到一个莫名其妙的网站&#xff1a; 问题原因 出于好奇&#…

大数据Doris(二十四):Doris数据Insert Into导入方式介绍

文章目录 Doris数据Insert Into导入方式介绍 一、语法及参数 二、案例 三、注意事项 1、关于插入数据量 2、关于insert操作返回结果 3、关于导入任务超时 4、关于Session变量 5、关于数据导入错误 Doris数据Insert Into导入方式介绍 Doris 提供多种数据导入方案&…

SpringMVC执行原理

目录结构 pom.xml依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!-- https://mvnrepository.co…

【Java校招面试】实战面经(五)

目录 前言一、讲讲short数据类型&#xff0c;short s1 1; s1 s11;对不对&#xff1f;二、使用final关键字的好处三、如果String中重写equals不重写hashCode会出现什么问题&#xff1f;四、ConcurrentHashMap的get方法是不加锁的&#xff0c;如何保证线程安全&#xff1f;五、…

缓存存在的问题

文章目录 缓存问题缓存穿透引入解决方案 缓存雪崩缓存击穿 缓存问题 使用缓存时常见的问题主要分为三个&#xff1a;缓存穿透 、缓存雪崩、缓存击穿。 下面对其进行一一学习 缓存穿透 引入 定义&#xff1a;缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#…

20230521给coolpi4b开发板刷Android12和串口的使用

20230521给coolpi4b开发板刷Android12和串口的使用 2023/5/21 9:31 所需要的配件&#xff1a; 1、2.0mm转2.54mm的杜邦线母头2条&#xff08;2位一起的一条&#xff09; 2、串口板&#xff1a;CH340&#xff08;WIN7下使用&#xff09; 3、USB的公头-公头线 首先&#xff0c;欢…

微星MSI GE66 10SF-416RU电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件配置 硬件型号驱动情况 主板Intel HM470 处理器Intel Core i7-10875H 2.30GHz up to 5.10GHz已驱动 内存Kingston Fury Impact DDR4 2x16Gb 3200mhz已驱动 硬盘NT…

Redis介绍及Linux单机安装

1.Redis介绍 1.1.什么是Redis Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 Redis是完全开源的&#…

OpenCV人脸识别QT上位机(含源码)

OpenCV Releases&#xff1a;4.6.0 开发平台&#xff1a;QT 6.4.0 编译环境&#xff1a;MSVC 2019 64bit 主要功能&#xff1a;1、预处理图片 2、生成CSV文件 3、生成识别器文件等功能。主要用于学习opencv的整个流程和实现一些简单的功能&#xff0c;比如识别指定的人脸并显…

安卓与串口通信-实践篇

前言 在上一篇文章中我们讲解了关于串口的基础知识&#xff0c;没有看过的同学推荐先看一下&#xff0c;否则你可能会不太理解这篇文章所述的某些内容。 这篇文章我们将讲解安卓端的串口通信实践&#xff0c;即如何使用串口通信实现安卓设备与其他设备例如PLC主板之间数据交互…

【计算机网络复习】第五章 数据链路层 1

数据链路层的作用 两台主机&#xff08;端到端&#xff09;之间的通信是依靠相邻的主机/路由器之间的逐步数据传送来实现 数据链路层实现相邻主机/路由器间的可靠的数据传输 网络层&#xff1a;主机-主机通信 数据链路层&#xff1a;点到点通信 数据链路层的主要功能 u 链路…

3R幸福法

3R幸福法 3R幸福法可以帮助我们《建立和谐亲密关系》 模型介绍 3R幸福法体现的是一个人被关注的完整逻辑&#xff1a; Reson-理由&#xff0c;关注缘起。不会让你想表达的感情看起来显得唐突&#xff0c;不会让对方和自己不好意思。Respond-反应&#xff0c;是关注影响。更多…