基于YOLO的国家电网变电站缺陷检测算法及数据集验证及分析主机侧规范接口实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、YOLO是什么?

YOLO 是基于 的一种工具,该工具是为了解决数据分析任务而创建的。

二、使用步骤YOLO进行变电站缺陷检测

1.训练变电站缺陷数据集

根据国家电网的规范,变电站缺陷检测的类别包括如下:
包含如下缺陷类别:
表盘模糊
表盘破损
外壳破损
表计读数有误
绝缘子破裂
地面油污
硅胶变色
硅胶体破损
箱门闭合异常
高空悬浮物
鸟巢
盖板破损
未带安全帽
未穿工装
吸烟
ywzt_yfyc
kgg_ybh
``每个类别样本约500张图像,数据集共8000张高质量标注的电站缺陷图像。

  #变电站缺陷数据集联系方式为aricojf@163.com
  weightConfiFile = "./config/weights/PowerStationDefectModelConfig.yaml"  # 国网电站缺陷检测模型配置文件
    modelConfig = Global.configData.models["PowerStationDefectModelConfig"]  # 国网电站缺陷检测模型配置属性,临时没有用,但这样可以取出配置

    modelManager = ModelManager(modelConfig)
    modelManager.initModel()

    imgsz = modelConfig.imgsz
    confThres = modelConfig.confThres
    targetFPS = Global.configData.coreConfig.targetFPS

    # 线程方式
    # streamReadServer = LoadStreams(ROOT / "stream.txt", img_size=imgsz, stride=stride, auto=pt, vid_stride=1)
    # bs = len(streamReadServer)
    # videoNodeManager.setWHFS(streamReadServer.sources,streamReadServer.width,streamReadServer.height,streamReadServer.fps)
    # 进程方式
    streamReadServer = NBStreamReadServer(__interruptedAI__, ROOT / "stream.txt", targetFPS=targetFPS,
                                          enableLetterBox=True,
                                          img_size=imgsz, stride=modelManager.model.stride, auto=modelManager.model.pt,
                                          videoNodeManager=videoNodeManager)
    if __interruptedAI__.value:
        # 如果启动时,流读取进程无法连接源而处于不断尝试状态时,后来收到接口关闭AI消息,从而被打断,则退出推理进程
        print(f'AI Inference Exit!')
        torch.cuda.empty_cache()
        __aiStatus__.value = AIServerRunningStatus.SERVER_STATUS_STOP.value
        stopViewCV2ImgServer()
        return
    streamReadServer.start()
    bs = len(streamReadServer)

    # 6.Run inference
    modelManager.model.warmup(imgsz=(1 if modelManager.model.pt else bs, 3, *imgsz))  # warmup
    dt, seen = [0.0, 0.0, 0.0], 0

2.验证变电站缺陷检测数据集

代码如下(示例):

#变电站缺陷数据集联系方式为aricojf@163.com
#!/usr/bin/python3.9
# -*- coding: utf-8 -*-
# @Time    : 2023/5/11 上午8:33
# @Author  : aricochen
# @Email   : aricojf@163.com
# @File    : httpMain.py
# @Software: PyCharm

"""
国家电网智能分析接口实现。
本实现基于国家电网智能分析规范实现。<<500330)千伏及以上变电站远程智能巡视系统技术规范(试行).pdf>>
本代码目前基于规范实现了电站缺陷检测。
#!/usr/bin/python3.9
# -*- coding: utf-8 -*-
# @Time    : 2023/5/11 上午8:33
# @Author  : aricochen
# @Email   : aricojf@163.com
# @File    : httpMain.py
# @Software: PyCharm
"""

from aricojf.common import Global
import numpy as np
import torch
import os
from pathlib import Path
from utils.general import (non_max_suppression, scale_boxes)
from utils.plots import Annotator, colors, save_one_box
import cv2
from pathlib import Path
import torch
import time
from flask import Flask, jsonify, request, abort, render_template
from easydict import EasyDict
import json
import requests
import uuid
import queue
import threading
from ftplib import FTP_TLS, FTP
from urllib.parse import urlparse
from aricojf.common.ConfigManager import updateModelWeightConfig, updateConfigKeyData
from aricojf.common.Logging import getLogger

