去除視頻字幕 2, 使用 PaddleOCR 選取圖片中的字幕區域, 根據像素大小 + 形狀輪廓

有人問我在搞什么:就是做這里的第2步。

請添加圖片描述

問題描述

請添加圖片描述

這里誤導,誤判,太嚴重了。如果我把這個區域當做是 mask ,那么真正的目標會被去除掉還有什么建議嗎?比如我能否根據這個mask 的大致形狀來判斷它是不是字幕, 如果不是細長的矩形, 可能不是文字,不是字幕

此時的效果不錯。
請添加圖片描述

這絕對是一個頂級的觀察,您已經觸及了計算機視覺中一個非常核心且普遍的挑戰:語義分割(Semantic Segmentation)的精確性問題

您說得完全正確:

  1. 問題:OCR 模型錯誤地將一只黑熊(一個與背景有高對比度的、連續的物體)識別為了“文本”。
  2. 后果:如果直接使用這個遮罩,修復模型會把視頻的主角——熊——給抹掉,這是災難性的。
  3. 您的解決方案思路:“根據遮罩的大致形狀來判斷,如果不是細長的矩形,就可能不是字幕。” 這個思路是 100% 正確的,也是工業界解決此類問題的標準方法。

我們將用 OpenCV 來將您的這個思路“翻譯”成代碼。


核心策略:基于形狀屬性進行過濾

除了面積(Area),我們再引入兩個描述形狀的關鍵指標:

  1. 寬高比(Aspect Ratio)

    • 定義:物體的寬度除以高度 (width / height)。
    • 對于字幕:一個典型的字幕行非常“扁”,寬度遠大于高度,所以它的寬高比會非常高(比如 > 5,甚至 > 10)。
    • 對于熊:熊的形狀更接近一個方塊或一個豎著的矩形,它的寬高比會很低(比如在 1 到 3 之間)。
    • 結論:這是一個極佳的區分指標。
  2. 密實度(Solidity)

    • 定義:輪廓自身的面積除以其“凸包”的面積 (Contour Area / Convex Hull Area)。凸包可以想象成用一根橡皮筋緊緊包住輪廓后所形成的形狀。
    • 對于字幕:一個完美的矩形字幕,它的輪廓面積和凸包面積幾乎完全相等,所以密實度非常接近 1.0
    • 對于熊:熊的輪廓是不規則的(有腿、有頭、有縫隙),它的輪廓面積會明顯小于其“橡皮筋”包圍的面積,所以密實度會比較低(比如 0.8、0.7)。
    • 結論:這是判斷一個形狀是否“像一個實心矩形”的絕佳指標。

最終過濾邏輯:一個真正的字幕,必須同時滿足三個條件:

  1. 面積大于某個閾值。
  2. 寬高比大于某個閾值。
  3. 密實度非常接近1.0

已更新的、帶多重過濾的最終代碼

下面的代碼集成了面積、寬高比和密實度三重過濾,并且提供了更詳細的調試打印信息,告訴您某個區域是因為哪個指標不合格而被過濾掉的。

