YOLO目標檢測應用——基于 YOLOv8目標檢測和 SAM 零樣本分割實現指定目標分割

概述

在當前的計算機視覺領域,目標分割技術正變得越來越重要。市面上有許多分割模型,它們的工作原理大致相似,通常包括收集數據、配置模型以及訓練分割模型等步驟。最終目標是實現精確的目標分割。而隨著 SAM(Segment Anything Model)的出現,這一過程變得更加高效。SAM 的獨特之處在于,它只需要用戶向模型提供某種坐標信息,就能自動完成所有分割工作,極大地簡化了操作流程。


在深入探討之前,可能會提出這樣一個問題:為何選擇 YOLO 模型作為我們的工具? 答案十分明確:SAM(Segment Anything Model)本身并不具備直接輸出目標類別標簽的功能。 它僅能依據用戶提供的位置信息來執行分割任務。而 YOLO 模型的引入,恰到好處地填補了這一空白。借助目標檢測模型,我們能夠精準地定位目標的位置,并獲取其對應的類別標簽。隨后,利用這些位置數據引導 SAM 進行分割操作,從而最終實現目標的清晰分割,并為分割結果賦予明確的類別標注。

與傳統分割模型不同,SAM(Segment Anything Model)在執行分割任務時,需要用戶主動提供目標的位置信息。這些位置信息有三種主要類型:

  1. 單點輸入:僅提供一個坐標點(x,y),用于指示目標的大致位置。
  2. 邊界框輸入:提供一個邊界框的坐標(x1,y1,x2,y2),明確指定目標的區域范圍。
  3. 多點輸入:同時輸入多個正點和負點,以更精細地引導模型進行分割。

鑒于我們采用的是 YOLO 模型,邊界框方法無疑是最佳選擇。YOLO 模型能夠直接輸出目標的邊界框坐標,這與 SAM 的輸入需求完美契合。因此,我們可以無縫地將 YOLO 模型的輸出作為 SAM 的輸入,從而實現高效的目標檢測與分割。在接下來的內容中,我們將詳細闡述如何將 YOLO 與 SAM 結合,以實現這一目標。

YOLOv8 目標檢測

在正式展開本文內容之前,若對如何從零開始訓練自定義的 YOLO 模型抱有興趣,不妨參考我過往撰寫的一篇文章《YOLOV8目標識別——詳細記錄從環境配置、自定義數據、模型訓練到模型推理部署》。不過,在本文中,為了便于快速上手和聚焦于核心問題,我將直接調用預訓練好的 yolov8n.pt 模型。若您選擇采用這一預訓練模型,僅需運行以下代碼,系統便會自動為您完成模型的下載工作。

conda create -n yolo_sam python==3.10
conda activate yolo_sam
pip install ultralytics
from ultralytics import YOLO# 加載模型
model = YOLO("yolov8n.pt")  # 預訓練的 YOLOv8n 模型# 對一系列圖像進行批量推理
results = model([r"ball.jpg"])  # 返回一個 Results 對象列表# 處理結果列表
for result in results:boxes = result.boxes  # 用于邊界框輸出的 Boxes 對象masks = result.masks  # 用于分割掩碼輸出的 Masks 對象keypoints = result.keypoints  # 用于姿態輸出的 Keypoints 對象probs = result.probs  # 用于分類輸出的 Probs 對象obb = result.obb  # 用于 OBB 輸出的 Oriented boxes 對象result.show()  # 顯示到屏幕result.save(filename="result.jpg")  # 保存到磁盤

檢測 + 分割與 SAM

在開始之前,你需要下載 SAM 模型。你可以從 Hugging Face 下載它(鏈接)。

1. 安裝必要的庫

pip install git+https://github.com/facebookresearch/segment-anything.git
pip install opencv-python mediapipe ultralytics numpy torch matplotlib

2. 導入庫

import torch
import cv2
import numpy as np
import matplotlib.pyplot as plt
from ultralytics import YOLO
from segment_anything import sam_model_registry, SamPredictor

3. 加載模型

# 加載 YOLO 模型
model = YOLO("yolov8n.pt") # 加載 SAM 模型
sam_checkpoint = "sam_vit_b_01ec64.pth"  # 替換為你的模型路徑
model_type = "vit_b"
device = "cuda" if torch.cuda.is_available() else "cpu"
print(device)sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device=device)
predictor = SamPredictor(sam)

4. 檢測 + 分割