logger = getLogger()
# =============================配置信息Begin=================================
# 国家电网,智能分析主机规则配置文件
powerStationDefectConfig = Global.configData.rules["PowerStationDefectRuleConfig"]
# 全局数据保存根目录
dataRoot = Global.configData.coreConfig.dataRoot
logger.info(f'全局数据保存根目录(项目根目录下的相对目录):{dataRoot}')
# --推理结果保存目录(相对项目根目录)
rsSaveDir = powerStationDefectConfig.rsSaveDir
logger.info(f'推理结果保存目录(相对全局数据保存根目录):{rsSaveDir}')
# http推理生成的图像保存目录
httpInferenceImagesDir = os.path.join(os.getcwd(), dataRoot, rsSaveDir)
logger.info(f'推理结果保存目录绝对目录:{httpInferenceImagesDir}')
if not Path(httpInferenceImagesDir).exists():
    Path(httpInferenceImagesDir).mkdir(parents=True)
# 生成推理结果后本机httpServer图像的相对URL
inferenceRelativeURL = powerStationDefectConfig.inferenceRelativeURL
app = Flask(__name__, static_folder=httpInferenceImagesDir, static_url_path=inferenceRelativeURL)
logger.info(f'Server Static目录:{httpInferenceImagesDir}')
logger.info(f'Server static url:{inferenceRelativeURL}')
# =============================配置信息End=================================
# ===========================国网图像缺陷分析报文模板Begin===========================================
# 1.三方请求图像分析报文格式 N.3.1
picAnalyseTemp = {
    "requestHostIp": "127.0.0.1",
    "requestHostPort": 20011,
    "requestId": "110",
    "objectList": [
        {
            "objectId": "123",
            "typeList": [],
            "imageNormalUrlPath": "",
            "imageUrlList": [
                "http://localhost:20011/defectImages/test/biandian_05293.jpg",
                "http://localhost:20011/defectImages/test/biandian_05294.jpg",
                "http://localhost:20011/defectImages/test/biandian_05295.jpg",
                "http://localhost:20011/defectImages/test/biandian_05296.jpg",
                "http://localhost:20011/defectImages/test/biandian_05297.jpg",
                "http://localhost:20011/defectImages/test/biandian_05298.jpg",
                "http://localhost:20011/defectImages/test/biandian_05300.jpg"
            ]
        }
    ]
}

# 2.本系统分析结果反馈报文格式 N.3.2
picAnalyseRetNotifyTemp = {
    "requestId": "110",
    "resultsList": [
        {
            "objectId": "123",
            "type": [],
            "value": [],
            "code": "",
            "resImageUrl": "",
            "pos": [],
            "conf": [],
            "desc": ""
        }
    ]
}
# 3.三方请求算法更新报文格式 N.3.3
algorithmUpdateTemp = {
    "requestHostIp": "127.0.0.1",
    "requestHostPort": 20011,
    "requestId": "120",
    "algorithmPath": "ftp://aricochen:chendeben@aricojfServer:21/home/aricochen/mask.txt"
}
# ===========================国网图像缺陷分析报文模板End===========================================

# =======================================================================
# 全局变量
model = None
rsServer = None
modelManager = None
httpInferCount = 0
modelStatus = 1  # 模型状态,1:正常,0:更新中,不能推理