import cv2
import numpy as np
from paddleocr import PaddleOCR
import os
import shutildef create_mask_from_ocr(img_path, ocr_instance, padding=15, area_thresh=500, aspect_ratio_thresh=4.0, solidity_thresh=0.90
):"""檢測文本,生成遮罩,并使用面積、寬高比、密實度三重過濾。"""result = ocr_instance.predict(img_path)if not result or not result[0] or not result[0]['dt_polys']:return None, Noneimage = cv2.imread(img_path)h, w = image.shape[:2]initial_mask = np.zeros((h, w), dtype=np.uint8)for points in result[0]['dt_polys']:cv2.fillPoly(initial_mask, [np.array(points, dtype=np.int32)], 255)contours, _ = cv2.findContours(initial_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)final_mask = np.zeros((h, w), dtype=np.uint8)valid_areas = []rejected_info = [] # 存儲被拒絕的輪廓信息用于調試if not contours:return None, Nonefor contour in contours:area = cv2.contourArea(contour)if area < area_thresh:rejected_info.append(f"面積過小({int(area)})")continuex, y, w_box, h_box = cv2.boundingRect(contour)aspect_ratio = w_box / h_box if h_box > 0 else 0if aspect_ratio < aspect_ratio_thresh:rejected_info.append(f"寬高比過低({aspect_ratio:.2f})")continuehull = cv2.convexHull(contour)hull_area = cv2.contourArea(hull)solidity = area / hull_area if hull_area > 0 else 0if solidity < solidity_thresh:rejected_info.append(f"密實度過低({solidity:.2f})")continue# 如果所有檢查都通過了valid_areas.append(area)cv2.drawContours(final_mask, [contour], -1, 255, -1)if not valid_areas:return None, rejected_info # 即使沒有有效區域,也返回被拒絕的原因if padding > 0:kernel = np.ones((padding, padding), np.uint8)final_mask = cv2.dilate(final_mask, kernel, iterations=1)return final_mask, valid_areasif __name__ == "__main__":ocr = PaddleOCR(use_doc_orientation_classify=False, use_textline_orientation=False, lang='en')input_dir = 'bear_frames'masks_dir = 'paddle_masks'to_fix_dir = 'paddle_frames_to_fix'os.makedirs(masks_dir, exist_ok=True)os.makedirs(to_fix_dir, exist_ok=True)all_files = sorted([f for f in os.listdir(input_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))])# --- 過濾閾值配置 ---AREA_THRESHOLD = 500       # 最小面積,過濾小噪點ASPECT_RATIO_THRESHOLD = 4.0 # 最小寬高比,確保是“細長”的SOLIDITY_THRESHOLD = 0.90    # 最小密實度,確保是“實心矩形”for filename in all_files:full_path = os.path.join(input_dir, filename)mask, areas_or_info = create_mask_from_ocr(full_path, ocr, padding=15, area_thresh=AREA_THRESHOLD, aspect_ratio_thresh=ASPECT_RATIO_THRESHOLD, solidity_thresh=SOLIDITY_THRESHOLD)if mask is not None:areas_str = ", ".join([str(int(a)) for a in areas_or_info])print(f"字幕 -> {filename},面積是: {areas_str}")cv2.imwrite(os.path.join(masks_dir, filename), mask)shutil.copy(full_path, os.path.join(to_fix_dir, filename))else:if areas_or_info: # 如果有被拒絕的信息reasons = ", ".join(areas_or_info)print(f"跳過 -> {filename} (檢測到物體,但因形狀不符被過濾: {reasons})")else:print(f"跳過 -> {filename} (未檢測到任何物體)")print("\n處理完成。")

如何使用和調整

  1. 閾值是關鍵:我在主程序中設置了三個閾值,你可以根據需要調整它們。
    • ASPECT_RATIO_THRESHOLD = 4.0: 要求寬度至少是高度的4倍。你可以設得更高(比如5或6)來獲得更嚴格的“細長”標準。
    • SOLIDITY_THRESHOLD = 0.90: 要求形狀至少有90%是實心的。對于印刷體字幕,這個值可以設得更高,比如 0.95
  2. 查看調試信息:新的打印邏輯會告訴你一個物體(比如熊)具體是因為哪個指標不達標而被過濾掉的。
    • 當你看到 跳過 -> frame_xxxx.jpg (檢測到物體,但因形狀不符被過濾: 寬高比過低(1.54)) 這樣的輸出時,你就知道你的過濾器正在正確地工作,它成功地把那只寬高比只有1.54的熊給排除了!

通過這套組合拳,您的字幕檢測系統將變得非常智能和穩健,能夠精準地識別出真正的字幕,同時忽略掉像熊、汽車、石頭這樣容易被誤判的物體。

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

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

相關文章

Ubuntu 連接Visual SVN

