【小貪】項目實戰——Zero-shot根據文字提示分割出圖片目標掩碼

目標描述

給定RGB視頻或圖片,目標是分割出圖像中的指定目標掩碼。我們需要復現兩個Zero-shot的開源項目,分別為IDEA研究院的GroundingDINO和Facebook的SAM。首先使用目標檢測方法GroundingDINO,輸入想檢測目標的文字提示,可以獲得目標的anchor box。將上一步獲得的box信息作為SAM的提示,分割出目標mask。具體效果如下(測試數據來自VolumeDeform數據集):

在這里插入圖片描述

其中GroundingDINO根據white shirt的文字輸入計算的box信息為:"shirt_000500": "[194.23726, 2.378189, 524.09503, 441.5135]"。項目實測下來單張圖片的預測速度GroundingDINO要慢于SAM。GroundingDINO和SAM均會給出多個預測結果,當選擇置信度最高的結果時兩個模型也會存在預測不準確的情況。

論文簡介

GroundingDINO

GroundingDINO extends a closedset detector DINO by performing vision-language modality fusion at multiple phases, including a feature enhancer, a language-guided query selection module, and a cross-modality decoder. Such a deep fusion strategy effectively improves open-set object detection.

在這里插入圖片描述

SAM

  • 簡介:使用三個組件建立圖像分割的foundation model,解決一系列下游分割問題,可zero-shot生成
  • 關鍵技術:
    1. promptable分割任務:使用prompt engineering,prompt不確定時輸出多目標mask
    2. 分割模型:image encoder + prompt encoder -> mask decoder
    3. 數據驅動:SA-1B(1B masks from 11M imgs)手工標注->半自動->全自動
  • Limitation:存在不連貫不精細的mask結果;交互式實時mask生成但是img encoder耗時;text-to-mask任務效果不魯棒

在這里插入圖片描述
在這里插入圖片描述

項目實戰

兩個項目的復現很簡單,按照github的readme配置相關環境并運行程序。當然也可以直接使用一站式項目Grounded Segment Anything等。當需要分割的圖片較多時,可以修改GroundingDINO的demo.shdemo/inference_on_a_image.py文件將檢測結果保存至json文件。

demo/inference_on_a_image.py文件

# 修改plot_boxes_to_image函數輸出box信息
image_with_box, mask, box_coor = plot_boxes_to_image(image_pil, pred_dict)
# obj為目標名稱,i為當前圖片的索引
obj = 'shirt'
data = {f'{obj}_{str(i).zfill(6)}': str(list(box_coor.cpu().detach().numpy()))}
with open("box.json", "r", encoding="utf-8") as f:old_data = json.load(f)old_data.update(data)
with open("box.json", "w", encoding="utf-8") as f:json.dump(old_data, f, indent=4)# f.write(json.dumps(old_data, indent=4, ensure_ascii=False))
f.close()

然后SAM再讀取json文件獲取box信息,將SAM的輸入提示改為box。

測試代碼