class RSPostServer(threading.Thread):
    def __init__(self, responseImgAnalysePortURL, responseAlgorithmUpdateURL, rsHttpServer, interruptedAI):
        super().__init__()
        self.responseImgAnalysePortURL = responseImgAnalysePortURL
        self.responseAlgorithmUpdateURL = responseAlgorithmUpdateURL
        self.rsHttpServer = rsHttpServer
        self.rsQueue = queue.Queue()
        self.__is_interrupted__ = interruptedAI

    def putRS(self, rs):
        self.rsQueue.put(rs)

    def run(self):
        """
        反馈缺陷检测到巡视主机,
        规范文件章节: N.3.2
        :return:
        """
        while not self.__is_interrupted__.value:
            action, rs = self.rsQueue.get()
            requestHostIp = rs.requestHostIp
            requestHostPort = rs.requestHostPort
            requestId = rs.requestId
            # ========1.  n311:巡视主机发送图像识别请求处理======
            try:
                if action == "n311":
                    logger.info(f'推理三方的图像')
                    objectList = rs.objectList
                    responsePostURL = self.responseImgAnalysePortURL  # 测试阶段使用
                    responsePostURL = "http://" + requestHostIp + ":" + str(requestHostPort) + "/picAnalyseRetNotify"
                    # 处理每一个obj
                    for idx, obj in enumerate(objectList):
                        logger.info(f'处理图像:{idx}')
                        objectId = obj.objectId
                        typeList = obj.typeList
                        imageUrlList = obj.imageUrlList
                        # imageNormalUrlPath = obj.imageNormalUrlPath 临时不用此字段
                        #处理每一幅图像
                        for imageURL in imageUrlList:
                            # 读取图像
                            logger.info(f'    读取图像:{imageURL}')
                            try:
                                image_bytes = requests.get(imageURL).content
                                image_np1 = np.frombuffer(image_bytes, dtype=np.uint8)
                                image_np2 = cv2.imdecode(image_np1, cv2.IMREAD_COLOR)
                            except Exception as e:
                                logger.error(e)
                                image_np2 =None
                            if image_np2 is None:  # 图像读取错误
                                logger.error(f'    图像读取错误!')
                                data = EasyDict()
                                data.requestId = requestId
                                data.resultsList = []
                                obj = EasyDict()
                                obj.objectId = objectId
                                rs = EasyDict()
                                rs.type = ""
                                rs.value = ""
                                rs.code = "2001"
                                rs.resImageUrl = ""
                                rs.pos = []
                                rs.conf = []
                                rs.desc = []
                                obj.results = [rs]
                                data.resultsList.append(obj)
                                # 转换为json
                                jsonData = json.dumps(data)
                                # 发送识别反馈
                                headers = {
                                    "Content-Type": "application/json; charset=UTF-8"
                                }
                                logger.info(f'    反馈三方错误!')
                                res = requests.post(responsePostURL, data=jsonData, headers=headers)

                                logger.info(f'    三方响应:{res}')
                                continue
                            else:  # 图像读取正确,进行推理
                                logger.info(f'    图像读取SUCESS!')
                                imgIDXPath, imgURL, clsIDList, enNameList, zhNameList, xyxyList, confList = predictImg(
                                    requestId,
                                    image_np2,
                                    typeList)
                                data = EasyDict()
                                data.requestId = requestId
                                data.resultList = []
                                obj = EasyDict()
                                obj.objectId = objectId
                                results = []
                                for idx, clsID in enumerate(clsIDList):
                                    rs = EasyDict()
                                    rs.type = enNameList[idx]
                                    rs.value = ""
                                    rs.code = "2000"
                                    rs.resImageUrl = f"{self.rsHttpServer}{imgURL}"
                                    rs.pos = [{"areas": [{"x": xyxyList[idx][0], "y": xyxyList[idx][1]},
                                                         {"x": xyxyList[idx][2], "y": xyxyList[idx][3]}]}]
                                    rs.conf = confList[idx]
                                    rs.desc = zhNameList[idx]
                                    results.append(rs)
                                obj.results = results
                                data.resultList.append(obj)
                                # 转换为json
                                jsonData = json.dumps(data)
                                # 发送识别反馈
                                headers = {
                                    "Content-Type": "application/json; charset=UTF-8"
                                }
                                logger.info(f'    反馈三方:{jsonData}')
                                res = requests.post(responsePostURL, data=jsonData, headers=headers)
                                logger.info(f'    三方响应:{res}')
            except Exception as e:
                logger.error(f'推理或推理结果发送三方反馈错误:{e}')
            # ========2.  n331:巡视主机发送算法更新请求处理======
            try:
                if action == "n331":
                    logger.info(f'处理三方发送模型更新请求...')
                    algorithmPath = rs.algorithmPath
                    responsePostURL = self.responseAlgorithmUpdateURL  # 测试阶段使用
                    responsePostURL = "http://" + requestHostIp + ":" + str(requestHostPort) + "/algorithmUpdateResult"
                    ret, modelFile, isEncrypt = downloadWeight(algorithmPath)
                    if not ret:  # download失败
                        logger.error(f'模型下载失败1:{modelFile}')
                        data = EasyDict()
                        data.requestId = requestId
                        data.result = "0"
                        # 转换为json
                        jsonData = json.dumps(data)
                        # 发送识别反馈
                        headers = {
                            "Content-Type": "application/json; charset=UTF-8"
                        }
                        logger.error(f'    反馈三方错误!')
                        res = requests.post(responsePostURL, data=jsonData, headers=headers)
                        logger.error(f'    三方响应:{res}')
                        return
                    logger.info(f'    模型下载成功!')
                    logger.info(f'    更新模型...')
                    ret, rs = updateModel(modelFile, isEncrypt) #模型下载成功,进行模型更新
                    # 反馈三方模型更新情况
                    data = EasyDict()
                    data.requestId = requestId
                    headers = {
                        "Content-Type": "application/json; charset=UTF-8"
                    }
                    if not ret:
                        logger.error(f'    更新模型失败:{rs}')
                        data.result = "0"
                    else:  # 模型更新成功
                        logger.info(f'    更新模型SUCESS')
                        data.result = "1"
                    jsonData = json.dumps(data)
                    logger.info(f'    反馈三方...')
                    res = requests.post(responsePostURL, data=jsonData, headers=headers)
                    logger.info(f'    三方响应:{res}')
            except Exception as e:
                logger.error(f'模型升级或模型升级发送三方反馈错误:{e}')