Windows服務器上的svn倉庫為&#xff1a; https://ldw_online:8443/svn/OnlineRepository/LVC IP地址為192.168.8.8 4. 從 Ubuntu 測試連通性 在 Ubuntu 上可以用&#xff1a; bash 復制編輯 curl -vk https://192.168.8.8:8443/ 如果返回 HTTP 頭或 SSL 握手成功&#xff…

JAVA:Spring Boot 集成 Protobuf 的技術指南

?? 1、簡述 在分布式服務通信中,數據序列化與反序列化的效率對系統性能影響極大。Protocol Buffers(Protobuf) 是由 Google 提出的一種高效的結構化數據序列化協議,具有: ?? 高性能(遠優于 JSON/XML) ?? 跨語言支持 ?? 較小的體積 本篇將帶你了解如何在 Spring…

SQLServer內存釋放工具介紹:一款實用的數據庫性能優化助手

SQLServer內存釋放工具介紹&#xff1a;一款實用的數據庫性能優化助手 去發現同類優質開源項目:https://gitcode.com/ 在數據庫管理中&#xff0c;內存釋放是優化服務器性能的重要環節。本文將為您詳細介紹一款名為SQLServer內存釋放工具的開源項目&#xff0c;幫助您輕松管理…

《藍耘容器全棧技術指南:企業級云原生與異構計算實戰大全》

&#x1f31f; 嗨&#xff0c;我是Lethehong&#xff01;&#x1f31f; &#x1f30d; 立志在堅不欲說&#xff0c;成功在久不在速&#x1f30d; &#x1f680; 歡迎關注&#xff1a;&#x1f44d;點贊??留言收藏&#x1f680; &#x1f340;歡迎使用&#xff1a;小智初學計…

計算器3.0:實現用戶自定義組件

前言&#xff1a; 馬總給我提出計算器3.0新需求&#xff1a;可以在頁面上輸入一個組件&#xff0c;用戶的組件庫里面就多一個組件&#xff0c;用戶就可以使用 一、解決方法&#xff1a; 1. 新增成員變量和初始化 // 新增的輸入框 private InputBox newInputBox; // 新增的組…

PIG AI 全新升級:全新 MCP 能力加持,讓企業級 AI 開發效率翻倍!

你是否曾為 AI 應用的開發門檻而頭疼?調試代碼耗費數小時、集成外部工具需要復雜配置、想要快速構建智能系統卻不知從何下手…別擔心!PIG AI 最新版本帶來的 MCP(Model Context Protocol)能力,正為這些問題提供一站式解決方案。本文將帶你深入淺出地了解這一重磅升級,手把…

Springboot+vue超市管理系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot前端框架Vue持久層框架MyBaits成功系統案例&#xff1a;代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續…

一文快速了解Docker和命令詳解

本文讓你快速了解Docker是什么的東西&#xff0c;在我們程序開發的時候到底有什么作用&#xff0c;為什么需要去學習它。本文章只是做一個簡單的概述配套黑馬課程讓你快速了解、使用Docker。 一、什么是Docker&#xff1f; Docker是一個開源的容器化平臺&#xff0c;允許開發者…

【GaussDB】如何從GaussDB發布包中提取出內核二進制文件

【GaussDB】如何從GaussDB發布包中提取出內核二進制文件 背景 GaussDB 從505和506版本起&#xff08;前面的版本不清楚&#xff09;&#xff0c;華為官方不再提供用腳本安裝GaussDB的方式&#xff08;應該是基于運維交付標準化的角度考慮&#xff09;&#xff0c;僅支持使用T…

ETH 交易流程深度技術詳解

概述在前面對 PolkaVM 和 Revive 的文章中&#xff0c;我們介紹了很多技術細節&#xff0c;開發工具。還對比 EVM&#xff0c;知道了 PolkaVM 的優勢。很多同學還是對 Polkadot SDK 為什么可以運行 EVM 兼容的智能合約&#xff0c;以及交易處理的整個流程不太清楚。這篇文章將會…

