基于RobustVideoMatting(RVM)進行視頻人像分割(torch、onnx版本)

發表時間:2021年8月25日
項目地址:https://peterl1n.github.io/RobustVideoMatting/
論文閱讀:https://hpg123.blog.csdn.net/article/details/134409222

RVM是字節團隊開源的一個實時人像分割模型,基于LSTMConv實現,在效果與性能上取得良好效果。為此,對齊開源代碼進行整理利用,實現對視頻人像的實時分割。本博客包含,torch版本、onnx版本代碼。請注意,RVM算法基于lstmconv實現,故推理時時序越長效果越穩定,屏閃概率越低。同時對比torch與onnx推理,發現torch推理速度比onnx快很多。
在這里插入圖片描述

1、環境準備

1.1 模型下載

本項目一共開源了兩個模型,有torch版本與onnx版本。這里需要下載torch模型與onnx模型
在這里插入圖片描述

1.2 視頻讀寫代碼

from torch.utils.data import DataLoader
from torchvision.transforms import ToTensor
from torch.utils.data import Dataset
from torchvision.transforms.functional import to_pil_image
from PIL import Imageimport decord
from torch.utils.data import Dataset
from PIL import Image
import numpy as npclass VideoReader(Dataset):def __init__(self, path, transform=None):# 初始化decord視頻讀取器,使用GPU加速(如果可用)self.vr = decord.VideoReader(path, ctx= decord.cpu(0)) #decord.gpu(0) # 獲取幀率self.rate = self.vr.get_avg_fps()self.transform = transform# 獲取視頻總幀數self.length = len(self.vr)@propertydef frame_rate(self):return self.ratedef __len__(self):return self.lengthdef __getitem__(self, idx):# 讀取指定索引的幀,返回numpy數組 (H, W, C),格式為RGBframe = self.vr[idx].asnumpy()# 轉換為PIL圖像frame = Image.fromarray(frame)# 應用變換if self.transform is not None:frame = self.transform(frame)return frameimport cv2
import numpy as npclass VideoWriter:def __init__(self, path, frame_rate, bit_rate=1000000):self.path = pathself.frame_rate = frame_rateself.bit_rate = bit_rateself.writer = Noneself.width = 0self.height = 0def write(self, frames):# frames: [T, C, H, W]# 獲取視頻尺寸self.width = frames.size(3)self.height = frames.size(2)# 如果是灰度圖則轉換為RGBif frames.size(1) == 1:frames = frames.repeat(1, 3, 1, 1)  # convert grayscale to RGB#([1, 3, 1280, 720])# 轉換為OpenCV需要的格式 [T, C, H, W] 且范圍為0-255的uint8frames = frames.mul(255).cpu().permute(0, 2, 3, 1).numpy().astype(np.uint8)# OpenCV默認使用BGR格式,需要轉換# 初始化視頻寫入器(首次調用write時)if self.writer is None:# 根據文件名后綴自動選擇編碼器fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 對于mp4格式# 如果是其他格式可以修改,例如'XVID'對應avi格式self.writer = cv2.VideoWriter(self.path,fourcc,self.frame_rate,(self.width, self.height))print(frames.shape,frames.dtype,frames.max(),self.width, self.height)for t in range(frames.shape[0]):frame = frames[t]frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)self.writer.write(frame)def close(self):if self.writer is not None:self.writer.release()

1.3 torch模型定義代碼

這里需要下載項目源碼與模型,注意是引入model目錄下的模型定義。
在這里插入圖片描述

2、視頻人像分割(torch版本)

2.1 模型加載代碼

import torch
from model import MattingNetworkmodel = MattingNetwork('mobilenetv3').eval().cuda()  # or "resnet50"
model.load_state_dict(torch.load('rvm_mobilenetv3.pth'))

2.3 調用代碼

import torch
bgr = torch.tensor([.47, 1, .6]).view(3, 1, 1).cuda()  # Green background.
rec = [None] * 4                                       # Initial recurrent states.
downsample_ratio = 0.25                                # Adjust based on your video.writer = VideoWriter('output.mp4', frame_rate=30)
batch=60
with torch.no_grad():for src in DataLoader(reader,batch_size=batch):                     # RGB tensor normalized to 0 ~ 1.while src.shape[0]<batch:src=torch.cat([src,src[-1:]])fgr, pha, *rec = model(src.cuda(), *rec, downsample_ratio)  # Cycle the recurrent states.fgr=fgr[:batch]pha=pha[:batch]com = fgr * pha + bgr * (1 - pha)              # Composite to green background. writer.write(com)                              # Write frame.
writer.close()