import os
import numpy as np
import matplotlib.pyplot as plt
import cv2
import glob
import jsoncoords = []def show_mask(mask, ax, random_color=False):if random_color:color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)else:color = np.array([30 / 255, 144 / 255, 255 / 255, 0.6])h, w = mask.shape[-2:]mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)ax.imshow(mask_image)def show_points(coords, labels, ax, marker_size=375):pos_points = coords[labels == 1]neg_points = coords[labels == 0]ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white',linewidth=1.25)ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white',linewidth=1.25)def show_box(box, ax):x0, y0 = box[0], box[1]w, h = box[2] - box[0], box[3] - box[1]ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0, 0, 0, 0), lw=2))def on_click(event):global coordsif event.button == 1:x, y = event.xdata, event.ydataprint(f"鼠標左鍵點擊:x={x:.2f}, y={y:.2f}")coords.append([x, y])# if len(coords) == 2:#     fig.canvas.mpl_disconnect(cid)elif event.button == 3:print("鼠標右鍵點擊")def get_mask(image, mask_id=1, click_coords=False, choose_mask=False, box=None):image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# plt.figure(figsize=(10, 10))# plt.imshow(image)# plt.axis('on')if click_coords:global coordsfig, ax = plt.subplots()  # 創建畫布和子圖對象fig.set_size_inches(30, 20)  # 設置寬度和高度,單位為英寸(inch)ax.imshow(image)cid = fig.canvas.mpl_connect('button_press_event', on_click)plt.show()else:  # 如果使用 必須全局coords = []from segment_anything import SamPredictor, sam_model_registrysam_checkpoint = "sam_vit_h_4b8939.pth"model_type = "vit_h"device = "cuda"sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)sam.to(device=device)predictor = SamPredictor(sam)predictor.set_image(image)input_point = np.array(coords)input_label = np.array([1] * len(coords))# plt.figure(figsize=(10, 10))# plt.imshow(image)# show_points(input_point, input_label, plt.gca())# plt.axis('on')# plt.show()input_box = boxif len(coords) == 0:input_point = Noneinput_label = Nonemasks, scores, logits = predictor.predict(point_coords=input_point,point_labels=input_label,box=input_box[None, :],multimask_output=True)if choose_mask:plt.figure(figsize=(60, 20))plt.subplot(1, 3, 1)plt.imshow(image)show_mask(masks[0], plt.gca())# show_points(input_point, input_label, plt.gca())plt.title(f"Mask 0, Score: {scores[0]:.3f}", fontsize=18)plt.subplot(1, 3, 2)plt.imshow(image)show_mask(masks[1], plt.gca())# show_points(input_point, input_label, plt.gca())plt.title(f"Mask 1, Score: {scores[1]:.3f}", fontsize=18)plt.subplot(1, 3, 3)plt.imshow(image)show_mask(masks[2], plt.gca())# show_points(input_point, input_label, plt.gca())plt.title(f"Mask 2, Score: {scores[1]:.3f}", fontsize=18)plt.show()mask_id = int(input())  # 通過輸入idx或者設置特定的idx輸出mask = masks[mask_id]mask = np.tile(np.expand_dims(mask, axis=-1), 3)mask_data = np.where(mask, 255, 0)# mask_image = np.where(mask, image/255, 0.)# plt.figure(figsize=(10, 10))# plt.imshow(mask_image)# plt.show()if click_coords: coords.clear()return mask_dataif __name__ == '__main__':obj = 'shirt'color_path = f'/Data/VolumeDeformData/{obj}/data/'mask_path = f'/Data/VolumeDeformData/{obj}/mask/'if not os.path.exists(mask_path):os.makedirs(mask_path)img_paths = []for extension in ["jpg", "png", "jpeg"]:img_paths += glob.glob(os.path.join(color_path, "*.{}".format(extension)))json_path = 'GroundingDINO-main/box.json'with open(json_path, "r", encoding="utf-8") as f:data = json.load(f)for i in range(len(img_paths) // 2):img_name = f'frame-{str(i).zfill(6)}.color.png'img = cv2.imread(color_path + img_name)id = f'{obj}_{str(i).zfill(6)}'box = np.array(list(map(float, data[id][1:-1].split(','))))mask = get_mask(img, mask_id=2, click_coords=False, choose_mask=False, box=box)cv2.imwrite(mask_path + str(i).zfill(6) + '.png', mask)print(img_name)f.close()

相關鏈接

  • GroundingDINO github arXiv
  • SAM Demo github arXiv
  • Grounded Segment Anything github

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

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

相關文章

uniapp中如何進行微信小程序的分包

思路:在uniapp中對微信小程序進行分包,和原生微信小程序進行分包的操作基本上沒區別,主要就是在pages.json中進行配置。 如圖,我新增了一個包diver-page 此時需要在pages.json中的subPackages數組中新增一項 root代表這個包的根…

用好華為小助手,生活總能快人一步

嘿!朋友們!你們有沒有想過,如果身邊有一個小助手,他不僅聰明伶俐,還能在生活的方方面面給予你最貼心的關懷和幫助,讓我們的日常生活變得更加方便和快捷,那該有多好!沒錯,…

【云原生】Kubernetes資源配額+HPA+節點選擇器+親和性+污點

Kubernetes高級功能 文章目錄 Kubernetes高級功能一、資源配額1.1、什么是資源配額1.2、資源配額應用1.2.1、針對Namespace設置資源配額1.2.2、針對Pod設置資源配額 二、HorizontalPodAutoscaler(HPA)2.1、什么是HorizontalPodAutoscaler2.2、Horizontal…

談談創意設計中的AI、AGI、AIGC

在當今的數字化時代,創意設計領域正經歷著前所未有的變革。隨著人工智能(AI)、通用人工智能(AGI)以及人工智能生成內容(AIGC)的迅猛發展,設計師們的工作方式和創作手段都發生了深刻的…

Spring Boot中的緩存配置與優化

Spring Boot中的緩存配置與優化 大家好,我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿!今天我們將探討在Spring Boot應用中如何配置和優化緩存,以提升系統的…

UML形式化建模期末復習筆記

本文檔為xmind導出,可能存在缺少圖片等問題,建議下載思維導圖查看完整內容 鏈接: https://pan.baidu.com/s/17s-utC2C6Qg0tFp61Kw0ZQ?pwduq64 提取碼: uq64 概述 UML: Unified Modeling Language 統一建模語言 建模 定義 把不太理解的東西和一些已經較…

隔離級別是如何實現的?

