当前位置: 首页 > news >正文

做网站前的准备制作网站作品

做网站前的准备,制作网站作品,海淀专业企业网站建设,株洲网站建设技术公司detect文件框架 一、导入模块包二、定义run函数1. 归一化操作代码解析uint8精度转换归一化 2. 扩展维度为什么扩展维度#xff1f;代码解释 3. 对检测结果类别计数检查是否有检测结果统计每个类别的出现次数构建描述性字符串 三、定义命令行参数四、主函数 本帖是YOLOV5推理部… detect文件框架 一、导入模块包二、定义run函数1. 归一化操作代码解析uint8精度转换归一化 2. 扩展维度为什么扩展维度代码解释 3. 对检测结果类别计数检查是否有检测结果统计每个类别的出现次数构建描述性字符串 三、定义命令行参数四、主函数 本帖是YOLOV5推理部分代码的中文逐行注释。由于AI注释的缘故可能与源码会有小部分出入所以不建议复制粘贴替换源码的detect.py文件。本贴的初衷是YOLOV5源码逻辑的学习后续会不断修正该代码和加入新的注释。 一、导入模块包 import argparse # 引入argparse库用于解析命令行参数 import os # 引入os库用于进行操作系统相关的操作 import platform # 引入platform库用于获取平台信息 import sys # 引入sys库用于操作Python运行时环境 from pathlib import Path # 引入Path库用于处理文件和目录路径import cv2 # 引入OpenCV库用于图像处理 import torch # 引入PyTorch库用于深度学习 FILE Path(__file__).resolve() # 获取当前文件的绝对路径 ROOT FILE.parents[0] # 获取当前文件的父目录路径if str(ROOT) not in sys.path: # 如果当前文件的父目录路径不在系统路径中sys.path.append(str(ROOT)) # 将当前文件的父目录路径添加到系统路径中ROOT Path(os.path.relpath(ROOT, Path.cwd())) # 将ROOT路径相对于当前工作目录进行转换from ultralytics.utils.plotting import Annotator, colors, save_one_box from models.common import DetectMultiBackend # 从models.common模块中导入DetectMultiBackend类 from utils.dataloaders import LoadImages, LoadStreams # 从utils.dataloaders模块中导入LoadImages和LoadStreams类 from utils.general import ( # 从utils.general模块中导入多个函数和类LOGGER,Profile,check_file,check_img_size,check_imshow,check_requirements,colorstr,cv2,increment_path,non_max_suppression,print_args,scale_boxes,strip_optimizer,xyxy2xywh, ) from utils.torch_utils import select_device, smart_inference_mode # 从utils.torch_utils模块中导入select_device和time_sync和smart_inference_mode函数二、定义run函数 smart_inference_mode() def run(weightsyolov5s.pt, # 模型权重文件路径默认值为yolov5s.ptsourcedata/images, # 输入源可以是文件、目录、URL或摄像头默认值为data/imagesdatadata/coco128.yaml, # 数据集配置文件路径默认值为data/coco128.yamlimgsz640, # 输入图像尺寸默认值为640conf_thres0.25, # 置信度阈值默认值为0.25iou_thres0.45, # 非极大值抑制的IoU阈值默认值为0.45max_det1000, # 每张图像的最大检测数量默认值为1000device, # 使用的设备可以是cpu或cuda:0默认值为view_imgFalse, # 是否显示检测结果默认值为Falsesave_txtFalse, # 是否将检测结果保存到文本文件默认值为Falsesave_confFalse, # 是否保存置信度默认值为Falsesave_cropFalse, # 是否保存裁剪后的检测框默认值为FalsenosaveFalse, # 是否保存图像/视频默认值为FalseclassesNone, # 按类别过滤例如0或0 2 3默认值为Noneagnostic_nmsFalse, # 是否使用类别无关的NMS默认值为FalseaugmentFalse, # 是否使用增强推理默认值为FalsevisualizeFalse, # 是否可视化特征默认值为FalseupdateFalse, # 是否更新所有模型默认值为Falseprojectruns/detect, # 保存结果的项目路径默认值为runs/detectnameexp, # 保存结果的文件夹名称默认值为expexist_okFalse, # 是否允许现有项目名称默认值为Falseline_thickness3, # 边界框的厚度像素默认值为3hide_labelsFalse, # 是否隐藏标签默认值为Falsehide_confFalse, # 是否隐藏置信度默认值为FalsehalfFalse, # 是否使用FP16半精度推理默认值为FalsednnFalse, # 是否使用OpenCV DNN进行ONNX推理默认值为Falsevid_stride1, # 视频帧率步幅默认值为1 ):# 将source变量转换为字符串source str(source)# 判断是否需要保存推理后的图像除非指定了--nosave或source是文本文件save_img not nosave and not source.endswith(.txt) # 判断source是否是一个图像或视频文件is_file Path(source).suffix[1:] in (IMG_FORMATS VID_FORMATS)# 判断source是否是一个网络链接is_url source.lower().startswith((rtsp://, rtmp://, http://, https://))# 判断source是否是一个网络摄像头流或屏幕截图指令或一个有效的URLwebcam source.isnumeric() or source.endswith(.streams) or (is_url and not is_file)# 判断source是否是一个屏幕截图指令screenshot source.lower().startswith(screen)# 如果source是一个有效的URL并且指向一个文件下载这个文件if is_url and is_file:source check_file(source) # 创建保存结果的目录如果存在则覆盖或增量命名save_dir increment_path(Path(project) / name, exist_okexist_ok) # 创建用于保存标签的子目录(save_dir / labels if save_txt else save_dir).mkdir(parentsTrue, exist_okTrue) # 加载模型并选择设备CPU或GPUdevice select_device(device)model DetectMultiBackend(weights, devicedevice, dnndnn, datadata, fp16half)# 获取模型的步幅、类别名以及模型是否是PyTorch模型stride, names, pt model.stride, model.names, model.pt# 检查并调整图像尺寸以适应模型的步幅imgsz check_img_size(imgsz, sstride) # 设置batch_size为1因为通常推理是单张图像进行bs 1 # 根据source类型选择数据加载方式if webcam:# 对于网络摄像头流检查是否可以显示图像view_img check_imshow(warnTrue)# 加载网络摄像头流数据dataset LoadStreams(source, img_sizeimgsz, stridestride, autopt, vid_stridevid_stride)# 确定batch_sizebs len(dataset)elif screenshot:# 加载屏幕截图数据dataset LoadScreenshots(source, img_sizeimgsz, stridestride, autopt)else:# 加载普通图像或视频数据dataset LoadImages(source, img_sizeimgsz, stridestride, autopt, vid_stridevid_stride)# 初始化视频路径和视频写入器列表vid_path, vid_writer [None] * bs, [None] * bs# 模型预热model.warmup(imgsz(1 if pt or model.triton else bs, 3, *imgsz)) # 初始化计数器和时间记录器seen, windows, dt 0, [], (Profile(devicedevice), Profile(devicedevice), Profile(devicedevice))# 遍历数据集中的每一张图片for path, im, im0s, vid_cap, s in dataset:# 测量预处理时间with dt[0]:# 将图像转换为Tensor并移至适当设备im torch.from_numpy(im).to(model.device)# 调整数据类型和归一化im im.half() if model.fp16 else im.float() im / 255 # 扩展维度以匹配batch_sizeif len(im.shape) 3:im im[None] # 如果模型是XML格式且batch_size大于1将图像拆分为多个部分if model.xml and im.shape[0] 1:ims torch.chunk(im, im.shape[0], 0)# 执行推理with dt[1]:# 可视化模式保存可视化结果visualize increment_path(save_dir / Path(path).stem, mkdirTrue) if visualize else False# 如果模型是XML格式且batch_size大于1逐个执行推理if model.xml and im.shape[0] 1:pred Nonefor image in ims:if pred is None:pred model(image, augmentaugment, visualizevisualize).unsqueeze(0)else:pred torch.cat((pred, model(image, augmentaugment, visualizevisualize).unsqueeze(0)), dim0)pred [pred, None]# 否则直接执行推理else:pred model(im, augmentaugment, visualizevisualize)# 进行非最大值抑制with dt[2]:pred non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_detmax_det)# 定义CSV文件路径csv_path save_dir / predictions.csv# 定义函数将预测数据写入CSV文件def write_to_csv(image_name, prediction, confidence):将预测数据写入CSV文件如果文件不存在则创建新文件。data {Image Name: image_name, Prediction: prediction, Confidence: confidence}with open(csv_path, modea, newline) as f:writer csv.DictWriter(f, fieldnamesdata.keys())if not csv_path.is_file():writer.writeheader()writer.writerow(data)# 处理预测结果for i, det in enumerate(pred): # 遍历每一张图片的预测结果seen 1 # 增加已处理图片的数量# 如果是网络摄像头流获取路径、原始图像和帧号if webcam: p, im0, frame path[i], im0s[i].copy(), dataset.counts f{i}: else:p, im0, frame path, im0s.copy(), getattr(dataset, frame, 0)# 将路径转换为Path对象p Path(p) # 构建保存图像的路径save_path str(save_dir / p.name) # 构建保存标签的路径txt_path str(save_dir / labels / p.stem) ( if dataset.mode image else f_{frame})# 更新打印字符串s %gx%g % im.shape[2:] # 计算归一化增益gn torch.tensor(im0.shape)[[1, 0, 1, 0]] # 为保存裁剪图像复制原始图像imc im0.copy() if save_crop else im0 # 创建Annotator对象用于在图像上绘制annotator Annotator(im0, line_widthline_thickness, examplestr(names))# 如果有检测结果if len(det):# 对每个类别进行计数for c in det[:, 5].unique():n (det[:, 5] c).sum() s f{n} {names[int(c)]}{s * (n 1)}, # 写入预测结果到CSV文件if save_csv:write_to_csv(p.name, label, confidence_str)# 将检测框坐标从模型输出大小缩放回原图大小det[:, :4] scale_boxes(im.shape[2:], det[:, :4], im0.shape).round()# 将检测结果写入文件或在图像上绘制for *xyxy, conf, cls in reversed(det):c int(cls) # 整数类别label names[c] if hide_conf else f{names[c]} confidence float(conf)confidence_str f{confidence:.2f}# 如果需要保存CSV文件写入数据if save_csv:write_to_csv(p.name, label, confidence_str)# 如果需要保存文本标签文件写入数据if save_txt: xywh (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() line (cls, *xywh, conf) if save_conf else (cls, *xywh) with open(f{txt_path}.txt, a) as f:f.write((%g * len(line)).rstrip() % line \n)# 如果需要保存图像或裁剪图像或显示图像在图像上绘制边界框if save_img or save_crop or view_img: c int(cls) label None if hide_labels else (names[c] if hide_conf else f{names[c]} {conf:.2f})annotator.box_label(xyxy, label, colorcolors(c, True))# 如果需要保存裁剪图像保存裁剪的检测框if save_crop:save_one_box(xyxy, imc, filesave_dir / crops / names[c] / f{p.stem}.jpg, BGRTrue)# 绘制结果im0 annotator.result()# 如果需要显示图像在窗口中显示if view_img:if platform.system() Linux and p not in windows:windows.append(p)cv2.namedWindow(str(p), cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO) cv2.resizeWindow(str(p), im0.shape[1], im0.shape[0])cv2.imshow(str(p), im0)cv2.waitKey(1) # 如果需要保存图像保存结果if save_img:if dataset.mode image:cv2.imwrite(save_path, im0)else: if vid_path[i] ! save_path: vid_path[i] save_pathif isinstance(vid_writer[i], cv2.VideoWriter):vid_writer[i].release() if vid_cap: fps vid_cap.get(cv2.CAP_PROP_FPS)w int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))h int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))else: fps, w, h 30, im0.shape[1], im0.shape[0]save_path str(Path(save_path).with_suffix(.mp4)) vid_writer[i] cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*mp4v), fps, (w, h))vid_writer[i].write(im0)# 输出单张图像的推理时间LOGGER.info(f{s}{ if len(det) else (no detections), }{dt[1].dt * 1E3:.1f}ms)# 输出整体速度统计t tuple(x.t / seen * 1e3 for x in dt) LOGGER.info(fSpeed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape {(1, 3, *imgsz)})# 输出保存结果的信息if save_txt or save_img:s f\n{len(list(save_dir.glob(labels/*.txt)))} labels saved to {save_dir / labels} if save_txt else LOGGER.info(fResults saved to {colorstr(bold, save_dir)}{s})# 如果有模型更新清理优化器if update:strip_optimizer(weights[0]) 1. 归一化操作 # 遍历数据集中的每一张图片for path, im, im0s, vid_cap, s in dataset:# 测量预处理时间with dt[0]:# 将图像转换为Tensor并移至适当设备im torch.from_numpy(im).to(model.device)# 调整数据类型和归一化im im.half() if model.fp16 else im.float() im / 255 这段代码是针对深度学习模型输入预处理的一部分特别是在使用PyTorch框架时。这里是针对YOLOv5或类似的模型它说明了如何将输入图像从uint8格式转换为适合模型输入的格式即fp16半精度浮点数16位或fp32单精度浮点数32位。 代码解析 uint8 uint8类型用于数字图像时每个像素的颜色通道如红、绿、蓝通常使用uint8类型表示每个通道的值范围从0黑色到255最饱和的颜色。 精度转换 im im.half() if model.fp16 else im.float()这段代码检查模型是否支持半精度fp16计算。如果model.fp16为True则im.half()将图像张量从uint8转换为fp16半精度浮点数。如果model.fp16为False则im.float()将图像张量转换为fp32单精度浮点数。 注意uint8到fp16或fp32的转换是隐式的即当从uint8类型转换到浮点类型时原本的整数值会被转换为相应的浮点数值但不会改变其数值大小。例如uint8的255在转换为fp32后仍然是255.0。 归一化 im / 255 # 0 - 255 to 0.0 - 1.0这行代码将图像张量的像素值从uint8的0到255范围归一化到fp16或fp32的0.0到1.0之间。这是深度学习模型输入预处理中常见的一步帮助模型在训练和推断时获得更好的数值稳定性同时使不同亮度和对比度的图像在模型眼中更加“平等”。 这段代码的关键在于它确保了输入图像被适当地格式化和归一化以供模型进行有效处理。模型是否使用半精度计算取决于模型自身的配置model.fp16这通常在模型训练时为了提高计算效率和减少内存使用而设定。归一化步骤则是深度学习图像处理中普遍采用的预处理步骤确保模型输入的一致性和数值稳定性。 2. 扩展维度 # 扩展维度以匹配batch_size if len(im.shape) 3:im im[None] 在深度学习中尤其是使用卷积神经网络CNN进行图像处理时通常需要处理的是一批图像而非单一图像。这是因为现代GPU架构设计为并行处理大量数据处理一批图像比一次处理一张图像更有效率。因此即使输入的是单张图像也需要将其形状转换为适用于模型的批次输入格式。 为什么扩展维度 当你的图像数据im的形状是三维的例如形状为(height, width, channels)这意味着你只有一个图像。然而大多数深度学习框架和模型期望输入数据的形状至少是四维的即(batch_size, height, width, channels)对于TensorFlow或(batch_size, channels, height, width)对于PyTorch。 在YOLOv5的情况下模型预期的输入是四维的即 (batch_size, channels, height, width)。因此如果你的im是一个单独的图像它的形状会是 (channels, height, width)需要在前面增加一个维度来代表batch_size这样形状就会变成 (1, channels, height, width)。这就是为什么使用im im[None]来扩展维度None在这里等价于np.newaxis它会在数组中插入一个新的轴。 代码解释 if len(im.shape) 3:im im[None] # 扩展维度使形状从 (channels, height, width) 变为 (1, channels, height, width)这条语句检查im的形状如果它只有三个维度那么就使用None来扩展其第一个维度从而匹配模型期望的输入形状。扩展维度是为了将单张图像转换为批次格式以便模型能够正确处理。这是深度学习实践中一个常见的预处理步骤尤其在使用CNN进行图像处理时。 3. 对检测结果类别计数 # 如果有检测结果if len(det):# 对每个类别进行计数for c in det[:, 5].unique():n (det[:, 5] c).sum() s f{n} {names[int(c)]}{s * (n 1)}, 这段代码是在处理YOLOv5模型输出的检测结果时用于统计每个类别出现的次数并生成一个描述性的字符串用于后续的日志记录或输出。让我们逐步分解这段代码 检查是否有检测结果 if len(det):det是一个二维张量包含了所有检测到的对象的信息每一行代表一个检测到的对象列中包含位置信息如边界框坐标、类别ID和置信度得分。如果det非空即有检测结果则执行以下操作。 统计每个类别的出现次数 for c in det[:, 5].unique():n (det[:, 5] c).sum() det[:, 5]访问的是检测结果中每一行的第6个元素索引为5因为Python中索引从0开始这通常对应于检测到对象的类别ID。unique()函数返回所有独特的类别ID这样我们就可以迭代每一个类别。对于每一个类别c(det[:, 5] c)会产生一个布尔掩码表示哪些检测结果属于这个类别。sum()函数计算这个布尔掩码中True的个数即该类别在检测结果中出现的次数结果存储在变量n中。 构建描述性字符串 s f{n} {names[int(c)]}{s * (n 1)}, f{n} {names[int(c)]}使用f-string格式化字符串字面量来构建一个描述其中n是检测到的类别数量names[int(c)]是从模型的类别名列表中获取该类别的名称。s * (n 1)检查如果n大于1就在类别名称后面加上一个s这样可以正确地复数化名词。最后结果字符串后面加上一个逗号和空格以便在下一个类别出现时可以继续拼接。 这段代码的结果是一个描述检测结果的字符串其中包含了每个类别及其出现的次数。例如如果有两个狗和一个猫被检测到结果可能是 2 dogs, 1 cat。这个字符串通常用于在控制台或日志中提供一个直观的反馈说明检测到了什么以及数量。 三、定义命令行参数 def parse_opt():parser argparse.ArgumentParser() # 创建ArgumentParser对象parser.add_argument(--weights, nargs, typestr, defaultyolov5s.pt, helpmodel path(s)) # 添加权重参数parser.add_argument(--source, typestr, defaultdata/images, helpfile/dir/URL/glob, 0 for webcam) # 添加输入源参数parser.add_argument(--data, typestr, defaultdata/coco128.yaml, help(optional) dataset.yaml path) # 添加数据集参数parser.add_argument(--imgsz, --img, --img-size, typeint, default640, helpinference size (pixels)) # 添加图像大小参数parser.add_argument(--conf-thres, typefloat, default0.25, helpconfidence threshold) # 添加置信度阈值参数parser.add_argument(--iou-thres, typefloat, default0.45, helpNMS IoU threshold) # 添加IoU阈值参数parser.add_argument(--max-det, typeint, default1000, helpmaximum detections per image) # 添加最大检测数量参数parser.add_argument(--device, default, helpcuda device, i.e. 0 or 0,1,2,3 or cpu) # 添加设备参数parser.add_argument(--view-img, actionstore_true, helpshow results) # 添加显示图像参数parser.add_argument(--save-txt, actionstore_true, helpsave results to *.txt) # 添加保存文本参数parser.add_argument(--save-conf, actionstore_true, helpsave confidences in --save-txt labels) # 添加保存置信度参数parser.add_argument(--save-crop, actionstore_true, helpsave cropped prediction boxes) # 添加保存裁剪框参数parser.add_argument(--nosave, actionstore_true, helpdo not save images/videos) # 添加不保存图像/视频参数parser.add_argument(--classes, nargs, typeint, helpfilter by class: --class 0, or --class 0 2 3) # 添加类别过滤参数parser.add_argument(--agnostic-nms, actionstore_true, helpclass-agnostic NMS) # 添加类别无关的NMS参数parser.add_argument(--augment, actionstore_true, helpaugmented inference) # 添加增强推理参数parser.add_argument(--visualize, actionstore_true, helpvisualize features) # 添加可视化特征参数parser.add_argument(--update, actionstore_true, helpupdate all models) # 添加更新模型参数parser.add_argument(--project, defaultruns/detect, helpsave results to project/name) # 添加项目路径参数parser.add_argument(--name, defaultexp, helpsave results to project/name) # 添加结果文件夹名称参数parser.add_argument(--exist-ok, actionstore_true, helpexisting project/name ok, do not increment) # 添加允许现有项目名称参数parser.add_argument(--line-thickness, default3, typeint, helpbounding box thickness (pixels)) # 添加边界框厚度参数parser.add_argument(--hide-labels, defaultFalse, actionstore_true, helphide labels) # 添加隐藏标签参数parser.add_argument(--hide-conf, defaultFalse, actionstore_true, helphide confidences) # 添加隐藏置信度参数parser.add_argument(--half, actionstore_true, helpuse FP16 half-precision inference) # 添加半精度推理参数parser.add_argument(--dnn, actionstore_true, helpuse OpenCV DNN for ONNX inference) # 添加OpenCV DNN推理参数parser.add_argument(--vid-stride, typeint, default1, helpvideo frame-rate stride) # 添加视频帧率步幅参数opt parser.parse_args() # 解析命令行参数return opt # 返回解析结果四、主函数 def main(opt):check_requirements(exclude(tensorboard, thop)) # 检查运行所需的库run(**vars(opt)) # 运行检测程序if __name__ __main__:opt parse_opt() # 解析命令行参数main(opt) # 运行主程序
http://www.w-s-a.com/news/85436/