2.3 處理效果

3060顯卡,cuda12,torch 2.4,處理20s的720p,fps30 視頻,耗時14s。
在這里插入圖片描述

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

3、視頻人像分割(onnx版本)

3.1 onnx模型加載代碼

先將從github中下載的 模型在 https://netron.app/ 打開,確認是支持動態size的。
在這里插入圖片描述

這里的代碼為通用onnx模型推理代碼

import onnxruntime as ort
import numpy as np
from typing import Dict, List, Union, Tupleclass ONNXModel:"""簡化版ONNX Runtime封裝,模擬PyTorch模型調用風格僅實現forward方法,輸入輸出均為numpy數組"""def __init__(self, onnx_path: str, device: str = 'cpu'):self.onnx_path = onnx_path# 根據設備選擇執行提供程序providers = ['CPUExecutionProvider']if device.lower() == 'cuda' and 'CUDAExecutionProvider' in ort.get_available_providers():providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']# 初始化ONNX Runtime會話self.session = ort.InferenceSession(onnx_path, providers=providers)# 獲取輸入和輸出節點信息self.input_names = [input.name for input in self.session.get_inputs()]self.output_names = [output.name for output in self.session.get_outputs()]def forward(self, *args, **kwargs) -> Union[np.ndarray, Tuple[np.ndarray]]:"""前向傳播方法,模擬PyTorch的forward輸入: numpy數組,可以是位置參數(按輸入順序)或關鍵字參數(按輸入名稱)輸出: numpy數組或numpy數組元組"""# 準備輸入字典inputs = {}# 處理位置參數if args:if len(args) != len(self.input_names):raise ValueError(f"位置參數數量不匹配,預期{len(self.input_names)}個,得到{len(args)}個")for name, arg in zip(self.input_names, args):inputs[name] = arg# 處理關鍵字參數if kwargs:for name, value in kwargs.items():if name not in self.input_names:raise ValueError(f"未知的輸入名稱: {name},有效名稱為: {self.input_names}")inputs[name] = value# 檢查輸入完整性if len(inputs) != len(self.input_names):missing = set(self.input_names) - set(inputs.keys())raise ValueError(f"缺少輸入: {missing}")# for k in inputs.keys():#     print(k,inputs[k].shape,inputs[k].dtype)# 執行推理outputs = self.session.run(self.output_names,inputs)# 處理輸出格式if len(outputs) == 1:return outputs[0]return tuple(outputs)def __call__(self, *args, **kwargs) -> Union[np.ndarray, Tuple[np.ndarray]]:"""重載調用方法,使實例可以像PyTorch模型一樣被調用"""return self.forward(*args, **kwargs)
model = ONNXModel('rvm_mobilenetv3_fp16.onnx','cuda')

3.2 調用代碼

這里推理代碼與torch推理代碼高度一致,注意數據類型。


import torch
import time
bgr = torch.tensor([.47, 1, .6]).view(3, 1, 1).numpy().astype(np.float16)  # Green background.
rec = None                                    # Initial recurrent states.
downsample_ratio = np.array([0.25]).astype(np.float32)                             # Adjust based on your video.writer = VideoWriter('output.mp4', frame_rate=30)
batch=32
t0=time.time()
with torch.no_grad():for src in DataLoader(reader,batch_size=batch):                     # RGB tensor normalized to 0 ~ 1.while src.shape[0]<batch:src=torch.cat([src,src[-1:]])src=src.numpy().astype(np.float16)if rec is None:rec=[np.zeros((1,1,1,1),dtype=np.float16)]*4fgr, pha, *rec = model(src, *rec, downsample_ratio)  # Cycle the recurrent states.fgr=fgr[:batch]pha=pha[:batch]com = fgr * pha + bgr * (1 - pha)              # Composite to green background. com=torch.tensor(com)writer.write(com)                              # Write frame.
writer.close()
rt=time.time()-t0
print(f"視頻處理耗時:{rt:.4f}")

此時代碼耗時為46s,相比于torch慢了很多。