# 加載圖像
image_path = r"ball.jpg"
image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 轉換為 RGB 格式以供 SAM 使用# 運行 YOLO 推理
results = model(image, conf=0.3)# 遍歷檢測結果
for result in results:# 獲取邊界框for box, cls in zip(result.boxes.xyxy, result.boxes.cls):   x1, y1, x2, y2 = map(int, box)  # 轉換為整數# 獲取 IDclass_id = int(cls)  # 類別 ID# 獲取類別標簽class_label = model.names[class_id]   # 準備 SAMpredictor.set_image(image_rgb)# 定義一個邊界框提示供 SAM 使用input_box = np.array([[x1, y1, x2, y2]])# 獲取 SAM 掩碼masks, _, _ = predictor.predict(box=input_box, multimask_output=False)# 創建原始圖像的副本以疊加掩碼highlighted_image = image_rgb.copy()# 將掩碼以半透明藍色應用于圖像mask = masks[0]# 創建一個空白圖像blue_overlay = np.zeros_like(image_rgb, dtype=np.uint8)  # 藍色用于分割區域(RGB)blue_overlay[mask == 1] = [0, 0, 255]   # 使用透明度將藍色疊加層與原始圖像混合alpha = 0.7  # 疊加層的透明度highlighted_image = cv2.addWeighted(highlighted_image, 1 - alpha, blue_overlay, alpha, 0)# 在邊界框上方添加標簽(類別名稱)font = cv2.FONT_HERSHEY_SIMPLEXlabel = f"{class_label}"  # 標簽為類別名稱cv2.putText(highlighted_image, label, (x1, y1 - 10), font, 2, (255, 255, 0), 2, cv2.LINE_AA)   # 可選:保存帶有邊界框和突出顯示的分割結果的圖像output_filename = f"highlighted_output.png"cv2.imwrite(output_filename, cv2.cvtColor(highlighted_image, cv2.COLOR_RGB2BGR))

交互加分割

使用 OpenCV 鼠標事件來畫框交互,并將框的坐標傳入 SAM 進行分割,是一種非常直觀且靈活的方法。

1. 代碼實現

import cv2
import numpy as np
import torch
from segment_anything import sam_model_registry, SamPredictor# 初始化全局變量
start_point = None
end_point = None
drawing = False# 鼠標回調函數
def draw_rectangle(event, x, y, flags, param):global start_point, end_point, drawingif event == cv2.EVENT_LBUTTONDOWN:start_point = (x, y)drawing = Trueelif event == cv2.EVENT_MOUSEMOVE:if drawing:end_point = (x, y)elif event == cv2.EVENT_LBUTTONUP:drawing = Falseend_point = (x, y)cv2.rectangle(image, start_point, end_point, (0, 255, 0), 2)cv2.imshow("Image", image)# 加載 SAM 模型
sam_checkpoint = "sam_vit_b_01ec64.pth"  # 替換為你的模型路徑
model_type = "vit_b"
device = "cuda" if torch.cuda.is_available() else "cpu"sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device=device)
predictor = SamPredictor(sam)# 加載圖像
image_path = "example.jpg"
image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 轉換為 RGB 格式# 創建窗口并綁定鼠標回調函數
cv2.namedWindow("Image")
cv2.setMouseCallback("Image", draw_rectangle)while True:cv2.imshow("Image", image)if cv2.waitKey(1) & 0xFF == ord('q'):break# 如果框已經畫好,進行分割if start_point and end_point:# 轉換為 SAM 需要的邊界框格式input_box = np.array([start_point[0], start_point[1], end_point[0], end_point[1]])input_box = np.array([min(input_box[0], input_box[2]), min(input_box[1], input_box[3]),max(input_box[0], input_box[2]), max(input_box[1], input_box[3])])# 生成分割掩碼predictor.set_image(image_rgb)masks, _, _ = predictor.predict(box=input_box, multimask_output=False)# 顯示分割結果highlighted_image = image_rgb.copy()mask = masks[0]blue_overlay = np.zeros_like(image_rgb, dtype=np.uint8)blue_overlay[mask == 1] = [0, 0, 255]  # 藍色掩碼highlighted_image = cv2.addWeighted(highlighted_image, 1, blue_overlay, 0.7, 0)cv2.imshow("Segmented Image", cv2.cvtColor(highlighted_image, cv2.COLOR_RGB2BGR))cv2.waitKey(0)cv2.destroyAllWindows()breakcv2.destroyAllWindows()

