SAHI: Slicing Aided Hyper Inference基于图像自动切片技术的辅助超推理框架,有效提升超分辨率大尺度图像上目标检测模型的推理效果

sahi这个框架本身并不陌生,早在之前开发目标检测系统的时候就已经使用过了,正好最近有小目标检测的需要,就需要再次使用sahi框架,这里当做是回顾学习,简单记录下吧。

sahi项目官方项目地址在这里,如下所示:

接近4w的star量,还是很出色的框架了。

目标检测和实例分割是计算机视觉中最重要的应用。然而,在实际应用中,对小目标的检测和对大图像的推理仍然需要改进。这也是sahi框架推出的根本原因。

CommandDescription
predictperform sliced/standard video/image prediction using any yolov5/mmdet/detectron2/huggingface model
predict-fiftyoneperform sliced/standard prediction using any yolov5/mmdet/detectron2/huggingface model and explore results in fiftyone app
coco sliceautomatically slice COCO annotation and image files
coco fiftyoneexplore multiple prediction results on your COCO dataset with fiftyone ui ordered by number of misdetections
coco evaluateevaluate classwise COCO AP and AR for given predictions and ground truth
coco analysecalculate and export many error analysis plots
coco yolov5automatically convert any COCO dataset to yolov5 format

官方目前提供模型支持组合如下:

YOLOX + SAHI demo: sahi-yolox (RECOMMENDED)
RT-DETR + SAHI walkthrough: sahi-rtdetr (NEW)
YOLOv8 + SAHI walkthrough: sahi-yolov8 (NEW)
SuperGradients/YOLONAS + SAHI: sahi-yolonas (NEW)
DeepSparse + SAHI walkthrough: sahi-deepsparse
HuggingFace + SAHI walkthrough: sahi-huggingface
YOLOv5 + SAHI walkthrough: sahi-yolov5
MMDetection + SAHI walkthrough: sahi-mmdetection
Detectron2 + SAHI walkthrough: sahi-detectron2
TorchVision + SAHI walkthrough: sahi-torchvision

SAHI(Slicing Aided Hyper Inference)是一个用于改进目标检测模型推理性能的Python库。它通过将图像切分成多个小块(切片),并在这些切片上进行推理,然后将结果合并,从而提高检测的准确性和效率。SAHI特别适用于处理大图像或在计算资源有限的情况下进行目标检测。

以下是SAHI框架的详细介绍:

主要功能

  1. 图像切片

    • SAHI可以将大图像切分成多个小块(切片),以便在每个切片上独立进行目标检测。

    • 支持设置切片的大小和重叠比例,以便在切片之间共享信息,减少边界效应。

  2. 目标检测

    • SAHI支持多种流行的目标检测模型,如YOLO、Detectron2、MMDetection等。

    • 可以在每个切片上运行目标检测模型,获取检测结果。

  3. 结果合并

    • SAHI提供了多种方法来合并切片上的检测结果,生成最终的检测结果。

    • 支持非极大值抑制(NMS)等后处理技术,以消除重复检测。

  4. 可视化

    • SAHI提供了可视化工具,可以方便地查看切片、检测结果和合并后的结果。

安装

SAHI可以通过pip安装:

pip install sahi

使用示例

以下是一个使用SAHI进行图像切片和目标检测的简单示例:

from sahi.slicing import slice_image
from sahi.inference import get_prediction, get_sliced_prediction
from sahi.utils.file import download_from_url
from sahi.utils.cv import read_image_as_pil

# 下载示例图像
image_url = 'https://example.com/path/to/image.jpg'
image_path = 'image.jpg'
download_from_url(image_url, image_path)

# 读取图像
image = read_image_as_pil(image_path)

# 切片图像
slices = slice_image(
    image=image,
    slice_height=512,
    slice_width=512,
    overlap_height_ratio=0.2,
    overlap_width_ratio=0.2
)

# 在每个切片上进行目标检测
model_type = 'yolov5'
model_path = 'path/to/yolov5/model.pt'

results = []
for slice_image in slices:
    result = get_prediction(
        image=slice_image,
        model_type=model_type,
        model_path=model_path
    )
    results.append(result)

# 合并检测结果
final_result = get_sliced_prediction(
    image=image,
    results=results,
    slice_height=512,
    slice_width=512,
    overlap_height_ratio=0.2,
    overlap_width_ratio=0.2
)

# 可视化结果
from sahi.utils.cv import visualize_object_predictions