def setHttpModel(_modelManager, interruptedAI):
    global modelManager, model, device, rsServer
    modelManager = _modelManager
    model = modelManager.model
    responseImgAnalysePortURL = powerStationDefectConfig.responseImgAnalysePortURL  # 识别结果反馈三方URL
    responseAlgorithmUpdateURL = powerStationDefectConfig.responseAlgorithmUpdateURL  # 模型更新反馈三方URL
    rsHttpServer = powerStationDefectConfig.rsHttpServer + powerStationDefectConfig.inferenceRelativeURL  # 反馈给三方的可访问本地推理文件的相对地址
    rsServer = RSPostServer(responseImgAnalysePortURL, responseAlgorithmUpdateURL, rsHttpServer,
                            interruptedAI=interruptedAI)
    rsServer.start()


@app.route('/')
def helloPowerStationDefect():
    return 'Hello!THIS IS ALGORITHM OF POWER STATION DEFECT  by aricojf 2023.05'


@app.route('/mypost')
def mypost():
    """
    页面模板测试
    :return:
    """
    return render_template("test.html")


# ==================本机模拟三方接口-->>接收本机反馈接口 Begin=========================
@app.route('/picAnalyseRetNotify', methods=["POST"])
def picAnalyseRetNotify():
    """
    测试用,模拟推理结果反馈给三方url
    :return:
    """
    try:
        get_Data = request.get_data()
        # # 判断传入的json数据是否为空
        if get_Data is None or get_Data == "":
            logger.warn(f'收到非法数据')
            return jsonify(code=400)
        # 传入的参数为bytes类型,需要转化成json
        get_Data = json.loads(get_Data)
        data = EasyDict(get_Data)
        logger.info(f'-----------------模拟三方接口:推理反馈结果------------------------')
        logger.info(data)
        return jsonify(code=200)
    except Exception as e:
        logger.error(f'三方模拟接口:推理反馈结果错误:{e}')
        return jsonify(code=500)


@app.route('/algorithmUpdateResult', methods=["POST"])
def algorithmUpdateResult():
    """
    测试用,模拟模型更新结果反馈给三方url
    :return:
    """
    try:
        get_Data = request.get_data()
        # # 判断传入的json数据是否为空
        if get_Data is None or get_Data == "":
            logger.warn(f'收到非法数据')
            return jsonify(code=400)
        # 传入的参数为bytes类型,需要转化成json
        get_Data = json.loads(get_Data)
        data = EasyDict(get_Data)
        logger.info(f'-----------------模拟三方接口:模型更新反馈结果------------------------')
        logger.info(data)
        return jsonify(code=200)
    except Exception as e:
        logger.error(f'三方模拟接口:模型更新反馈结果错误:{e}')
        return jsonify(code=500)


# ==================本机模拟三方接口-->>接收本机反馈接口 End=========================