(32, 1280, 720, 3) uint8 255 720 1280
視頻處理耗時:45.9930

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

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

相關文章

強制從不抱怨環境。

警世俗語&#xff1a;強者逆襲心法&#xff08;句句穿心&#xff09;環境是泥潭&#xff1f;那就讓它開出金蓮&#xff01; —— 抱怨是弱者的裹腳布&#xff0c;行動是強者的登天梯。爛泥里也能種出搖錢樹&#xff0c;關鍵看你敢不敢下手挖&#xff01;老天爺發牌爛&#xff1…

MC0439符號統計

碼蹄集OJ-符號統計 MC0439?符號統計 難度&#xff1a;黃金 時間限制&#xff1a;1 秒 占用內存&#xff1a;256 M 收藏 報錯 在華容道放曹的緊張時刻&#xff0c;小碼哥接到了一個看似微不足道卻至關重要的任務&#xff1a;解讀一條僅由小寫英文字母組成的神秘字符串 s&#…

Android Jetpack 系列(五)Room 本地數據庫實戰詳解

1. 簡介 在需要輕量級本地持久化的場景中&#xff0c;DataStore 是一個理想的選擇&#xff08;詳見《Android Jetpack 系列&#xff08;四&#xff09;DataStore 全面解析與實踐》&#xff09;。但當你面臨如下需求時&#xff0c;本地數據庫便顯得尤為重要&#xff1a; 復雜的…

C語言實現類似C#的格式化輸出

在C#中&#xff0c;格式化輸出可以使用索引占位符以及復合格式的占位符&#xff0c;可以不用關心后面參數是什么類型&#xff0c;使用起來非常方便&#xff0c;如下簡單的示例&#xff1a; Console.WriteLine("{2} {1} {0} {{{2}}}", "Hello, World!", 1,…

一人公司方法論

** 一人公司方法論 ** 那什么是一人公司&#xff1f; 字面的理解就是一個人運營的公司&#xff0c;但實際上它指代的是比較少的人運營的小公司&#xff0c;一般來說 1 ~ 3 個人運營的公司&#xff0c;也可以把它放到一人公司的范圍以內。其他一些形式&#xff0c;比如說一個人再…

Ceph CSI 鏡像刪除流程與 Trash 機制失效問題分析文檔

#作者&#xff1a;閆乾苓 文章目錄一、問題背景二、實際行為三、源碼分析四、分析與推論五、期望行為與建議優化六、結論一、問題背景 在生產環境中&#xff0c;為避免因誤操作導致的永久數據丟失&#xff0c;Ceph RBD 提供了 Trash 功能&#xff0c;允許將鏡像“軟刪除”至回…

.NET Framework 3.5 不原生支持PreApplicationStartMethod特性

.NET Framework 3.5 不原生支持PreApplicationStartMethod特性。這個特性是在 .NET Framework 4.0 中引入的&#xff0c;用于在應用程序啟動早期執行初始化邏輯。 在.NET 3.5 中&#xff0c;如果你需要實現類似的 “應用啟動時自動注冊模塊” 功能&#xff0c;需要通過手動配置…

智能巡檢技術淺析

從機載智能硬件到深度學習算法&#xff0c;從實時邊緣計算到數字孿生平臺&#xff0c;無人機AI智能巡檢通過多模態感知、自主決策和持續進化&#xff0c;實現從"被動檢查"到"主動預防"的跨越式發展。機載智能硬件邊緣計算與機載AI芯片當代先進巡檢無人機已…

【圖像算法 - 11】基于深度學習 YOLO 與 ByteTrack 的目標檢測與多目標跟蹤系統(系統設計 + 算法實現 + 代碼詳解 + 擴展調優)

前言 詳細視頻介紹 【圖像算法 - 11】基于深度學習 YOLO 與 ByteTrack 的目標檢測與多目標跟蹤系統&#xff08;系統設計 算法實現 代碼詳解 擴展調優&#xff09;在計算機視覺應用中&#xff0c;目標檢測與多目標跟蹤的結合是實現智能視頻分析的關鍵。本文基于 YOLO 檢測模…

AI加持下的智能路由監控:Amazon VPC Direct Connect實戰指南

