音頻分類標注工具

pyqt 分類標注工具:

import glob
import sys
import json
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableWidget, QTableWidgetItem,QSplitter, QVBoxLayout, QWidget, QPushButton, QRadioButton,QButtonGroup, QLabel, QHBoxLayout, QMessageBox
)
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QColor
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContentclass AudioAnnotator(QMainWindow):def __init__(self,base_dir):super().__init__()self.setWindowTitle("MP3標注工具 (單選標注)")self.setGeometry(100, 100, 1000, 600)  # 增大窗口尺寸# 初始化媒體播放器self.player = QMediaPlayer()# 主布局main_widget = QWidget()self.setCentralWidget(main_widget)layout = QVBoxLayout()main_widget.setLayout(layout)# 分割左右區域splitter = QSplitter(Qt.Horizontal)# 左側:音頻文件列表(表格)self.table = QTableWidget()self.table.setColumnCount(2)self.table.setHorizontalHeaderLabels(["音頻文件", "標注狀態"])self.table.setEditTriggers(QTableWidget.NoEditTriggers)self.table.cellClicked.connect(self.play_audio)self.table.setColumnWidth(0, 400)  # 文件名列寬self.table.setColumnWidth(1, 150)  # 狀態列寬# 右側:單選標注區域right_panel = QWidget()right_layout = QVBoxLayout()# 單選按鈕組self.radio_group = QButtonGroup()self.radio_1 = QRadioButton("small (1)")self.radio_2 = QRadioButton("normal (2)")self.radio_3 = QRadioButton("3 (3)")self.radio_group.addButton(self.radio_1, 1)self.radio_group.addButton(self.radio_2, 2)self.radio_group.addButton(self.radio_3, 3)self.radio_group.buttonClicked[int].connect(self.on_radio_selected)right_layout.addWidget(QLabel("標注選項:"))right_layout.addWidget(self.radio_1)right_layout.addWidget(self.radio_2)right_layout.addWidget(self.radio_3)right_layout.addStretch()right_panel.setLayout(right_layout)# 底部按鈕self.btn_save = QPushButton("保存標注")self.btn_save.clicked.connect(self.save_annotation)# 添加到布局splitter.addWidget(self.table)splitter.addWidget(right_panel)layout.addWidget(splitter)layout.addWidget(self.btn_save)self.json_path=os.path.basename(base_dir)+'.json'files = glob.glob(base_dir + "/*.mp3")self.audio_files = files# 加載歷史標注self.annotations = {}self.load_annotations()self.load_audio_files()def on_radio_selected(self, checked_id):print(f"選中了按鈕 ID: {checked_id}")current_row = self.table.currentRow()if current_row >= 0:audio_file = self.audio_files[current_row]checked_id = self.radio_group.checkedId()if checked_id == -1:QMessageBox.warning(self, "警告", "請選擇標注選項!")return# 更新標注字典self.annotations[audio_file] = checked_id# 保存到JSON文件with open(self.json_path, "w", encoding="utf-8") as f:json.dump(self.annotations, f, ensure_ascii=False, indent=4)# 更新表格顯示self.load_audio_files()def load_audio_files(self):"""加載音頻文件到表格并顯示標注狀態"""self.table.setRowCount(len(self.audio_files))# 標注選項映射label_map = {1: "small", 2: "normal", 3: "3"}for i, file in enumerate(self.audio_files):# 文件名列file_item = QTableWidgetItem(file)self.table.setItem(i, 0, file_item)# 狀態列status_item = QTableWidgetItem()if file in self.annotations:label_id = self.annotations[file]status_item.setText(f"已標注: {label_map.get(label_id, '未知')}")file_item.setBackground(QColor(200, 255, 200))  # 淺綠色背景status_item.setBackground(QColor(200, 255, 200))else:status_item.setText("未標注")file_item.setBackground(QColor(255, 200, 200))  # 淺紅色背景status_item.setBackground(QColor(255, 200, 200))self.table.setItem(i, 1, status_item)def play_audio(self, row, column):if column > 0:  # 只在點擊第一列時觸發returnfile_path = self.audio_files[row]print('start play',file_path)media_content = QMediaContent(QUrl.fromLocalFile(file_path))self.player.setMedia(media_content)self.player.play()# 加載該音頻的歷史標注if file_path in self.annotations:checked_id = self.annotations[file_path]self.radio_group.button(checked_id).setChecked(True)else:self.radio_group.setExclusive(False)for btn in self.radio_group.buttons():btn.setChecked(False)self.radio_group.setExclusive(True)def save_annotation(self):"""保存標注到JSON文件"""current_row = self.table.currentRow()if current_row >= 0:audio_file = self.audio_files[current_row]checked_id = self.radio_group.checkedId()if checked_id == -1:QMessageBox.warning(self, "警告", "請選擇標注選項!")return# 更新標注字典self.annotations[audio_file] = checked_id# 保存到JSON文件with open(self.json_path, "w", encoding="utf-8") as f:json.dump(self.annotations, f, ensure_ascii=False, indent=4)# 更新表格顯示self.load_audio_files()QMessageBox.information(self, "成功", f"標注已保存:{os.path.basename(audio_file)} -> {checked_id}")else:QMessageBox.warning(self, "警告", "請先選中音頻文件!")def load_annotations(self):"""加載歷史標注文件"""if os.path.exists(self.json_path):try:with open(self.json_path, "r", encoding="utf-8") as f:self.annotations = json.load(f)# 轉換鍵為絕對路徑(如果保存的是相對路徑)base_dir = os.path.dirname(os.path.abspath(self.json_path))fixed_annotations = {}for k, v in self.annotations.items():if not os.path.isabs(k):fixed_path = os.path.join(base_dir, k)if os.path.exists(fixed_path):fixed_annotations[fixed_path] = velse:fixed_annotations[k] = velse:fixed_annotations[k] = vself.annotations = fixed_annotationsexcept Exception as e:QMessageBox.warning(self, "警告", f"加載標注文件出錯: {str(e)}")self.annotations = {}if __name__ == "__main__":base_dir = r"/Users/lbg/Documents/data/audio_0817_low"app = QApplication(sys.argv)window = AudioAnnotator(base_dir)window.show()sys.exit(app.exec_())

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

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

