Sahi+Yolov10

news2024/9/22 23:33:58

一、前言

    了解到Sahi,是通过切图,实现提高小目标的检测效果。sahi 目前支持yolo5\yolo8\mmdet\detection2 等等算法,本篇主要通过实验onnx加载模型的方式使sahi支持yolov10。

二、代码

(1)转换模型

      首先使用  conda创建虚拟环境,配置好yolov10环境,然后 pip 将sahi 安装上

pip install sahi

     将yolov10 模型导出为 onnx格式文件,命令窗cd 至 模型文件所在目录 执行

 yolo export model=vitrolite_best.pt  format=onnx opset=11 simplify

     转换成功,将在目录下生成同名 onnx格式文件

 (2)加载onnx 模型推理代码

参考 sahi 提供的demo 文件 inference_for_yolov8_onnx.ipynb ,分块大小和重叠比例可设置

from sahi import AutoDetectionModel
from sahi.utils.cv import read_image
from sahi.utils.file import download_from_url
from sahi.predict import get_prediction, get_sliced_prediction, predict


import time



if __name__ == '__main__':
    yolov8_onnx_model_path = "runs\\detect\\train_v102\\weights\\vitrolite_best.onnx"  #加载自己的onnx模型文件
    #yolov8_onnx_model_path = "D:\\Project\\yolov8\\weights\\yolov8x.onnx"

    category_mapping = {'0': 'p0', '1': 'p1', '2': 'p2', '3': 'p3'  }  #类别映射,换成你的


    detection_model = AutoDetectionModel.from_pretrained(
        model_type='yolov8onnx',
        model_path=yolov8_onnx_model_path,
        confidence_threshold=0.3,
        category_mapping=category_mapping,
        device='cuda:0', # or 'cuda:0'  #这里要使用GPU
    )


    #img_path = "datasets\\vitrolite\\images\\val\\c144846_5_10.png"   #推导图片路径
    #result = get_prediction(read_image(img_path), detection_model)  #第一次启动GOU ,时间比较慢,必须先启动一次


 
    #分块检测
    result = get_sliced_prediction(
        "D:\\Project\\vitroliteDefect\\tile_round1_train_20201231\\train_imgs\\197_2_t20201119084924170_CAM1.jpg",
        detection_model,
        slice_height=640,
        slice_width=640,
        overlap_height_ratio=0.05,
        overlap_width_ratio=0.05
    )


    result.export_visuals(export_dir="demo_data/")

(3)修改sahi的接口文件  

找到pip安装的sahi 位置 , 修改 yolov8onnx.py

修改 _post_process 函数 , 主要是由于yolov8 和yolov10 输出 shape有所不同,yolov10没有nms

    def _post_process(
        self, outputs: np.ndarray, input_shape: Tuple[int, int], image_shape: Tuple[int, int]
    ) -> List[torch.Tensor]:
        image_h, image_w = image_shape
        input_w, input_h = input_shape

        predictions = np.squeeze(outputs[0])  # 不用.T 转置  ,  #( 300,6)
        # 在下面这个地方改动,by zjy ,  self.confidence_threshold 是0.3
        #for row in predictions:
            #print(  "row:" ,  row.shape   )

        scores =  predictions[: , 4]  #shape 为 ( 300,6) ,第5个,下标为4
        #self.confidence_threshold = 0.9

        predictions = predictions[ scores > self.confidence_threshold, : ]
        scores = scores[scores > self.confidence_threshold]

        boxes = predictions[:, :4]
        boxes = boxes.astype(np.int32)
        class_ids = predictions[:,  5 ].astype(np.int32)

        # Format the results
        prediction_result = []
        for bbox, score, label in zip(boxes , scores , class_ids ):
            bbox = bbox.tolist()
            cls_id = int(label)
            prediction_result.append([bbox[0], bbox[1], bbox[2], bbox[3], score, cls_id])


        """  
        # Filter out object confidence scores below threshold
        scores = np.max(predictions[:, 4:], axis=1)
        predictions = predictions[scores > self.confidence_threshold, :]
        scores = scores[scores > self.confidence_threshold]
        class_ids = np.argmax(predictions[:, 4:], axis=1)

        boxes = predictions[:, :4]

        # Scale boxes to original dimensions
        input_shape = np.array([input_w, input_h, input_w, input_h])
        boxes = np.divide(boxes, input_shape, dtype=np.float32)
        boxes *= np.array([image_w, image_h, image_w, image_h])
        boxes = boxes.astype(np.int32)

        # Convert from xywh two xyxy
        boxes = xywh2xyxy(boxes).round().astype(np.int32)
    
        # Perform non-max supressions
        indices = non_max_supression(boxes, scores, self.iou_threshold)

        # Format the results
        prediction_result = []
        for bbox, score, label in zip(boxes[indices], scores[indices], class_ids[indices]):
            bbox = bbox.tolist()
            cls_id = int(label)
            prediction_result.append([bbox[0], bbox[1], bbox[2], bbox[3], score, cls_id])

      
        """



        prediction_result = [torch.tensor(prediction_result)]
        # prediction_result = [prediction_result]

        return prediction_result