在數據庫管理系統中,隔離級別(Isolation Level)是用來定義事務在執行過程中可以看到其他事務執行中的操作的一個設置。這主要用于控制事務之間的并發性和數據一致性。SQL標準定義了四種隔離級別,每種級別都以不同的方式平衡了性能…

Swift 中的 StoreKit 測試

文章目錄 前言創建一個 StoreKit Demo使用 SKTestSessionaskToBuyEnabled 屬性總結前言 StoreKit 框架的第二次迭代是我在過去幾年中應用程序中最重大的變化。最近版本的 StoreKit 框架已完全采用了 Swift 語言特性,如 async 和 await。本篇內容我們將討論 StoreKitTest 框架…

【揭秘】嘴尚絕鹵味健康新風尚,讓你吃得美味又健康!

在快節奏的現代生活中,美食不僅是味蕾的享受,更是健康生活的追求。今天,我們要聊的就是備受食客們青睞的“嘴尚絕鹵味”——如何在享受美味的同時,也能兼顧健康飲食的理念。 一、鹵味文化,源遠流長 鹵味,作…

Redis緩存管理機制

在當今快節奏的數字世界中,性能優化對于提供無縫的用戶體驗至關重要。緩存在提高應用程序性能方面發揮著至關重要的作用,它通過將經常使用或處理的數據存儲在臨時高速存儲中來減少數據庫負載并縮短響應時間,從而減少系統的延遲。Redis 是一種…

navicat Lite 版

navicat Lite 版: Navicat 出了一個 Navicat Premium 的Lite版。 官方現在鏈接:https://www.navicat.com.cn/download/navicat-premium-lite#windows 從官網可以看到現在能夠下載最新版本 17,支持各種平臺

[vue2/vue3] 詳細剖析watch、computed、watchEffect的區別,原理解讀

前言:哈嘍,大家好,我是前端菜鳥的自我修養!今天給大家分享【深入剖析watch、computed、watchEffect的區別】,并提供具體代碼幫助大家深入理解,徹底掌握!原創不易,如果能幫助到帶大家…

為什么企業應用開發,c++干不過java?

在開始前剛好我有一些資料,是我根據網友給的問題精心整理了一份「c的資料從專業入門到高級教程」, 點個關注在評論區回復“888”之后私信回復“888”,全部無償共享給大家!!! C/C這種東西,根本…

使用Optimum的BetterTransformer為常見的transformer結構模型進行推理加速

概述 🤗 Optimum 提供了一個名為 BetterTransformer 的 API,這是標準 PyTorch Transformer API 的快速路徑,能夠通過稀疏性和融合內核(如 Flash Attention)在 CPU 和 GPU 上實現有趣的加速。目前,BetterTr…

一個 API 客戶端和一份 TS 學習手冊

第75期: Insomnia:超好看的 API 客戶端 項目介紹: 一款適用于 GraphQL、REST、WebSockets 和 gRPC 的開源 API 客戶端,顏值超高。 跨平臺,支持 Mac、Windows 和 Linux。但不支持網頁版,需要下載客戶端。…

Supabase 自托管部署實踐

Supabase 是 Firebase 的開源替代品。使用 Postgres 數據庫、身份驗證、即時 API、邊緣函數、實時訂閱、存儲和向量嵌入來啟動您的項目。 Supabase介紹 Supabase 是一個開源的后端即服務(BaaS)平臺,提供了一系列工具和服務,幫助…

CrimsonEDR:一款惡意軟件模式識別與EDR策略評估工具

關于CrimsonEDR CrimsonEDR是一個功能強大的開源項目,該項目旨在幫助廣大研究人員識別特定的惡意軟件模式,以此來優化終端檢測與響應(EDR)的策略方案。通過使用各種不同的檢測方案,可以加深開發人員與研究人員加深對安…

SpringBoot入門實戰:SpringBoot整合WebSocket

1.背景介紹 SpringBoot是一個快速開發的框架,它可以幫助我們快速開發Web應用程序。SpringBoot整合WebSocket是SpringBoot的一個組件,它可以幫助我們快速開發WebSocket應用程序。 WebSocket是一種新的協議,它可以讓客戶端和服務器之間建立持久…

MSYS2教程(windows環境下使用linux工具)

MSYS2教程(windows環境下使用linux工具) 1.msys2簡介 MSYS2(Minimal SYStem 2)是一個集成了大量的GNU工具鏈、工具和庫的開源軟件包集合。它提供了一個類似于Linux的shell環境,可以在Windows系統中編譯和運行許多Linux應用程序和工具。 MS…

數據增強:目標檢測算法的煉金術

數據增強:目標檢測算法的煉金術 在目標檢測領域,數據增強技術是一種提高模型泛化能力和性能的關鍵方法。通過數據增強,我們可以從現有的訓練集中生成更多的訓練樣本,這些樣本通過應用不同的變換來模擬真實世界中的多樣性。本文將…