相關文章

云計算-Kubernetes+Istio 實現金絲雀發布:流量管理、熔斷、流量鏡像、ingreess、污點及pv案例實戰

介紹 在微服務架構中,如何安全、高效地實現服務發布與流量管理是保障業務穩定性的核心挑戰。金絲雀發布(Canary Release)、灰度發布等策略通過精細化的流量控制,可有效降低新版本上線風險, Istio 作為主流的服務網格(Service Mesh)工具。 此次Istio 在 Kubernetes 集群…

12.web api 3

定時器-間歇函數

ComfyUI進階:EchoMimic插件全解析,讓靜態肖像實現音頻驅動的精準口型動畫

在數字內容創作中,讓靜態肖像“開口說話”并做出自然表情,是提升交互感與沉浸感的關鍵。傳統動畫制作需專業人員逐幀調整口型與表情,成本高且效率低。ComfyUI的EchoMimic插件通過音頻驅動技術,實現了“輸入音頻→自動生成匹配口型…

鏈式前向星、vector存圖

場景設定 想象你是一個社交達人,要記錄你和所有朋友的關系(這就是“圖”)。每個朋友是一個節點,關系是一條邊。你需要快速回答:“我有哪些朋友?”(遍歷鄰居)。方式1:鏈式…

YAML 中定義 List 的幾種方式

在 YAML 配置文件中定義 List 并在 Spring 應用中注入是非常常見的操作,下面詳細介紹具體寫法和注入方式。一、YAML 中定義 List 的幾種方式1. 縮進式寫法(推薦)最常用的方式,通過短橫線 - 加空格表示列表項:yaml# app…

C# 反射和特性(自定義特性)

自定義特性 你或許已經注意到了,應用特性的語法和之前見過的其他語法有很大不同。你可能會覺得特 性是一種完全不同的結構類型,其實不是,特性只是一種特殊的類。 有關特性類的一些要點如下。 用戶自定義的特性類叫作自定義特性。所有特性類都…

科目二的四個電路

一.K21電動機單連續運轉接線(帶點動控制)1.電路圖2.主線路這可很明了,是一條直線,從上接到下就OK了,然后從熱繼電器出來,接到SB3按鈕的常閉觸點上接著往下走一端接到SB2的常閉觸點上,接著往下走,走到接觸器的線圈上,從L2借一條火線出來,從熔斷器的上端接入,另一端接…

【位運算】查詢子數組最大異或值|2693