實現效果:
在這里插入圖片描述### 2. 代碼說明

  1. 全局變量

    • start_pointend_point 用于記錄鼠標點擊和釋放時的坐標。
    • drawing 用于標記是否正在繪制矩形。
  2. 鼠標回調函數

    • draw_rectangle 函數用于處理鼠標事件,包括按下、移動和釋放。
    • 當鼠標按下時,記錄起始點。
    • 當鼠標移動時,更新終點。
    • 當鼠標釋放時,繪制矩形并更新圖像。
  3. 加載 SAM 模型

    • 使用 sam_model_registry 加載預訓練的 SAM 模型。
    • 將模型移動到 GPU(如果可用)。
  4. 加載圖像

    • 使用 OpenCV 讀取圖像,并將其轉換為 RGB 格式以供 SAM 使用。
  5. 創建窗口并綁定鼠標回調

    • 使用 cv2.namedWindow 創建窗口。
    • 使用 cv2.setMouseCallback 綁定鼠標回調函數。
  6. 主循環

    • 顯示圖像并等待用戶操作。
    • 如果用戶繪制了矩形,將矩形的坐標轉換為 SAM 需要的格式,并調用 SAM 進行分割。
    • 顯示分割結果。

3. 運行效果

  1. 繪制矩形

    • 運行程序后,使用鼠標在圖像上繪制一個矩形框,表示需要分割的目標區域。
  2. 顯示分割結果

    • 按下 q 鍵后,程序會根據繪制的矩形框調用 SAM 進行分割,并顯示分割結果。

4. 注意事項

  • 圖像路徑:確保 image_path 指向正確的圖像文件。
  • 模型路徑:確保 sam_checkpoint 指向正確的 SAM 模型文件。
  • 環境依賴:確保安裝了必要的依賴庫,如 opencv-pythontorchsegment_anything

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76312.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76312.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76312.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Flutter中使用BottomNavigationBar和IndexedStack可以實現一個功能完整的底部導航欄

