mikao007 commited on
Commit
baff7c3
·
verified ·
1 Parent(s): 4752319

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +386 -0
  2. config_spaces.json +36 -0
  3. requirements.txt +17 -0
app.py ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Gradio部署專用腳本
3
+ 優化用於Gradio Spaces部署
4
+ """
5
+
6
+ import gradio as gr
7
+ import os
8
+ import sys
9
+ import logging
10
+ from typing import Dict, Optional
11
+ import tempfile
12
+ import shutil
13
+
14
+ # 設定日誌
15
+ logging.basicConfig(level=logging.INFO)
16
+ logger = logging.getLogger(__name__)
17
+
18
+ # 導入分析模組
19
+ try:
20
+ from modules.text_analyzer import TextAnalyzer
21
+ from modules.image_analyzer import ImageAnalyzer
22
+ from modules.video_analyzer import VideoAnalyzer
23
+ from modules.multimodal_fusion import MultimodalFusion
24
+ from utils.file_handler import FileHandler
25
+ from utils.config import Config
26
+ except ImportError as e:
27
+ logger.error(f"模組導入失敗: {e}")
28
+ # 創建簡化版本的分析器
29
+ class TextAnalyzer:
30
+ def analyze(self, text, analysis_type="comprehensive"):
31
+ return {"sentiment": "中性", "keywords": ["測試"], "summary": "測試分析"}
32
+
33
+ class ImageAnalyzer:
34
+ def analyze(self, image_path, analysis_type="comprehensive"):
35
+ return {"objects": ["測試物件"], "scene": "測試場景", "summary": "測試分析"}
36
+
37
+ class VideoAnalyzer:
38
+ def analyze(self, video_path, analysis_type="comprehensive"):
39
+ return {"actions": ["測試動作"], "audio_sentiment": "中性", "summary": "測試分析"}
40
+
41
+ class MultimodalFusion:
42
+ def fuse_analysis(self, text_analysis, image_analysis, video_analysis):
43
+ return {"fused_sentiment": "中性", "summary": "測試融合分析"}
44
+
45
+ class FileHandler:
46
+ pass
47
+
48
+ class Config:
49
+ def get(self, key, default=None):
50
+ return default
51
+
52
+ class GradioSocialMediaAnalyzer:
53
+ """Gradio專用社交媒體分析器"""
54
+
55
+ def __init__(self):
56
+ """初始化分析器"""
57
+ try:
58
+ self.config = Config()
59
+ self.text_analyzer = TextAnalyzer()
60
+ self.image_analyzer = ImageAnalyzer()
61
+ self.video_analyzer = VideoAnalyzer()
62
+ self.multimodal_fusion = MultimodalFusion()
63
+ self.file_handler = FileHandler()
64
+ logger.info("所有分析模組載入成功")
65
+ except Exception as e:
66
+ logger.error(f"分析器初始化失敗: {e}")
67
+ # 使用簡化版本
68
+ self.text_analyzer = TextAnalyzer()
69
+ self.image_analyzer = ImageAnalyzer()
70
+ self.video_analyzer = VideoAnalyzer()
71
+ self.multimodal_fusion = MultimodalFusion()
72
+
73
+ def analyze_content(self,
74
+ text_input: Optional[str] = None,
75
+ image_input: Optional[str] = None,
76
+ video_input: Optional[str] = None,
77
+ analysis_type: str = "comprehensive") -> Dict:
78
+ """分析多模態內容"""
79
+ try:
80
+ results = {
81
+ "text_analysis": None,
82
+ "image_analysis": None,
83
+ "video_analysis": None,
84
+ "multimodal_analysis": None,
85
+ "summary": ""
86
+ }
87
+
88
+ # 文字分析
89
+ if text_input and text_input.strip():
90
+ logger.info("開始文字分析...")
91
+ results["text_analysis"] = self.text_analyzer.analyze(text_input, analysis_type)
92
+
93
+ # 圖片分析
94
+ if image_input:
95
+ logger.info("開始圖片分析...")
96
+ results["image_analysis"] = self.image_analyzer.analyze(image_input, analysis_type)
97
+
98
+ # 影片分析
99
+ if video_input:
100
+ logger.info("開始影片分析...")
101
+ results["video_analysis"] = self.video_analyzer.analyze(video_input, analysis_type)
102
+
103
+ # 多模態融合分析
104
+ if any([text_input, image_input, video_input]):
105
+ logger.info("開始多模態融合分析...")
106
+ results["multimodal_analysis"] = self.multimodal_fusion.fuse_analysis(
107
+ results["text_analysis"],
108
+ results["image_analysis"],
109
+ results["video_analysis"]
110
+ )
111
+
112
+ # 生成總結
113
+ results["summary"] = self._generate_summary(results)
114
+
115
+ logger.info("分析完成")
116
+ return results
117
+
118
+ except Exception as e:
119
+ logger.error(f"分析過程中發生錯誤: {str(e)}")
120
+ return {"error": str(e)}
121
+
122
+ def _generate_summary(self, results: Dict) -> str:
123
+ """生成分析總結"""
124
+ summary_parts = []
125
+
126
+ if results["text_analysis"]:
127
+ summary_parts.append(f"文字分析: {results['text_analysis'].get('summary', 'N/A')}")
128
+
129
+ if results["image_analysis"]:
130
+ summary_parts.append(f"圖片分析: {results['image_analysis'].get('summary', 'N/A')}")
131
+
132
+ if results["video_analysis"]:
133
+ summary_parts.append(f"影片分析: {results['video_analysis'].get('summary', 'N/A')}")
134
+
135
+ if results["multimodal_analysis"]:
136
+ summary_parts.append(f"綜合分析: {results['multimodal_analysis'].get('summary', 'N/A')}")
137
+
138
+ return "\n".join(summary_parts)
139
+
140
+ # 創建全局分析器實例
141
+ analyzer = GradioSocialMediaAnalyzer()
142
+
143
+ def analyze_interface(text: str, image, video, analysis_type: str):
144
+ """Gradio介面函數"""
145
+ try:
146
+ # 處理檔案輸入
147
+ image_path = None
148
+ video_path = None
149
+
150
+ if image:
151
+ image_path = image.name if hasattr(image, 'name') else str(image)
152
+
153
+ if video:
154
+ video_path = video.name if hasattr(video, 'name') else str(video)
155
+
156
+ # 執行分析
157
+ results = analyzer.analyze_content(
158
+ text_input=text if text.strip() else None,
159
+ image_input=image_path,
160
+ video_input=video_path,
161
+ analysis_type=analysis_type
162
+ )
163
+
164
+ if "error" in results:
165
+ return f"分析錯誤: {results['error']}", "", "", ""
166
+
167
+ # 格式化輸出
168
+ text_output = format_text_analysis(results.get("text_analysis", {}))
169
+ image_output = format_image_analysis(results.get("image_analysis", {}))
170
+ video_output = format_video_analysis(results.get("video_analysis", {}))
171
+ summary_output = results.get("summary", "無分析結果")
172
+
173
+ return text_output, image_output, video_output, summary_output
174
+
175
+ except Exception as e:
176
+ error_msg = f"處理過程中發生錯誤: {str(e)}"
177
+ logger.error(error_msg)
178
+ return error_msg, "", "", ""
179
+
180
+ def format_text_analysis(analysis: Dict) -> str:
181
+ """格式化文字分析結果"""
182
+ if not analysis:
183
+ return "無文字分析結果"
184
+
185
+ formatted = []
186
+ if "sentiment" in analysis:
187
+ formatted.append(f"情感分析: {analysis['sentiment']}")
188
+ if "keywords" in analysis:
189
+ formatted.append(f"關鍵詞: {', '.join(analysis['keywords'])}")
190
+ if "topics" in analysis:
191
+ formatted.append(f"主題: {', '.join(analysis['topics'])}")
192
+ if "summary" in analysis:
193
+ formatted.append(f"總結: {analysis['summary']}")
194
+
195
+ return "\n".join(formatted)
196
+
197
+ def format_image_analysis(analysis: Dict) -> str:
198
+ """格式化圖片分析結果"""
199
+ if not analysis:
200
+ return "無圖片分析結果"
201
+
202
+ formatted = []
203
+ if "objects" in analysis:
204
+ formatted.append(f"偵測物件: {', '.join(analysis['objects'])}")
205
+ if "scene" in analysis:
206
+ formatted.append(f"場景描述: {analysis['scene']}")
207
+ if "sentiment" in analysis:
208
+ formatted.append(f"圖片情感: {analysis['sentiment']}")
209
+ if "summary" in analysis:
210
+ formatted.append(f"總結: {analysis['summary']}")
211
+
212
+ return "\n".join(formatted)
213
+
214
+ def format_video_analysis(analysis: Dict) -> str:
215
+ """格式化影片分析結果"""
216
+ if not analysis:
217
+ return "無影片分析結果"
218
+
219
+ formatted = []
220
+ if "objects" in analysis:
221
+ formatted.append(f"偵測物件: {', '.join(analysis['objects'])}")
222
+ if "actions" in analysis:
223
+ formatted.append(f"動作識別: {', '.join(analysis['actions'])}")
224
+ if "audio_sentiment" in analysis:
225
+ formatted.append(f"音頻情感: {analysis['audio_sentiment']}")
226
+ if "summary" in analysis:
227
+ formatted.append(f"總結: {analysis['summary']}")
228
+
229
+ return "\n".join(formatted)
230
+
231
+ def create_gradio_app():
232
+ """創建Gradio應用程式"""
233
+
234
+ # 創建Gradio介面
235
+ with gr.Blocks(
236
+ title="社交媒體多模態內容分析系統",
237
+ theme=gr.themes.Soft(),
238
+ css="""
239
+ .gradio-container {
240
+ max-width: 1200px !important;
241
+ margin: auto !important;
242
+ }
243
+ .main-header {
244
+ text-align: center;
245
+ margin-bottom: 2rem;
246
+ }
247
+ """
248
+ ) as app:
249
+
250
+ # 標題和說明
251
+ with gr.Row():
252
+ gr.HTML("""
253
+ <div class="main-header">
254
+ <h1>🔍 社交媒體多模態內容分析系統</h1>
255
+ <p>支援文字、圖片、影片的智能分析與多模態融合</p>
256
+ </div>
257
+ """)
258
+
259
+ # 主要內容區域
260
+ with gr.Row():
261
+ # 左側輸入區域
262
+ with gr.Column(scale=1):
263
+ gr.Markdown("### 📝 輸入內容")
264
+
265
+ text_input = gr.Textbox(
266
+ label="文字內容",
267
+ placeholder="請輸入要分析的文字內容...",
268
+ lines=5,
269
+ max_lines=10
270
+ )
271
+
272
+ image_input = gr.File(
273
+ label="圖片檔案",
274
+ file_types=["image"],
275
+ file_count="single"
276
+ )
277
+
278
+ video_input = gr.File(
279
+ label="影片檔案",
280
+ file_types=["video"],
281
+ file_count="single"
282
+ )
283
+
284
+ analysis_type = gr.Dropdown(
285
+ choices=[
286
+ ("綜合分析", "comprehensive"),
287
+ ("情感分析", "sentiment"),
288
+ ("內容分類", "content_classification"),
289
+ ("物件檢測", "object_detection")
290
+ ],
291
+ value="comprehensive",
292
+ label="分析類型"
293
+ )
294
+
295
+ analyze_btn = gr.Button(
296
+ "🚀 開始分析",
297
+ variant="primary",
298
+ size="lg"
299
+ )
300
+
301
+ # 右側結果區域
302
+ with gr.Column(scale=1):
303
+ gr.Markdown("### 📊 分析結果")
304
+
305
+ text_output = gr.Textbox(
306
+ label="📝 文字分析結果",
307
+ lines=8,
308
+ interactive=False,
309
+ show_copy_button=True
310
+ )
311
+
312
+ image_output = gr.Textbox(
313
+ label="🖼️ 圖片分析結果",
314
+ lines=8,
315
+ interactive=False,
316
+ show_copy_button=True
317
+ )
318
+
319
+ video_output = gr.Textbox(
320
+ label="🎬 影片分析結果",
321
+ lines=8,
322
+ interactive=False,
323
+ show_copy_button=True
324
+ )
325
+
326
+ summary_output = gr.Textbox(
327
+ label="🎯 綜合分析總結",
328
+ lines=6,
329
+ interactive=False,
330
+ show_copy_button=True
331
+ )
332
+
333
+ # 範例區域
334
+ with gr.Row():
335
+ gr.Markdown("""
336
+ ### 💡 使用範例
337
+
338
+ **文字分析範例:**
339
+ - 輸入:「這個新產品真的很棒,我強烈推薦給大家!」
340
+ - 分析:情感分析、關鍵詞提取、主題識別
341
+
342
+ **圖片分析範例:**
343
+ - 上傳:風景照片、人物照片、產品圖片
344
+ - 分析:物件檢測、場景識別、情感分析
345
+
346
+ **影片分析範例:**
347
+ - 上傳:短影片、廣告影片、教學影片
348
+ - 分析:動作識別、音頻分析、場景變化
349
+
350
+ **多模態分析:**
351
+ - 同時上傳多種內容類型
352
+ - 系統會進行綜合分析並提供融合結果
353
+ """)
354
+
355
+ # 綁定事件
356
+ analyze_btn.click(
357
+ fn=analyze_interface,
358
+ inputs=[text_input, image_input, video_input, analysis_type],
359
+ outputs=[text_output, image_output, video_output, summary_output]
360
+ )
361
+
362
+ # 清除按鈕
363
+ clear_btn = gr.Button("🗑️ 清除所有", variant="secondary")
364
+ clear_btn.click(
365
+ fn=lambda: ("", None, None, "comprehensive", "", "", "", ""),
366
+ outputs=[text_input, image_input, video_input, analysis_type,
367
+ text_output, image_output, video_output, summary_output]
368
+ )
369
+
370
+ return app
371
+
372
+ # Gradio Spaces 部署配置
373
+ if __name__ == "__main__":
374
+ # 創建應用程式
375
+ app = create_gradio_app()
376
+
377
+ # 啟動應用程式
378
+ app.launch(
379
+ server_name="0.0.0.0",
380
+ server_port=7860,
381
+ share=False, # 在Spaces上不需要share
382
+ debug=False, # 生產環境關閉debug
383
+ show_error=True,
384
+ quiet=False,
385
+ pinned=False # 設定pinned為布林值
386
+ )
config_spaces.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "models": {
3
+ "text_model": "distilbert-base-chinese",
4
+ "image_model": "mobilenet_v2",
5
+ "video_model": "slowfast",
6
+ "multimodal_model": "clip"
7
+ },
8
+ "analysis": {
9
+ "max_text_length": 256,
10
+ "max_image_size": 224,
11
+ "max_video_duration": 15,
12
+ "confidence_threshold": 0.5
13
+ },
14
+ "api": {
15
+ "openai_api_key": "",
16
+ "huggingface_token": "",
17
+ "google_api_key": ""
18
+ },
19
+ "storage": {
20
+ "temp_dir": "/tmp",
21
+ "output_dir": "/tmp/output",
22
+ "max_file_size": 10485760
23
+ },
24
+ "logging": {
25
+ "level": "INFO",
26
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
27
+ },
28
+ "gradio": {
29
+ "server_name": "0.0.0.0",
30
+ "server_port": 7860,
31
+ "share": false,
32
+ "debug": false,
33
+ "show_error": true,
34
+ "quiet": false
35
+ }
36
+ }
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio Spaces 部署專用依賴套件
2
+ gradio>=4.0.0
3
+ opencv-python-headless>=4.8.0
4
+ numpy>=1.24.0
5
+ jieba>=0.42.1
6
+ librosa>=0.10.0
7
+ scikit-learn>=1.3.0
8
+ Pillow>=10.0.0
9
+ matplotlib>=3.7.0
10
+ pandas>=2.0.0
11
+ requests>=2.31.0
12
+ tqdm>=4.65.0
13
+
14
+ # 可選的深度學習套件(如果需要更進階的分析)
15
+ # torch>=2.0.0
16
+ # transformers>=4.30.0
17
+ # torchvision>=0.15.0