# ====================本机提供的供三方request请求的接口 Begin========================
@app.route(powerStationDefectConfig.requestImgAnalyseRelaURL, methods=["POST"])
def picAnalyse():
    """
    国家电网分析主机,分析缺陷,接收推理数据接口.
    规范文件章节: N.3.1
    :return:
    """
    global rsServer, modelStatus
    if modelStatus == 0:  # 模型更新中,不可用
        return jsonify(code=500)
    try:
        get_Data = request.get_data()
        # # 判断传入的json数据是否为空
        if get_Data is None or get_Data == "":
            logger.warn(f'国家电网分析主机,分析缺陷,接收推理数据接口->收到非法数据')
            return jsonify(code=400)
        # 传入的参数为bytes类型,需要转化成json
        get_Data = json.loads(get_Data)
        data = EasyDict(get_Data)
        logger.info(f'====>>>Request国家电网分析主机,分析缺陷,接收推理数据接口->接收到的数据:{data}')
        # 数据合法性验证
        isDataValidate, e = checkPicAnalysePackage(data)
        if not isDataValidate:
            logger.warn(f'国家电网分析主机,分析缺陷,接收推理数据接口->缺少必要数据:{e}')
            return jsonify(code=400)
        rsServer.putRS(("n311", data))
        return jsonify(code=200)
    except Exception as e:
        logger.error(f'错误:{e}')
        return jsonify(code=500)


@app.route(powerStationDefectConfig.requestAlgorithmUpdateURL, methods=["POST"])
def algorithmUpdate():
    """
    三方算法模型更新请求。
    规范章节:N.3.3
    :return:
    """
    global rsServer
    try:
        get_Data = request.get_data()
        # # 判断传入的json数据是否为空
        if get_Data is None or get_Data == "":
            logger.warn(f'国家电网分析主机,分析缺陷,三方算法模型更新请求接口->收到非法数据')
            return jsonify(code=400)
        # 传入的参数为bytes类型,需要转化成json
        get_Data = json.loads(get_Data)
        data = EasyDict(get_Data)
        logger.info(f'====>>>Request国家电网分析主机,分析缺陷,三方算法模型更新请求接口->接收到的数据:{data}')
        # 数据合法性验证
        isDataValidate, e = checkModelUpdatePackage(data)
        if not isDataValidate:
            logger.warn(f'国家电网分析主机,分析缺陷,三方算法模型更新请求接口->缺少必要数据:{e}')
            return jsonify(code=400)
        rsServer.putRS(("n331", data))
        return jsonify(code=200)
    except Exception as e:
        logger.error(f'三方算法模型更新请求错误:{e}')
        return jsonify(code=500)




# 更新算法模型
def downloadWeight(algorithmPath):
    """
    下载模型权重,
    权重命名规则:
    1. 只有1个后缀,则认为是未加密权重,如:
      exam.onnx,exam2.pt,examp.engine
    2.如果有2个后缀,则认为是加密后缀,如
      *.onnx.aes,*.pt.aes
    3.如果有多个后缀,则认为不合法,下载失败
    :param algorithmPath:根据规范此路径是ftps路径,ftp://username:password@url
    :return: True/False:成功与否,weightName:权重文件名,加密后缀去除,可直接保存和加载,isEncrypt:是否加密的模型
    """
    # 需要确定path格式再实现
    logger.info(f'    模型下载地址:{algorithmPath}')
    rs = urlparse(algorithmPath)
    scheme = rs.scheme
    userName = rs.username
    password = rs.password
    host = rs.hostname
    port = rs.port
    path = rs.path
    modelPath, modelFile = os.path.split(path)
    isEncrypt = True
    d = modelFile.split(".")
    if len(d) == 3:  # *.onx.aes
        modelName, modelType, x = d
    elif len(d) == 2:
        modelName, modelType = d
        isEncrypt = False
    logger.info(f'    模型加密:{isEncrypt}')
    newModelFilePath = os.path.join(os.getcwd(), "weights", modelFile)  # 存放算法模型文件
    # saveModelDir = "/opt/project/2023/PowerTD/PowerStationDefect/3_Inference/weights/mask.txt"
    logger.info(f'    模型存放目录:{newModelFilePath}')
    try:
        logger.info(f'    下载路径信息:host:{host},port:{port},user:{userName},password:{password}')
        logger.info(f'    模型路径:{modelPath},模型文件:{modelFile},模型类型:{modelType}')
        # ftp = FTP_TLS(host, userName,password) #注意规范中描述的使用ftps路径,bug:提示需要登录
        ftp = FTP()  # 注意规范中描述的使用ftps路径
        ftp.connect(host=host, port=port)
        ftp.login(user=userName, passwd=password)
        ftp.cwd("/")
        # print(f'{ftp.dir()}')
        with open(newModelFilePath, 'wb') as f:
            ftp.retrbinary('RETR ' + path, f.write)
        logger.info(f'    模型文件下载完毕!')
        return True, modelName + "." + modelType, isEncrypt
    except Exception as e:
        logger.error(f'    算法模型下载出错:{e}')
        return False, "模型下载失败!", None