相关文章:

  • 手机网站 jsp个人网页制作成品代码五个页面
  • ppt做长图网站wordpress文章页面图片自动适应
  • 做泌尿科网站价格京东商城网站建设教程
  • 像网站的ppt怎么做的移动app与网站建设的区别
  • 怎么建个人网站网站收录有什么用
  • 广州市医院网站建设广州头条新闻最近一周
  • 广州移动 网站设计中国交通建设监理协网站
  • 甘肃省第八建设集团公司网站wordpress topnews
  • 公司网站建设维保协议wordpress会员可看
  • 合肥百度网站排名优化深圳集团网站开发公司
  • 可以直接打开网站的方法手机回收站
  • 山西免费网站制作中天建设集团有限公司第九建设公司
  • 好的网站有哪些企业微信开发者工具
  • 网站通栏代码老外做的中国汉字网站
  • 东莞公司建站哪个更便宜wordpress宝塔伪静态
  • 六安网站建设价格做网站好吗
  • 中小企业网站建设咨询湖南省邵阳建设局网站
  • 分类网站一天做几条合适南安网络推广
  • 案例学 网页设计与网站建设百度竞价关键词出价技巧
  • 做公司网站要那些资料南雄网站建设
  • 自己做的网站发布到网上视频播放不了网页游戏奥奇传说
  • 网站效果用什么软件做品牌网站建设等高端服务
  • 四川省成华区建设局网站网站专业制作
  • 网站建设如何开票网站后台怎么做超链接
  • 教育网站设计方案建设网站技术公司电话号码
  • 建网站要定制还是第三方系统传奇网站模板psd
  • 免费搭建企业网站什么叫网站定位
  • 网站建设cms程序员培训班
  • 网站seo技术wordpress editor ios
  • 红酒网站设计成立公司需要哪些手续