> 一次流量突增引發的生產事故,如何催生出融合流日志、機器學習與自動化告警的智能監控體系 深夜2點,電商平臺運維負責人李明的手機瘋狂報警——北美用戶下單量斷崖式下跌。他緊急登錄系統,發現跨境專線延遲飆升至2000ms。**經過3小時的排查**,罪魁禍首竟是新部署的CDN…

具身智能競速時刻,百度百舸提供全棧加速方案

2025年&#xff0c;全球具身智能賽道迎來快速發展期&#xff0c;技術方向日益清晰。每一家企業都面臨著同樣的核心命題&#xff1a;如何將前沿的模型能力&#xff0c;轉化為在真實世界各類場景中可規模化應用落地的機器人產品&#xff1f;這背后&#xff0c;是研發團隊對模型迭…

JavaScript 壓縮與混淆實戰:Terser 命令行詳解

使用 Terser 壓縮 JavaScript 文件&#xff08;基礎 現代語法問題解決&#xff09; 在前端開發中&#xff0c;隨著業務復雜度增加&#xff0c;JavaScript 文件體積越來越大。 文件大帶來的問題&#xff1a; 加載慢&#xff1a;文件越大&#xff0c;瀏覽器下載和解析時間越長…

【數據結構初階】--排序(三):冒泡排序、快速排序

&#x1f618;個人主頁&#xff1a;Cx330? &#x1f440;個人簡介&#xff1a;一個正在努力奮斗逆天改命的二本覺悟生 &#x1f4d6;個人專欄&#xff1a;《C語言》《LeetCode刷題集》《數據結構-初階》 前言&#xff1a;在上篇博客的學習中&#xff0c;我們掌握了直接選擇排序…

名詞概念:什么是尾部誤差?

“尾部誤差”就是指誤差分布在兩端的那一小撮、但數值特別大的誤差——也就是離中心&#xff08;均值/中位數&#xff09;很遠的“極端樣本”的誤差。對應統計學里的“分布尾部”&#xff08;tails&#xff09;。通俗點&#xff1a;大多數樣本誤差都很小&#xff0c;但總會有少…

記對外國某服務器的內網滲透

本專欄是筆者的網絡安全學習筆記&#xff0c;一面分享&#xff0c;同時作為筆記 文章目錄前文鏈接前言上線CS上線rdp后滲透信息收集SMB Pth攻擊權限維持魔幻上線提權關Windows Defenderend前文鏈接 WAMP/DVWA/sqli-labs 搭建burpsuite工具抓包及Intruder暴力破解的使用目錄掃描…

速賣通平臺關鍵字搜索商品列表列表接口實現指南:從接口分析到代碼落地

在跨境電商開發中&#xff0c;速賣通平臺的商品數據獲取是許多開發者關注的焦點。本文將詳細介紹如何實現速賣通關鍵字搜索商品列表接口&#xff0c;涵蓋接口請求參數分析、簽名機制、分頁處理及完整代碼實現&#xff0c;幫助開發者快速對接速賣通開放平臺。一、接口基本信息速…

UE UDP通信

1.確保工程為C工程&#xff0c;在項目工程的xx.Build.cs中加入Networking和Sockets模塊。PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Networking", "Socke…

JavaScript 邏輯運算符與實戰案例:從原理到落地

JavaScript 中的邏輯運算符不僅是條件判斷的核心&#xff0c;還能通過“短路特性”簡化代碼&#xff1b;結合 DOM 操作的實戰案例&#xff0c;更能體現其靈活性。本文整理了邏輯運算符的個人理解、優先級規則&#xff0c;以及 4 個高頻實戰需求的實現方案&#xff0c;附個人思路…

Android RxJava 過濾與條件操作詳解

RxJava 是一個基于觀察者模式的響應式編程庫&#xff0c;在 Android 開發中被廣泛使用。其中&#xff0c;過濾和條件操作是 RxJava 中非常重要的一部分&#xff0c;它們允許我們對數據流進行精細控制。本文將詳細介紹 RxJava 中常用的過濾與條件操作符及其使用場景。一、過濾操…

云手機都具有哪些特點?

云手機擁有著便捷的遠程操作功能&#xff0c;讓用戶無論身處何地&#xff0c;只要能連接網絡&#xff0c;就能通過手機、電腦等終端設備遠程操控云手機&#xff0c;無需受限于物理位置&#xff0c;大大提升了工作的靈活性與便捷性。云手機主要是依賴于云計算技術&#xff0c;能…