三、结果

运行推理代码,在 demo_data 文件夹下生成结果图片, 实验图片是一张高分辨率瓷砖图片

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

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

相关文章

EtherCAT转Profinet网关配置说明第一讲:配置软件安装及介绍

网关XD-ECPNS20为EtherCAT转Profinet协议网关,使EtherCAT协议和Profinet协议两种工业实时以太网网络之间双向传输 IO 数据。适用于具有EtherCAT协议网络与Profinet协议网络跨越网络界限进行数据交换的解决方案。 本网关通过上位机来进行配置。 首先安装上位机软件 一…

DP:二维费用背包问题

文章目录 🎵二维费用背包问题🎶引言🎶问题定义🎶动态规划思想🎶状态定义和状态转移方程🎶初始条件和边界情况 🎵例题🎶1.一和零🎶2.盈利计划 🎵总结 &#x1…

Explore Synapse

rm -r dp-203 -f git clone https://github.com/MicrosoftLearning/dp-203-azure-data-engineer dp-203 cd dp-203/Allfiles/labs/01 ./setup.ps1 -- This is auto-generated code SELECTTOP 100 * FROMOPENROWSET(BULK https://datalakexxxxxxx.dfs.core.windows.net/fil…

单/多线程--协程--异步爬虫

免责声明:本文仅做技术交流与学习... 目录 了解进程和线程 单个线程(主线程)在执行 多线程 线程池 协程(爬虫多用) 假异步:(同步) 真异步: 爬虫代码模版 异步-爬虫 同步效果--19秒 异步效果--7秒 了解进程和线程 ​ # --------------------> # ------> # …

Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制

文件的读取、显示、存取 cv2.imread(imagepath,IMREAD.xxx) 读取图像cv2.imshow(窗口名称,mat图片) 显示图像cv2.imwrite(保存的位置,img) 保存图像 # 1. 读取图像 原始图片路径,图片读取模式 cv2.imread(imagepath,IMREAD.xxx)cv2.IMREAD_COLOR 彩色模式读取 cv2…

PostgreSQL 如何优化存储过程的执行效率?

文章目录 一、查询优化1. 正确使用索引2. 避免不必要的全表扫描3. 使用合适的连接方式4. 优化子查询 二、参数传递1. 避免传递大对象2. 参数类型匹配 三、减少数据量处理1. 限制返回结果集2. 提前筛选数据 四、优化逻辑结构1. 分解复杂的存储过程2. 避免过度使用游标 五、事务处…

贵州建筑三类人员安全员2024年考试最新题库练习题

一、单选题 1.建设工程安全管理的方针是()。 A.安全第一,预防为主,综合治理 B.质量第一,兼顾安全 C.安全至上 D.安全责任重于泰山 答案:A 2.安全生产管理的根本目的是()。 A.…

zerotier-one自建根服务器方法五

一、简介 前面几篇文章已经写完了自己建立服务器的方法,今天写一下我在使用过程中遇到的问题和解决方法。 二、准备工作 准备一个有公网IP的云主机。 要稳定性、安全性、不差钱的可以使用阿里、腾讯等大厂的云服务器。 本人穷屌丝一枚,所以我用的是免…