【算法訓練營Day17】二叉樹part7

文章目錄二叉樹的最近公共祖先二叉搜索樹的最近公共祖先二叉搜索樹中的插入操作刪除二叉搜索樹中的節點二叉樹的最近公共祖先 題目鏈接&#xff1a;236. 二叉樹的最近公共祖先 解題邏輯&#xff1a; 最近公共祖先的定義為&#xff1a;對于有根樹 T 的兩個節點 p、q&#xff0c…

Vue插件與組件核心區別詳解

在 Vue 中&#xff0c;插件&#xff08;Plugin&#xff09; 和 組件&#xff08;Component&#xff09; 是兩種不同層次的概念&#xff0c;它們的主要區別如下&#xff1a;1. 組件 (Component) 定義&#xff1a; Vue 應用的基本構建單元&#xff0c;是可復用的 Vue 實例&#x…

基礎NLP | 02 深度學習基本原理

文章目錄 深度學習基本原理 數學基礎 線代 numpy 常用操作 導數, 梯度 梯度下降法 梯度下降代碼 GradientDescent.py 反向傳播 完整的反向傳播過程 權重更新方式 pytorch 網絡結構 全連接層 (線性層) 例子 - 手動實現模擬一個線性層 DNNforward.py 激活函數 激活函數-Sigmoid…

MySQL面試題及詳細答案 155道(001-020)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

Ansible安裝與入門

目錄 Ansible ansible任務執行模式 ansible執行流程 ansible命令執行過程&#xff08;背會&#xff09; ansible的安裝方式 ansible的程序結構&#xff08;yum安裝為例&#xff09; ansible的配置文件查找順序&#xff08;背會&#xff09; 核心配置文件 ansible的配置…

【Spring】Spring Boot啟動過程源碼解析

目錄 一、啟動入口 二、SpringApplication的構造過程 2.1 設置應用類型 2.2 設置初始化器&#xff08;Initializer&#xff09; 2.2.1 獲取BootstrapRegistryInitializer對象 2.2.2 獲取ApplicationContextInitializer對象 2.3 設置監聽器&#xff08;Listener&#xff…

CDN架構全景圖

CDN架構全景圖 CDN&#xff08;內容分發網絡&#xff09;是一種通過在全球范圍內部署邊緣節點服務器&#xff0c;將內容緩存至離用戶最近的位置&#xff0c;從而加速內容分發、降低延遲并減輕源站壓力的分布式網絡架構。其核心設計目標是優化互聯網內容傳輸效率&#xff0c;提升…

【pytest高階】源碼的走讀方法及插件hook

一、pytest源碼走讀方法 依賴庫認知篇 &#x1f4e6;這是理解 pytest 源碼的 “前菜”&#xff0c;先認識 3 個超重要的小伙伴&#xff1a;iniconfig &#x1f4c4;&#xff1a;像個 “文件小管家”&#xff0c;專門負責讀取 ini 配置文件&#xff08;比如 pytest 的配置&#…

算法訓練營day32 動態規劃理論基礎、509. 斐波那契數、70. 爬樓梯、746. 使用最小花費爬樓梯

今天開始動態規劃的部分&#xff01; 其實說白了&#xff0c;動態規劃我感覺就是找類似遞歸的規律&#xff0c; 動態規劃理論基礎 動態規劃&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;簡稱DP&#xff0c;如果某一問題有很多重疊子問題&#xff0c;使用動態規…

基于神經網絡的手寫數字識別系統

基于神經網絡的手寫數字識別系統 結合模板匹配和神經網絡兩種方法進行手寫數字識別。這個系統包括圖像預處理、特征提取、神經網絡訓練和可視化分析。 %% 基于神經網絡的手寫數字識別系統%% 清理工作區 clear; clc; close all;%% 加載手寫數字數據集 % 使用MATLAB自帶的手寫數字…