1. 小目標(biāo)檢測實(shí)戰(zhàn)

        共 14901字,需瀏覽 30分鐘

         ·

        2024-04-30 10:05

        點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

        重磅干貨,第一時(shí)間送達(dá)


        利用切片輔助的超級推斷

        目標(biāo)檢測是計(jì)算機(jī)視覺中的基本任務(wù)之一。在高層次上,它涉及預(yù)測圖像中物體的位置和類別。像You-Only-Look-Once(YOLO)系列中的最先進(jìn)(SOTA)深度學(xué)習(xí)模型已經(jīng)達(dá)到了令人矚目的準(zhǔn)確度。然而,目標(biāo)檢測中一個(gè)眾所周知的挑戰(zhàn)是小物體。在本文中,您將學(xué)習(xí)如何使用切片輔助的超級推斷(SAHI)來檢測數(shù)據(jù)集中的小物體。我們將涵蓋以下內(nèi)容:

        • 為什么檢測小物體很困難

        • SAHI 的工作原理

        • 如何將 SAHI 應(yīng)用于您的數(shù)據(jù)集

        • 如何評估這些預(yù)測的質(zhì)量


        為什么檢測小物體很困難?

        它們很小

        首先,檢測小物體很困難,因?yàn)樾∥矬w很小。物體越小,檢測模型可用的信息就越少。如果汽車遠(yuǎn)處,它可能只占據(jù)圖像中的幾個(gè)像素。與人類難以辨認(rèn)遠(yuǎn)處物體的情況類似,我們的模型在沒有視覺可辨識特征(如車輪和車牌)的情況下更難識別汽車!


        訓(xùn)練數(shù)據(jù)

        模型只有它們所訓(xùn)練的數(shù)據(jù)好。大多數(shù)標(biāo)準(zhǔn)的目標(biāo)檢測數(shù)據(jù)集和基準(zhǔn)都專注于中大型物體,這意味著大多數(shù)現(xiàn)成的目標(biāo)檢測模型未經(jīng)優(yōu)化用于小物體檢測。


        固定的輸入尺寸 

        目標(biāo)檢測模型通常采用固定尺寸的輸入。例如,YOLOv8 是在最大邊長為 640 像素的圖像上訓(xùn)練的。這意味著當(dāng)我們將一張大小為 1920x1080 的圖像輸入時(shí),模型會將圖像縮小到 640x360 然后進(jìn)行預(yù)測,降低了小物體的分辨率并丟棄了重要信息。


        SAHI 的工作原理

        理論上,您可以在較大的圖像上訓(xùn)練模型以提高小物體的檢測能力。然而,在實(shí)際操作中,這將需要更多的內(nèi)存、更多的計(jì)算能力和更加費(fèi)時(shí)費(fèi)力的數(shù)據(jù)集創(chuàng)建。與之相反的方法是利用現(xiàn)有的目標(biāo)檢測,將模型應(yīng)用于圖像中固定大小的塊或切片,然后將結(jié)果拼接在一起。


        SAHI 將圖像分成完全覆蓋它的切片,并對每個(gè)切片使用指定的檢測模型進(jìn)行推斷。然后,將所有這些切片的預(yù)測結(jié)果合并在一起,生成整個(gè)圖像上的一個(gè)檢測列表。SAHI 中的“超級”來自于 SAHI 的輸出不是模型推斷的結(jié)果,而是涉及多個(gè)模型推斷的計(jì)算結(jié)果。SAHI 切片允許重疊(如上面的 GIF 所示),這可以確保至少有一個(gè)切片中包含足夠多的對象以進(jìn)行檢測。


        設(shè)置


        為了說明如何使用 SAHI 檢測小物體,我們將使用中國天津大學(xué)機(jī)器學(xué)習(xí)與數(shù)據(jù)挖掘?qū)嶒?yàn)室的 AISKYEYE 團(tuán)隊(duì)的 VisDrone 檢測數(shù)據(jù)集。該數(shù)據(jù)集包含 8,629 張圖像,邊長從 360 像素到 2,000 像素不等,使其成為 SAHI 的理想測試平臺。Ultralytics 的 YOLOv8l 將作為我們的基本目標(biāo)檢測模型。我們將使用以下庫:

        • fiftyone 用于數(shù)據(jù)集管理和可視化

        • huggingface_hub 用于從 Hugging Face Hub 加載 VisDrone 數(shù)據(jù)集

        • ultralytics 用于使用 YOLOv8 進(jìn)行推斷

        • sahi 用于在圖像切片上運(yùn)行推斷


        如果尚未安裝,請安裝這些庫的最新版本。您需要 fiftyone>=0.23.8 來從 Hugging Face Hub 加載 VisDrone:

        pip install -U fiftyone sahi ultralytics huggingface_hub --quiet

        現(xiàn)在在 Python 進(jìn)程中,讓我們導(dǎo)入我們將用于查詢和管理數(shù)據(jù)的 FiftyOne 模塊:

        import fiftyone as foimport fiftyone.zoo as fozimport fiftyone.utils.huggingface as fouhfrom fiftyone import ViewField as F

        我們將使用 FiftyOne 的 Hugging Face 工具中的 load_from_hub() 函數(shù)直接從 Hugging Face Hub 通過 repo_id 加載 VisDrone 數(shù)據(jù)集的部分。為了演示并保持代碼執(zhí)行盡可能快,我們將只取數(shù)據(jù)集的前 100 張圖像。我們還將給我們正在創(chuàng)建的新數(shù)據(jù)集命名為 ”sahi-test“:


        使用YOLOv8進(jìn)行推理


        在接下來的部分,我們將使用SAHI對我們的數(shù)據(jù)進(jìn)行超級推理。在引入SAHI之前,讓我們使用Ultralytics的大型YOLOv8模型進(jìn)行標(biāo)準(zhǔn)目標(biāo)檢測推理。首先,我們創(chuàng)建一個(gè)ultralytics.YOLO模型實(shí)例,如果需要的話會下載模型檢查點(diǎn)。然后,我們將這個(gè)模型應(yīng)用到我們的數(shù)據(jù)集上,并將結(jié)果存儲在我們的樣本的“base_model”字段中:

        from ultralytics import YOLO
        ckpt_path = "yolov8l.pt"model = YOLO(ckpt_path)
        dataset.apply_model(model, label_field="base_model")session.view = dataset.view()

        通過觀察模型的預(yù)測和ground truth標(biāo)簽,我們可以看到一些情況。首先,我們的YOLOv8l模型檢測到的類與VisDrone數(shù)據(jù)集中的ground truth類不同。我們的YOLO模型是在COCO數(shù)據(jù)集上訓(xùn)練的,該數(shù)據(jù)集有80個(gè)類,而VisDrone數(shù)據(jù)集有12個(gè)類,包括一個(gè) ignore_regions 類。為了簡化比較,我們將專注于數(shù)據(jù)集中最常見的幾個(gè)類,并將VisDrone類映射到COCO類,如下所示:

        mapping = {"pedestrians": "person", "people": "person", "van": "car"}mapped_view = dataset.map_labels("ground_truth", mapping)

        然后只篩選我們感興趣的類別:

        def get_label_fields(sample_collection):    """Get the (detection) label fields of a Dataset or DatasetView."""    label_fields = list(        sample_collection.get_field_schema(embedded_doc_type=fo.Detections).keys()    )    return label_fields
        def filter_all_labels(sample_collection): label_fields = get_label_fields(sample_collection)
        filtered_view = sample_collection
        for lf in label_fields: filtered_view = filtered_view.filter_labels( lf, F("label").is_in(["person", "car", "truck"]), only_matches=False ) return filtered_view
        filtered_view = filter_all_labels(mapped_view)session.view = filtered_view.view()

        現(xiàn)在我們有了基本模型的預(yù)測結(jié)果,讓我們使用SAHI來對我們的圖像進(jìn)行切片 。


        使用SAHI進(jìn)行超級推理


        SAHI技術(shù)是我們之前安裝的sahi Python包中實(shí)現(xiàn)的。SAHI是一個(gè)與許多目標(biāo)檢測模型兼容的框架,包括YOLOv8。我們可以選擇要使用的檢測模型,并創(chuàng)建任何子類為 sahi.models.DetectionModel 的類的實(shí)例,包括 YOLOv8、YOLOv5,甚至是 Hugging Face Transformers 模型。我們將使用 SAHI 的 AutoDetectionModel 類來創(chuàng)建我們的模型對象,指定模型類型和檢查點(diǎn)文件的路徑:

        from sahi import AutoDetectionModelfrom sahi.predict import get_prediction, get_sliced_prediction
        detection_model = AutoDetectionModel.from_pretrained( model_type='yolov8', model_path=ckpt_path, confidence_threshold=0.25, ## same as the default value for our base model image_size=640, device="cpu", # or 'cuda' if you have access to GPU)

        在生成切片預(yù)測之前,讓我們使用 SAHI 的 get_prediction() 函數(shù)檢查模型在一張?jiān)囼?yàn)圖像上的預(yù)測結(jié)果:

        result = get_prediction(dataset.first().filepath, detection_model)print(result)
        <sahi.prediction.PredictionResult object at 0x2b0e9c250>

        幸運(yùn)的是,SAHI 的結(jié)果對象有一個(gè) to_fiftyone_detections() 方法,將結(jié)果轉(zhuǎn)換為 FiftyOne 檢測對象的列表:

        print(result.to_fiftyone_detections())
        [<Detection: {    'id': '661858c20ae3edf77139db7a',    'attributes': {},    'tags': [],    'label': 'car',    'bounding_box': [        0.6646394729614258,        0.7850866247106482,        0.06464214324951172,        0.09088355170355902,    ],    'mask': None,    'confidence': 0.8933132290840149,    'index': None,}>, <Detection: {    'id': '661858c20ae3edf77139db7b',    'attributes': {},    'tags': [],    'label': 'car',    'bounding_box': [        0.6196376800537109,        0.7399617513020833,        0.06670347849527995,        0.09494832356770834,    ],    'mask': None,    'confidence': 0.8731599450111389,    'index': None,}>, <Detection: {   ....   ....   ....

        這樣我們就可以專注于數(shù)據(jù),而不是瑣碎的格式轉(zhuǎn)換細(xì)節(jié)。SAHI 的 get_sliced_prediction() 函數(shù)的工作方式與 get_prediction() 相同,但增加了一些額外的超參數(shù),讓我們可以配置圖像如何被切片。特別是,我們可以指定切片的高度和寬度,以及切片之間的重疊。下面是一個(gè)示例:

        sliced_result = get_sliced_prediction(    dataset.skip(40).first().filepath,    detection_model,    slice_height = 320,    slice_width = 320,    overlap_height_ratio = 0.2,    overlap_width_ratio = 0.2,)

        作為初步檢查,我們可以比較切片預(yù)測中的檢測數(shù)量與原始預(yù)測中的檢測數(shù)量:

        num_sliced_dets = len(sliced_result.to_fiftyone_detections())num_orig_dets = len(result.to_fiftyone_detections())
        print(f"Detections predicted without slicing: {num_orig_dets}")print(f"Detections predicted with slicing: {num_sliced_dets}")
        Detections predicted without slicing: 17Detections predicted with slicing: 73

        我們可以看到,預(yù)測數(shù)量大大增加了!我們還沒有確定額外的預(yù)測是有效的還是只有更多的誤報(bào)。我們稍后將使用 FiftyOne 的評估 API 來做這件事。我們還希望為我們的切片找到一組好的超參數(shù)。我們需要將 SAHI 應(yīng)用于整個(gè)數(shù)據(jù)集來完成所有這些工作。


        為簡化流程,我們將定義一個(gè)函數(shù),將預(yù)測添加到指定的標(biāo)簽字段中的樣本中,然后我們將迭代數(shù)據(jù)集,將該函數(shù)應(yīng)用于每個(gè)樣本。這個(gè)函數(shù)將樣本的文件路徑和切片超參數(shù)傳遞給 get_sliced_prediction(),然后將預(yù)測結(jié)果添加到指定的標(biāo)簽字段的樣本中:

        def predict_with_slicing(sample, label_field, **kwargs):    result = get_sliced_prediction(        sample.filepath, detection_model, verbose=0, **kwargs    )    sample[label_field] = fo.Detections(detections=result.to_fiftyone_detections())

        我們將保持切片重疊固定為0.2,然后看看切片的高度和寬度如何影響預(yù)測的質(zhì)量:

        kwargs = {"overlap_height_ratio": 0.2, "overlap_width_ratio": 0.2}
        for sample in dataset.iter_samples(progress=True, autosave=True): predict_with_slicing(sample, label_field="small_slices", slice_height=320, slice_width=320, **kwargs) predict_with_slicing(sample, label_field="large_slices", slice_height=480, slice_width=480, **kwargs)

        請注意,這些推理時(shí)間比原始推理時(shí)間要長得多。這是因?yàn)槲覀冊诿總€(gè)圖像上運(yùn)行模型的多個(gè)切片,這增加了模型需要進(jìn)行的前向傳遞次數(shù)。我們在進(jìn)行權(quán)衡,以改善對小物體的檢測。現(xiàn)在讓我們再次篩選我們的標(biāo)簽,只包括我們感興趣的類別,并在 FiftyOne App 中可視化結(jié)果:

        filtered_view = filter_all_labels(mapped_view)session = fo.launch_app(filtered_view, auto=False)

        從幾個(gè)視覺示例來看,切片似乎提高了ground truth檢測的覆蓋率,特別是較小的切片似乎更多地捕獲了人物檢測。但是我們?nèi)绾未_切地知道呢?讓我們運(yùn)行一個(gè)評估程序,將檢測標(biāo)記為真陽性、假陽性或假陰性,以將切片預(yù)測與ground truth進(jìn)行比較。我們將使用我們篩選的視圖的 evaluate_detections() 方法。


        評估SAHI預(yù)測


        繼續(xù)使用我們數(shù)據(jù)集的篩選視圖,讓我們運(yùn)行一個(gè)評估程序,將每個(gè)預(yù)測標(biāo)簽字段的預(yù)測與ground truth標(biāo)簽進(jìn)行比較。在這里,我們使用默認(rèn)的 IoU 閾值為0.5,但您可以根據(jù)需要進(jìn)行調(diào)整:

        base_results = filtered_view.evaluate_detections("base_model", gt_field="ground_truth", eval_key="eval_base_model")large_slice_results = filtered_view.evaluate_detections("large_slices", gt_field="ground_truth", eval_key="eval_large_slices")small_slice_results = filtered_view.evaluate_detections("small_slices", gt_field="ground_truth", eval_key="eval_small_slices")

        讓我們輸出每個(gè)report:

        print("Base model results:")base_results.print_report()
        print("-" * 50)print("Large slice results:")large_slice_results.print_report()
        print("-" * 50)print("Small slice results:")small_slice_results.print_report()
        Base model results:              precision    recall  f1-score   support
        car 0.81 0.55 0.66 692 person 0.94 0.16 0.28 7475 truck 0.66 0.34 0.45 265
        micro avg 0.89 0.20 0.33 8432 macro avg 0.80 0.35 0.46 8432weighted avg 0.92 0.20 0.31 8432
        --------------------------------------------------Large slice results: precision recall f1-score support
        car 0.67 0.71 0.69 692 person 0.89 0.34 0.49 7475 truck 0.55 0.45 0.49 265
        micro avg 0.83 0.37 0.51 8432 macro avg 0.70 0.50 0.56 8432weighted avg 0.86 0.37 0.51 8432
        --------------------------------------------------Small slice results: precision recall f1-score support
        car 0.66 0.75 0.70 692 person 0.84 0.42 0.56 7475 truck 0.49 0.46 0.47 265
        micro avg 0.80 0.45 0.57 8432 macro avg 0.67 0.54 0.58 8432weighted avg 0.82 0.45 0.57 8432

        我們可以看到,隨著引入更多的切片,假陽性的數(shù)量增加,而假陰性的數(shù)量減少。這是預(yù)期的,因?yàn)槟P湍軌蚴褂酶嗟那衅瑱z測到更多的物體,但也會犯更多的錯(cuò)誤!您可以對置信度進(jìn)行更激進(jìn)的閾值處理,以應(yīng)對假陽性的增加,但即使不這樣做,F(xiàn)1 分?jǐn)?shù)也有了顯著的提升。


        讓我們深入一點(diǎn)研究這些結(jié)果。我們之前指出模型在小物體上有困難,所以讓我們看看這三種方法在小于 32x32 像素的物體上的表現(xiàn)如何。我們可以使用 FiftyOne 的 ViewField 來執(zhí)行這種過濾:

        ## Filtering for only small boxes
        box_width, box_height = F("bounding_box")[2], F("bounding_box")[3]rel_bbox_area = box_width * box_height
        im_width, im_height = F("$metadata.width"), F("$metadata.height")abs_area = rel_bbox_area * im_width * im_height
        small_boxes_view = filtered_viewfor lf in get_label_fields(filtered_view): small_boxes_view = small_boxes_view.filter_labels(lf, abs_area < 32**2, only_matches=False)
        session.view = small_boxes_view.view()

        通過結(jié)果我們可以發(fā)現(xiàn)在使用 SAHI 時(shí),小物體的召回率大大提高,而精確度沒有明顯下降,導(dǎo)致 F1 分?jǐn)?shù)提升。這在人物檢測中尤其明顯,F(xiàn)1 分?jǐn)?shù)增加了三倍!

        ## Evaluating on only small boxessmall_boxes_base_results = small_boxes_view.evaluate_detections("base_model", gt_field="ground_truth", eval_key="eval_small_boxes_base_model")small_boxes_large_slice_results = small_boxes_view.evaluate_detections("large_slices", gt_field="ground_truth", eval_key="eval_small_boxes_large_slices")small_boxes_small_slice_results = small_boxes_view.evaluate_detections("small_slices", gt_field="ground_truth", eval_key="eval_small_boxes_small_slices")
        ## Printing reportsprint("Small Box — Base model results:")small_boxes_base_results.print_report()
        print("-" * 50)print("Small Box — Large slice results:")small_boxes_large_slice_results.print_report()
        print("-" * 50)print("Small Box — Small slice results:")small_boxes_small_slice_results.print_report()
        Small BoxBase model results:              precision    recall  f1-score   support
        car 0.71 0.25 0.37 147 person 0.83 0.08 0.15 5710 truck 0.00 0.00 0.00 28
        micro avg 0.82 0.08 0.15 5885 macro avg 0.51 0.11 0.17 5885weighted avg 0.82 0.08 0.15 5885
        --------------------------------------------------Small BoxLarge slice results: precision recall f1-score support
        car 0.46 0.48 0.47 147 person 0.82 0.23 0.35 5710 truck 0.20 0.07 0.11 28
        micro avg 0.78 0.23 0.36 5885 macro avg 0.49 0.26 0.31 5885weighted avg 0.80 0.23 0.36 5885
        --------------------------------------------------Small BoxSmall slice results: precision recall f1-score support
        car 0.42 0.53 0.47 147 person 0.79 0.31 0.45 5710 truck 0.21 0.18 0.19 28
        micro avg 0.75 0.32 0.45 5885 macro avg 0.47 0.34 0.37 5885weighted avg 0.77 0.32 0.45 5885


        后續(xù)工作


        在本教程中,我們介紹了如何將 SAHI 預(yù)測添加到您的數(shù)據(jù)中,然后嚴(yán)格評估了切片對預(yù)測質(zhì)量的影響。我們看到了切片輔助的超級推斷(SAHI)如何在不需要在較大圖像上訓(xùn)練模型的情況下,改善檢測的召回率和 F1 分?jǐn)?shù),特別是對于小物體。為了最大程度地提高 SAHI 的效果,您可能希望嘗試以下內(nèi)容:

        • 切片超參數(shù),如切片高度和寬度以及重疊

        • 基本目標(biāo)檢測模型,因?yàn)?SAHI 兼容許多模型,包括 YOLOv5 和 Hugging Face Transformers 模型

        • 置信度閾值,可能是逐類別的,以減少誤檢的數(shù)量

        • 后處理技術(shù),如非極大值抑制(NMS),以減少重疊檢測的數(shù)量

        無論您想調(diào)整哪些參數(shù),重要的是要超越單一數(shù)字指標(biāo)。在處理小物體檢測任務(wù)時(shí),圖像中的小物體越多,就越可能缺少“ground truth”標(biāo)簽。SAHI 可以幫助您發(fā)現(xiàn)潛在的錯(cuò)誤,您可以通過人工干預(yù)工作流程來糾正。


                
        下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
        在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

        下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目52講
        小白學(xué)視覺公眾號后臺回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計(jì)數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個(gè)視覺實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺。

        下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
        小白學(xué)視覺公眾號后臺回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講,即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

        交流群


        歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計(jì)算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


        瀏覽 33
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 男女爽啪啪gif动态第140期 | 国产传媒-第1页-MM606-萌萌视频 | 亚洲福建男人和女人三线片 | 日韩AV中文字幕在线播放 | 五月丁香花网 |