数据结构1:C++实现边长数组

数组作为线性表的一种,具有内存连续这一特点,可以通过下标访问元素,并且下标访问的时间复杂的是O(1),在数组的末尾插入和删除元素的时间复杂度同样是O(1),我们使用C实现一个简单的边长数组。 数据结构定义 class Arr…

CentOS 7.9 停止维护(2024-6-30)后可用在线yum源 —— 筑梦之路

众所周知,centos 7 在2024年6月30日,生命周期结束,官方不再进行支持维护,而很多环境一时之间无法完全更新替换操作系统,因此对于yum源还是需要的,特别是对于互联网环境来说,在线yum源使用方便很…

第6章 选课学习:需求分析,添加选课,支付,支付通知,在线学习

1 模块需求分析 1.1 模块介绍 本模块实现了学生选课、下单支付、学习的整体流程。 网站的课程有免费和收费两种,对于免费课程学生选课后可直接学习,对于收费课程学生需要下单且支付成功方可选课、学习。 选课:是将课程加入我的课程表的过…

关于HTTP的攻击实验

实验原理:1. 根据ARP中间人攻击,获取 用户和服务器之间的数据2. 将获取到的数据 通过一定的技术来复原,进而获取用户的信息或者 相关权限实验拓扑图 将 kali 的网卡改为桥接模式,查看Kali和本机的ip 启动ettercap,…

CANopen协议开发梳理总结笔记教程

0、提醒 CANOpen使用时,需要清楚什么是大端和小端,这对于CANOpen数据发送及解析时,有很大的帮助。且学习开发CANOpen时,需要具备一定的CAN基础。 1、CANOpen协议介绍 ①、什么是CANOpen协议 CANOpen协议是一种架构在控制局域网络…

FreeRTOS——队列集

一、队列集 一个队列只允许任务间传递的消息为 同一种数据类型 ,如果需要在任务间 传递不同数据类型的消息 时,那么就可以使用队列集 作用:用于对多个队列或信号量进行“监听”(接收或获取),其中 不管哪一…

Java线上接口耗时分析神器 Arthas

介绍 程序员的日常,总是离不开“调优”和“排查”。尤其当线上环境出现问题,性能瓶颈把人逼疯。这时候,你就需要一款像 Arthas 这样的神器来救场。 什么是 Arthas? 简单来说,Arthas 是阿里巴巴开源的 Java 诊断工具…

SwinUnet详解

文章目录 摘要一. 编码端模块1. PatchEmbed2. SwinTransformerBlock2.1. Window_partition2.2. WindowAttention2.3. Window_reverse2.4. MLP 3. PatchMerging 二. 解码端模块三. 完整流程图 摘要 swinunet基本结构: swinunet采用编码器-解码器结构: 编…

python读取csv出错怎么解决

Python用pandas的read_csv函数读取csv文件。 首先,导入pandas包后,直接用read_csv函数读取报错OSError,如下: 解决方案是加上参数:enginepython。 运行之后没有报错,正在我欣喜之余,输出一下d…

vulnhub靶场之Jarbas

1 信息收集 1.1 主机发现 arp-scan -l 发现主机IP地址为:192.168.1.16 1.2 端口发现 nmap -sS -sV -A -T5 -p- 192.168.1.16 存在端口22,80,3306,8080 1.3 目录扫描 dirsearch -u 192.168.1.16 2 端口访问 2.1 80端口 2.2…

软件设计之Java入门视频(12)

软件设计之Java入门视频(12) 视频教程来自B站尚硅谷: 尚硅谷Java入门视频教程,宋红康java基础视频 相关文件资料(百度网盘) 提取密码:8op3 idea 下载可以关注 软件管家 公众号 学习内容: 该视频共分为1-7…

【OnlyOffice】桌面应用编辑器,插件开发大赛,等你来挑战

OnlyOffice,桌面应用编辑器,最近版本已从8.0升级到了8.1 从PDF、Word、Excel、PPT等全面进行了升级。随着AI应用持续的火热,OnlyOffice也在不断推出AI相关插件。 因此,在此给大家推荐一下OnlyOffice本次的插件开发大赛。 详细信息…