# 更新配置文件的权重配置且加载最新模型
def updateModel(modelFile, isEncrypt):
    """
    更新配置文件的权重配置
    :param modelFile: 权重文件名,权重文件需要是aes加密过的,且存在 weights/:return:
    """
    global modelManager, model, modelStatus
    modelStatus = 0  # 0更新中,1更新完毕,可正常工作
    # 1.更新最新模型地址配置
    updateModelWeightConfig(modelManager.modelConfigFile, "weights/" + modelFile)
    updateConfigKeyData(modelManager.modelConfigFile, key="isEncrypt", value=isEncrypt)
    # 2.更新模型
    modelManager.reset()
    model = modelManager.model
    modelStatus = 1

    return True, ""


# 三方图像推理请求,报文合法性检查
def checkPicAnalysePackage(picAnalysisData):
    """
    检查数据格式是否正确
    :param picAnalysisData: 三方请求的推理数据包,EasyDict类型
    :return:
    """
    if not hasattr(picAnalysisData, "requestHostIp"):
        return False, "不存在requestHostIp属性"
    if not hasattr(picAnalysisData, "requestHostPort"):
        return False, "不存在requestHostPort属性"
    if not hasattr(picAnalysisData, "requestId"):
        return False, "不存在requestId属性"
    if not hasattr(picAnalysisData, "objectList"):
        return False, "不存在objectList属性"
    if not isinstance(picAnalysisData.objectList, list):
        return False, "objectList不是列表"
    if len(picAnalysisData.objectList) == 0:
        return False, "objectList为空"
    for obj in picAnalysisData.objectList:
        if not hasattr(obj, "objectId"):
            return False, "不存在objectId属性"
        if not hasattr(obj, "typeList"):
            return False, "不存在typeList属性"
        if not hasattr(obj, "imageNormalUrlPath"):
            return False, "不存在imageNormalUrlPath属性"
        if not hasattr(obj, "imageUrlList"):
            return False, "不存在imageUrlList属性"
        if not isinstance(obj.imageUrlList, list):
            return False, "imageUrlList不是列表"
    return True, ""


# 三方请求模型更新报文检查
def checkModelUpdatePackage(updateModelData):
    """
    检查数据格式是否正确
    :param updateModelData:模型更新请求
    :return:
    """
    if not hasattr(updateModelData, "requestHostIp"):
        return False, "不存在requestHostIp属性"
    if not hasattr(updateModelData, "requestHostPort"):
        return False, "不存在requestHostPort属性"
    if not hasattr(updateModelData, "requestId"):
        return False, "不存在requestId属性"
    if not hasattr(updateModelData, "algorithmPath"):
        return False, "不存在algorithmPath属性"
    return True, ""


# 时间戳
def getDateTimeS(ct):
    local_time = time.localtime(ct)
    data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
    stamp = data_head
    return stamp


def getDateTimeUUID(ct):
    local_time = time.localtime(ct)
    data_head = time.strftime("%Y%m%d%H%M%S", local_time)
    stamp = data_head
    return stamp


def inferenceHTTP():
    app.run(powerStationDefectConfig.httpLocalIP, powerStationDefectConfig.httpLocalPort)
    #
    # server = pywsgi.WSGIServer(('0.0.0.0', 20011), app)
    # server.serve_forever()

该处使用的url网络请求的数据。


提高变电站缺陷检测的准确率和召回率

为了提高缺陷检测的检测的准确率和召回率,您需要高质量的大型电站缺陷数据集,才能提供算法效率。变电站缺陷大型数据集联系方式为aricojf@163.com

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值