在Flutter中,使用BottomNavigationBar和IndexedStack可以實現一個功能完整的底部導航欄。BottomNavigationBar用于顯示底部的導航按鈕,而IndexedStack則用于管理頁面的切換,確保每個頁面的狀態得以保留(即頁面不會因為切換而重新構…

【10】數據結構的矩陣與廣義表篇章

目錄標題 二維以上矩陣矩陣存儲方式行序優先存儲列序優先存儲 特殊矩陣對稱矩陣稀疏矩陣三元組方式存儲稀疏矩陣的實現三元組初始化稀疏矩陣的初始化稀疏矩陣的創建展示當前稀疏矩陣稀疏矩陣的轉置 三元組稀疏矩陣的調試與總代碼十字鏈表方式存儲稀疏矩陣的實現十字鏈表數據標簽…

微服務篇——SpringCloud

服務注冊 Spring Cloud5大組件有哪些? 服務注冊和發現是什么意思?Spring Cloud如何實現服務注冊發現? nacos與eureka的區別 負載均衡 如何實現負載均衡? Ribbon負載均衡的策略有哪些? 如何自定義負載均衡的策略&…

【小沐雜貨鋪】基于Three.JS繪制三維數字地球Earth(GIS 、WebGL、vue、react,提供全部源代碼)

🍺三維數字地球系列相關文章如下🍺:1【小沐學GIS】基于C繪制三維數字地球Earth(456:OpenGL、glfw、glut)第一期2【小沐學GIS】基于C繪制三維數字地球Earth(456:OpenGL、glfw、glut)第二期3【小沐…

Cursor 在前端需求開發工作流中的應用|得物技術

一、引言 很高興與大家分享現階段 Cursor 在我的工作中的使用體驗。首先是預期管理,本篇文章不會分享 x 個你可能不知道的小技巧,也不會讓你擁有無需自行編碼的能力,同時不涉及 Cursor 工程化方面內容。僅僅是圍繞個人開發流程中的已有問題&…

PyQt學習記錄

PyQt學習記錄 要在界面上 創建一個控件,就需要在程序代碼中 創建 這個 控件對應類 地一個 實例對象。 在Qt系統中,控件(widget)是 層層嵌套 的,除了最頂層的控件,其他的控件都有父控件。 幾個函數 函數mo…

react: styled-components實現原理 標簽模版

styled-components是針對react中一個前端廣泛使用的css-in-js樣式庫B站 利用標簽模版 利用ES6中的 標簽模版文檔標簽模板其實不是模板,而是函數調用的一種特殊形式。“標簽”指的就是函數,緊跟在后面的模板字符串就是它的參數。 let a 5; let b 10;…

網絡安全應急響應之文件痕跡排查:從犯罪現場到數字狩獵的進化論

凌晨3點,某金融企業的服務器突然告警,核心數據庫出現未知進程訪問。安全團隊緊急介入時,攻擊者已抹去日志痕跡。在這場與黑客的時間賽跑中,文件痕跡排查成為破局關鍵。本文將帶您深入數字取證的"案發現場",揭…

多模態大語言模型arxiv論文略讀(七)

MLLM-DataEngine: An Iterative Refinement Approach for MLLM ?? 論文標題:MLLM-DataEngine: An Iterative Refinement Approach for MLLM ?? 論文作者:Zhiyuan Zhao, Linke Ouyang, Bin Wang, Siyuan Huang, Pan Zhang, Xiaoyi Dong, Jiaqi Wang,…

idea插件:AICommit,智能生成Git提交信息

AICommit:智能生成Git提交信息的IDEA插件指南 一、AICommit插件介紹 AICommit是一款專為開發者設計的IntelliJ IDEA插件,它利用人工智能技術自動生成清晰、規范的Git提交信息(Commit Message)。該插件能夠分析你的代碼變更,理解修改的上下文…

js 拷貝-包含處理循環引用問題

在 JavaScript 中,拷貝對象和數組時需要特別注意,因為對象和數組是引用類型,直接賦值只會復制引用,而不是實際的數據。以下是幾種常見的拷貝方法及其應用場景: 1. 淺拷貝(Shallow Copy) 淺拷貝…

oracle將varchar2 轉為clob類型存儲。 oracle不支持直接使用sql,將 varchar2 到clob的類型轉換,需要下面操作

將一個現有表中的 VARCHAR2 列數據遷移到一個 CLOB 列的過程。以下是對每一步操作的說明: 1. 添加一個新的 CLOB 類型列 首先,向表中添加一個新的 CLOB 類型的列。這個列將用來存儲原本的 VARCHAR2 數據。 ALTER TABLE your_table ADD (new_column CL…

Dynamics 365 Business Central Recurring Sales Lines 經常購買銷售行 來作 訂閱

#D365 BC ERP# #Navision# 前面有節文章專門介紹了BC 2024 Wave 2 支持的更好的Substription & Recurring Billing。 其實在D365 BC ERP中一直有一個比較簡單的訂閱模塊Recrring Sales Lines。本文將介紹一下如何用Recurring Sales Lines來 實施簡易的訂閱Substription。具…

算法比賽中常用的數學知識

一、求某個整數的正約數個數與正約數之和 1.1求某個正整數N的正約數個數 public class Main {public static void main(String[] args) {System.out.println(count(360));//結果為24}public static long count(long number){long count1;for(long i2;i<Math.sqrt(number);…

虛擬Ubuntu系統 開機提示:SMBus Host controller not enabled 后正常啟動,去除這個提示提升開機速度。

如題&#xff0c;虛擬機中的Ubuntu系統開機提示&#xff1a;SMBus Host controller not enabled&#xff0c;雖然能正常啟動&#xff0c;但不僅影響開機速度&#xff0c;而且還膈應人。 使用命令查看模塊 lsmod | grep piix4 發現i2c_piix4有問題&#xff0c; 禁止 i2c_piix4…

NLP基礎知識 與 詞向量的轉化方法 發展

目錄 1.NLP 基礎知識點 為什么需要自然語言處理? 自然語言處理有哪些分類? 自然語言處理有哪些實際應用? 為什么需要自然語言處理? 自然語言處理有哪些分類? 自然語言處理有哪些實際應用? 自然語言處理的技術/工作原理是什么? 2.NLP文本轉化為詞向量的方法 2…

【FPGA基礎學習】狀態機思想實現流水燈

目錄 一、用狀態機實現LED流水燈1.狀態機思想簡介1. 1基本概念1.2.核心要素1.3分類與模型 2.LED流水燈 二、CPLD與FPGA1.技術區別2.應用場景3.設計選擇建議 三、HDLbits組合邏輯題目 一、用狀態機實現LED流水燈 1.狀態機思想簡介 1. 1基本概念 ? 狀態機&#xff08;Finite …

CSS語言的游戲AI

CSS語言的游戲AI探討 隨著技術的飛速發展&#xff0c;游戲行業也在不斷地革命和演變。游戲中的人工智能&#xff08;AI&#xff09;作為一種重要的設計元素&#xff0c;其復雜性和智能程度對游戲的體驗、玩法和整體表現都有著深遠的影響。近年來&#xff0c;CSS&#xff08;Ca…

docker配置redis容器時配置文件docker-compose.yml示例

1.配置數據節點&#xff08;主從節點&#xff09; version: 3.7 services:master:image: redis:5.0.9container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: redis:5.0.9container_name: redis-slave1restart: a…

【WPF】IOC控制反轉的應用:彈窗但不互相調用ViewModel

全稱&#xff1a;Inversion of Control&#xff0c;控制反轉 場景&#xff1a;A頁面需要調用B/C頁面等&#xff0c;防止直接在VM中新建別的頁面實例&#xff0c;使用IOC設計架構&#xff1b; 創建Service&#xff0c;在Service中實現頁面的實例創建和定義頁面輸入輸出參數。 在…