本文涉及知識點 位運算、狀態壓縮、枚舉子集匯總 3277. 查詢子數組最大異或值 給你一個由 n 個整數組成的數組 nums,以及一個大小為 q 的二維整數數組 queries,其中 queries[i] [li, ri]。 對于每一個查詢,你需要找出 nums[li…ri] 中任…

HTML DOM 方法

HTML DOM 方法 引言 HTML DOM(文檔對象模型)是HTML文檔的編程接口,它允許開發者通過JavaScript來操作HTML文檔中的元素。DOM 方法是DOM編程的核心,它提供了豐富的操作手段來改變網頁的結構、樣式和行為。本文將詳細介紹HTML DOM中…

w嵌入式分享合集68

自己的原文哦~ https://blog.51cto.com/whaosoft/14133002 一、一鍵開關機電路的設計方案 方案一:電路圖 一鍵開關機電路分析如下: 電路工作流程如下: Key按下瞬間,Q2、Q1導通,7805輸入電壓在8.9V左右&…

FFmpeg QoS 處理

FFmpeg 中的 QoS (服務質量) 處理主要關注于實時流媒體傳輸中的時序控制、丟幀策略和網絡適應等方面。以下是 FFmpeg 中 QoS 相關的關鍵機制和配置方法。1. 基本 QoS 機制丟幀策略 (Frame Dropping)cAVDictionary *options NULL; av_dict_set(&options, "framedrop&q…

TexStudio中的Latex,PDFLatex,XeLatex和LuaLatex的區別

多種LaTeX編譯器一、多種LaTeX編譯器 1.1 PDFLaTeX(1994年) 默認、最常用的引擎。 輸入文件通常是 ASCII 或 UTF-8 編碼(但中文需要 CJK 宏包或 ctex 宏包支持)。 字體選擇受限:只能使用 TeX 自帶的字體或者 Type 1…

容器化部署:用Docker封裝機器翻譯模型與服務詳解

文章目錄一、機器翻譯容器化的技術棧選型1.1 為什么需要容器化MT模型?1.2 基礎鏡像選擇對比1.3 典型依賴分層方案1.4 性能對比(容器化 vs 原生部署)二、關鍵部署模式2.1 輕量級API服務封裝2.2 模型熱更新策略三、Docker鏡像構建3.1 編寫Docke…

leetcode_42 接雨水

1. 題意 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之后能接多少雨水。 2. 題解 這個題不會做,全部是看得題解捏。 不過能看懂題解感覺自己也很棒了! 看完題解后感覺最難的是如何求出有多少…

Spring Boot 整合 Thymeleaf 模板引擎:從零開始的完整指南

引言:為什么選擇 Thymeleaf? Thymeleaf 是一個現代化的服務器端 Java 模板引擎,專為 Web 開發而設計。與 JSP 不同,Thymeleaf 模板是純 HTML 文件,可以直接在瀏覽器中預覽,無需后端服務器支持。這種"…

pytest介紹(python測試框架)(@pytest.mark.parametrize、@pytest.fixtures)

文章目錄**1. 核心特點**- **簡潔易用**:無需復雜的配置,只需編寫簡單的函數或類即可進行測試。- **豐富的斷言**:直接使用 Python 內置的 assert 語句,失敗時提供詳細的錯誤信息。- **自動發現測試**:通過約定的命名規…

[Python 基礎課程]繼承

在 Python 的面向對象編程(OOP)中,繼承(Inheritance) 是一種重要的機制,它允許一個類(稱為子類或派生類)從另一個類(稱為父類、基類或超類)中繼承屬性和方法。…

QT之設計器組件功能(8大類55個組件)

組件名稱 功能描述關鍵屬性1. Layouts(布局組件)(1) Vertical Layout(垂直布局)將子控件按垂直方向依次排列layoutSpacing:控件之間的間距layoutMargin:布局邊緣的邊距layoutStretch:設置各控件…

java中list的api詳細使用

在Java中,List是集合框架中最常用的接口之一,繼承自Collection,代表有序、可重復的元素集合(允許null元素)。其核心實現類有ArrayList(數組實現,隨機訪問高效)、LinkedList&#xff…

Azure AI Search 探索總結

Azure AI Search 原名 Azure Cognitive Service,是Azure中用來給AI項目構建知識庫的組件。知識庫本質和數據庫很像,但是內部的存儲結構和檢索算法不一樣。比如并不是知識庫的每一列都可以用來過濾、檢索或group by,而是要根據實際情況配置。A…