visualize_object_predictions(
    image=image,
    object_prediction_list=final_result.object_prediction_list
)

主要模块

  1. sahi.slicing

    • slice_image:将图像切分成多个小块(切片)。

  2. sahi.inference

    • get_prediction:在单个切片上进行目标检测。

    • get_sliced_prediction:合并多个切片的检测结果。

  3. sahi.utils.file

    • download_from_url:从URL下载文件。

  4. sahi.utils.cv

    • read_image_as_pil:读取图像并转换为PIL图像对象。

    • visualize_object_predictions:可视化目标检测结果。

优势

  1. 提高检测准确性:通过切片和合并,可以减少大图像中的边界效应,提高检测准确性。

  2. 节省计算资源:可以在较小的切片上进行推理,减少内存和计算资源的消耗。

  3. 灵活性:支持多种目标检测模型和后处理技术,可以根据需求进行定制。

适用场景

  1. 大图像目标检测:适用于处理大图像中的目标检测问题。

  2. 计算资源有限:适用于计算资源有限的环境,通过切片减少单次推理的负担。

  3. 提高检测精度:适用于需要提高目标检测精度的场景。

SAHI是一个强大的工具,它的核心思想就是结合了图像切片和合并技术,可以显著提高目标检测的性能和效率。说白了就是在不改变模型的情况下,通过整合数据的处理技术来最大化发挥当前条件下模型的效果。

在整合使用sahi来进行推理的时候,我们是不需要显式的切分子图,然后人工处理子图的,这些sahi框架都已经完成了,但是如果自己感兴趣或者是实际有需要分析子图数据的话可以使用下面的方法:

slice_image(image=image_path,output_file_name=output_file_name,
            output_dir=output_dir,slice_height=640,slice_width=640,
            overlap_height_ratio=0.2,overlap_width_ratio=0.2)

下面我们来实例演示,测试图像如下:

自动切分结果如下:

如果自己的数据集是标准的coco格式的话,想要切分图像数据也可以使用下面的方法:

from sahi.slicing import slice_coco
coco_dict, coco_path = slice_coco(
    coco_annotation_file_path=coco_annotation_file_path,
    image_dir=image_dir,
    slice_height=256,
    slice_width=256,
    overlap_height_ratio=0.2,
    overlap_width_ratio=0.2,
)

使用sahi框架来助力模型切片推理的核心方法是:

result = get_sliced_prediction(
    image,
    detection_model,
    slice_height = 640,
    slice_width = 640,
    overlap_height_ratio = 0.2,
    overlap_width_ratio = 0.2
)

推理完成后可以借助于框架内置的方法visualize_object_predictions来实现快速的可视化操作,实例实现如下所示:

visualization_result = visualize_object_predictions(
    image,
    object_prediction_list=result["object_prediction_list"],
    output_dir="",
    file_name="",
)

但是,像我们自己实际的项目端需求可能都是比较复杂的,官方内置的可视化操作可能不能够满足实际需要,或则是比较死板,不能够灵活掌握想要显示的信息,这时候就可以自己来实现替换官方的可视化方法。

核心实现如下:

def plot_one_box(x, img, color=None, label=None, line_thickness=3):
    """
    可视化绘图
    """
    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1
    color = color or [random.randint(0, 255) for _ in range(3)]
    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if label:
        tf = max(tl - 1, 1)
        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)
        cv2.putText(
            img,
            label,
            (c1[0], c1[1] - 2),
            0,
            tl / 3,
            [225, 255, 255],
            thickness=tf,
            lineType=cv2.LINE_AA,
        )
    return img

要绘制的信息、需要展示或者隐藏的信息、样式字体颜色等等都可以在这个基础上面修改即可。

想要适配调用上面的方法,需要自己来解析结果数据,核心实现如下:

x1,y1,w,h=one_dict["bbox"]
x2,y2=x1+w,y1+h
one_box=[x1,y1,x2,y2]
print("one_box: ", one_box)
one_score=one_dict["score"]
one_label=one_dict["category_name"]
one_area=one_dict["area"]
resData.append([one_label, one_score, one_box])
resImg=plot_one_box(one_box, img, color=(0,0,255), label=one_label+": "+str(round(one_score,3)), line_thickness=3)

如果发现出现下面的情况,可能是RGB图像和BGR图像弄混了,调整下颜色通道即可:

正确的结果如下:

本文主要是回顾以及结合自己近期的开发实践来写的教程文章,希望帮到有需要的人,同时以后备忘使用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Together_CZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值