HBDing commited on
Commit
0110507
·
1 Parent(s): 66c193d

更新边界框组件的错误处理逻辑,改进了数据加载和JavaScript通信,升级Gradio版本至5.31.0,添加详细的调试日志以增强用户体验。

Browse files
Files changed (3) hide show
  1. SOLUTION_SUMMARY.md +11 -3
  2. app.py +152 -147
  3. requirements.txt +1 -1
SOLUTION_SUMMARY.md CHANGED
@@ -3,6 +3,7 @@
3
  ## 🔍 问题诊断
4
 
5
  你的边界框绘制功能目前存在以下问题:
 
6
  1. **绘制无响应** - 鼠标拖拽没有绘制边界框
7
  2. **数据同步失败** - 边界框数据没有传递给Gradio
8
 
@@ -11,16 +12,19 @@
11
  我已经为你进行了以下修复:
12
 
13
  ### 1. 代码改进
 
14
  - ✅ 更新了 `bbox_component.html` 和 `bbox_component_fixed.html`
15
  - ✅ 改进了 `app.py` 中的数据处理和JavaScript通信
16
  - ✅ 添加了详细的调试日志和错误处理
17
 
18
  ### 2. 通信机制优化
 
19
  - ✅ 简化了JavaScript通信逻辑
20
  - ✅ 改进了元素选择器和事件触发
21
  - ✅ 增加了多种数据同步方式
22
 
23
  ### 3. 调试工具
 
24
  - ✅ 创建了 `test_simple.py` 用于独立测试
25
  - ✅ 提供了详细的调试指南 `BBOX_DEBUG_GUIDE.md`
26
 
@@ -37,6 +41,7 @@ python test_simple.py
37
  ```
38
 
39
  然后:
 
40
  1. 打开浏览器访问 `http://localhost:7861`
41
  2. 打开开发者工具 (F12)
42
  3. 在画布上拖拽鼠标测试绘制
@@ -82,9 +87,10 @@ document.dispatchEvent(new CustomEvent('bbox_data_update', {
82
 
83
  ## 📋 预期结果
84
 
85
- ### 正常工作时应该看到:
86
 
87
  1. **控制台日志**:
 
88
  ```
89
  边界框组件已加载
90
  画布已初始化
@@ -92,6 +98,7 @@ document.dispatchEvent(new CustomEvent('bbox_data_update', {
92
  ```
93
 
94
  2. **绘制时**:
 
95
  ```
96
  开始绘制: (x, y)
97
  添加边界框: 1个
@@ -108,7 +115,7 @@ document.dispatchEvent(new CustomEvent('bbox_data_update', {
108
 
109
  1. **运行的命令**: 是运行 `test_simple.py` 还是 `app.py`?
110
  2. **浏览器控制台日志**: 复制完整的Console输出
111
- 3. **具体现象**:
112
  - 能看到画布吗?
113
  - 鼠标在画布上有任何反应吗?
114
  - 右侧有数据显示吗?
@@ -116,6 +123,7 @@ document.dispatchEvent(new CustomEvent('bbox_data_update', {
116
  ## 🎉 成功标志
117
 
118
  当边界框功能正常工作时,你应该能够:
 
119
  - ✅ 在画布上拖拽绘制彩色边界框
120
  - ✅ 看到实时的绘制预览(虚线框)
121
  - ✅ 为每个边界框添加文字描述
@@ -124,4 +132,4 @@ document.dispatchEvent(new CustomEvent('bbox_data_update', {
124
 
125
  ---
126
 
127
- 🚀 **开始测试**: 运行 `python test_simple.py` 并访问 `http://localhost:7861` 开始调试!
 
3
  ## 🔍 问题诊断
4
 
5
  你的边界框绘制功能目前存在以下问题:
6
+
7
  1. **绘制无响应** - 鼠标拖拽没有绘制边界框
8
  2. **数据同步失败** - 边界框数据没有传递给Gradio
9
 
 
12
  我已经为你进行了以下修复:
13
 
14
  ### 1. 代码改进
15
+
16
  - ✅ 更新了 `bbox_component.html` 和 `bbox_component_fixed.html`
17
  - ✅ 改进了 `app.py` 中的数据处理和JavaScript通信
18
  - ✅ 添加了详细的调试日志和错误处理
19
 
20
  ### 2. 通信机制优化
21
+
22
  - ✅ 简化了JavaScript通信逻辑
23
  - ✅ 改进了元素选择器和事件触发
24
  - ✅ 增加了多种数据同步方式
25
 
26
  ### 3. 调试工具
27
+
28
  - ✅ 创建了 `test_simple.py` 用于独立测试
29
  - ✅ 提供了详细的调试指南 `BBOX_DEBUG_GUIDE.md`
30
 
 
41
  ```
42
 
43
  然后:
44
+
45
  1. 打开浏览器访问 `http://localhost:7861`
46
  2. 打开开发者工具 (F12)
47
  3. 在画布上拖拽鼠标测试绘制
 
87
 
88
  ## 📋 预期结果
89
 
90
+ ### 正常工作时应该看到
91
 
92
  1. **控制台日志**:
93
+
94
  ```
95
  边界框组件已加载
96
  画布已初始化
 
98
  ```
99
 
100
  2. **绘制时**:
101
+
102
  ```
103
  开始绘制: (x, y)
104
  添加边界框: 1个
 
115
 
116
  1. **运行的命令**: 是运行 `test_simple.py` 还是 `app.py`?
117
  2. **浏览器控制台日志**: 复制完整的Console输出
118
+ 3. **具体现象**:
119
  - 能看到画布吗?
120
  - 鼠标在画布上有任何反应吗?
121
  - 右侧有数据显示吗?
 
123
  ## 🎉 成功标志
124
 
125
  当边界框功能正常工作时,你应该能够:
126
+
127
  - ✅ 在画布上拖拽绘制彩色边界框
128
  - ✅ 看到实时的绘制预览(虚线框)
129
  - ✅ 为每个边界框添加文字描述
 
132
 
133
  ---
134
 
135
+ 🚀 **开始测试**: 运行 `python test_simple.py` 并访问 `http://localhost:7861` 开始调试!
app.py CHANGED
@@ -11,7 +11,7 @@ import warnings
11
  try:
12
  from dream_renderer import DreamRendererPipeline
13
  except ImportError:
14
- print("Error: dream_renderer 模块未找到。请确保模型文件存在。")
15
  # raise
16
 
17
  warnings.filterwarnings("ignore")
@@ -41,12 +41,17 @@ def initialize_pipeline():
41
  def load_bbox_component():
42
  """加载边界框绘制组件"""
43
  try:
44
- with open('bbox_component_fixed.html', 'r', encoding='utf-8') as f:
45
- return f.read()
46
- except FileNotFoundError:
47
- # 如果修复版本不存在,使用原版本
48
  with open('bbox_component.html', 'r', encoding='utf-8') as f:
49
- return f.read()
 
 
 
 
 
 
 
 
 
50
 
51
  def update_bbox_data(bbox_json: str):
52
  """更新边界框数据显示"""
@@ -235,12 +240,6 @@ def create_interface():
235
  font-weight: bold;
236
  padding: 12px 25px;
237
  }
238
- .parameter-group {
239
- background: #f8f9fa;
240
- border-radius: 10px;
241
- padding: 15px;
242
- margin: 10px 0;
243
- }
244
  """
245
 
246
  with gr.Blocks(css=css, title="DreamRenderer - Multi-Instance Control", theme=gr.themes.Soft()) as demo:
@@ -279,7 +278,7 @@ def create_interface():
279
  # 初始化部分
280
  with gr.Group():
281
  gr.Markdown("### 🚀 模型初始化")
282
- init_btn = gr.Button("🚀 初始化DreamRenderer", variant="primary", elem_classes=["init-btn"])
283
  init_status = gr.Textbox(label="初始化状态", interactive=False, lines=2)
284
 
285
  # 边界框绘制区域
@@ -291,7 +290,7 @@ def create_interface():
291
  <p style="margin: 5px 0 0 0; color: #1976d2;"><strong>步骤2:</strong> 在右侧为每个框输入详细描述</p>
292
  </div>
293
  """)
294
- bbox_component = gr.HTML(load_bbox_component(), elem_classes=["bbox-container"])
295
 
296
  # 隐藏的输入框用于接收边界框数据
297
  bbox_data_input = gr.Textbox(visible=False, elem_id="bbox_data")
@@ -357,7 +356,6 @@ def create_interface():
357
  generate_btn = gr.Button(
358
  "🎨 生成图像",
359
  variant="primary",
360
- elem_classes=["generate-btn"],
361
  size="lg"
362
  )
363
 
@@ -407,150 +405,157 @@ def create_interface():
407
  function() {
408
  console.log('DreamRenderer界面已加载');
409
 
410
- // 全局变量
411
- let isDrawing = false;
412
- let startX, startY, currentRect;
413
- let bboxes = [];
 
 
 
414
 
415
- const canvas = document.getElementById('bboxCanvas');
416
- if (!canvas) {
417
- console.error('画布元素未找到');
418
- return;
419
- }
420
-
421
- const ctx = canvas.getContext('2d');
422
 
423
- // 清除之前的监听器并添加新的
424
- canvas.replaceWith(canvas.cloneNode(true));
425
- const newCanvas = document.getElementById('bboxCanvas');
426
- const newCtx = newCanvas.getContext('2d');
427
 
428
- // 重新设置样式
429
- newCanvas.style.display = 'block';
430
- newCanvas.style.border = '2px solid #4ECDC4';
431
- newCanvas.style.backgroundColor = 'white';
432
- newCanvas.style.cursor = 'crosshair';
433
- newCanvas.style.borderRadius = '8px';
434
 
435
- // 边界框编辑函数
436
- window.updateBboxField = function(index, field, value) {
437
- if (index >= 0 && index < bboxes.length) {
438
- bboxes[index][field] = value;
439
- console.log(`更新边界框 ${index} 的 ${field}:`, value);
440
- updateBboxData();
441
- }
442
- };
443
 
444
- window.deleteBbox = function(index) {
445
- if (index >= 0 && index < bboxes.length) {
446
- bboxes.splice(index, 1);
447
- console.log(`删除边界框 ${index}`);
448
- redrawCanvas();
449
- updateBboxData();
450
- }
451
- };
452
 
453
- window.clearAllBboxes = function() {
454
- bboxes = [];
455
- console.log('清空所有边界框');
456
- redrawCanvas();
457
- updateBboxData();
458
- };
459
 
460
- // 重绘画布
461
- function redrawCanvas() {
462
- newCtx.clearRect(0, 0, newCanvas.width, newCanvas.height);
463
- bboxes.forEach((bbox, index) => {
464
- newCtx.strokeStyle = `hsl(${index * 60}, 70%, 50%)`;
465
- newCtx.lineWidth = 2;
466
- newCtx.strokeRect(bbox.x, bbox.y, bbox.width, bbox.height);
467
-
468
- // 绘制标签
469
- newCtx.fillStyle = `hsl(${index * 60}, 70%, 50%)`;
470
- newCtx.font = '12px Arial';
471
- newCtx.fillText(bbox.label || `区域${index + 1}`, bbox.x + 5, bbox.y - 5);
472
- });
473
- }
474
 
475
- // 更新边界框数据
476
- function updateBboxData() {
477
- const relativeBboxes = bboxes.map(b => ({
478
- x: b.x / newCanvas.width,
479
- y: b.y / newCanvas.height,
480
- width: b.width / newCanvas.width,
481
- height: b.height / newCanvas.height,
482
- label: b.label || '',
483
- prompt: b.prompt || ''
484
- }));
485
-
486
- const dataString = JSON.stringify(relativeBboxes);
487
- console.log('📤 更新数据:', relativeBboxes.length, '个边界框');
488
-
489
- const textarea = document.querySelector('#bbox_data textarea');
490
- if (textarea) {
491
- textarea.value = dataString;
492
- textarea.dispatchEvent(new Event('input', { bubbles: true }));
493
- }
494
- }
495
 
496
- // 添加绘制事件监听器
497
- newCanvas.addEventListener('mousedown', function(e) {
498
- isDrawing = true;
499
- startX = e.offsetX;
500
- startY = e.offsetY;
501
- console.log('🎯 开始绘制:', startX, startY);
502
- });
503
 
504
- newCanvas.addEventListener('mousemove', function(e) {
505
- if (!isDrawing) return;
506
-
507
- const currentX = e.offsetX;
508
- const currentY = e.offsetY;
509
-
510
- // 清除画布并重绘所有边界框
511
- redrawCanvas();
512
-
513
- // 绘制当前正在绘制的框
514
- newCtx.strokeStyle = '#007bff';
515
- newCtx.lineWidth = 2;
516
- newCtx.setLineDash([5, 5]);
517
- const width = currentX - startX;
518
- const height = currentY - startY;
519
- newCtx.strokeRect(startX, startY, width, height);
520
- newCtx.setLineDash([]);
521
- });
522
 
523
- newCanvas.addEventListener('mouseup', function(e) {
524
- if (!isDrawing) return;
525
- isDrawing = false;
526
-
527
- const endX = e.offsetX;
528
- const endY = e.offsetY;
529
- const width = endX - startX;
530
- const height = endY - startY;
531
-
532
- // 只有当框足够大时才添加
533
- if (Math.abs(width) > 10 && Math.abs(height) > 10) {
534
- const bbox = {
535
- x: Math.min(startX, endX),
536
- y: Math.min(startY, endY),
537
- width: Math.abs(width),
538
- height: Math.abs(height),
539
- label: `区域${bboxes.length + 1}`,
540
- prompt: ''
541
- };
542
-
543
- bboxes.push(bbox);
544
- console.log('✅ 添加边界框:', bbox);
545
-
546
- redrawCanvas();
547
- updateBboxData();
548
- }
549
-
550
- console.log('🎯 绘制结束,当前边界框数量:', bboxes.length);
551
- });
552
 
553
- console.log('🚀 DreamRenderer边界框功能已就绪!');
 
 
 
 
554
  }
555
  """)
556
 
 
11
  try:
12
  from dream_renderer import DreamRendererPipeline
13
  except ImportError:
14
+ print("Warning: dream_renderer 模块未找到。将使用演示模式。")
15
  # raise
16
 
17
  warnings.filterwarnings("ignore")
 
41
  def load_bbox_component():
42
  """加载边界框绘制组件"""
43
  try:
 
 
 
 
44
  with open('bbox_component.html', 'r', encoding='utf-8') as f:
45
+ content = f.read()
46
+ return content
47
+ except FileNotFoundError:
48
+ # 返回简化的HTML内容
49
+ return """
50
+ <div style="text-align: center; padding: 20px; border: 2px dashed #ccc; border-radius: 8px;">
51
+ <p>边界框组件加载失败</p>
52
+ <p>请检查 bbox_component.html 文件是否存在</p>
53
+ </div>
54
+ """
55
 
56
  def update_bbox_data(bbox_json: str):
57
  """更新边界框数据显示"""
 
240
  font-weight: bold;
241
  padding: 12px 25px;
242
  }
 
 
 
 
 
 
243
  """
244
 
245
  with gr.Blocks(css=css, title="DreamRenderer - Multi-Instance Control", theme=gr.themes.Soft()) as demo:
 
278
  # 初始化部分
279
  with gr.Group():
280
  gr.Markdown("### 🚀 模型初始化")
281
+ init_btn = gr.Button("🚀 初始化DreamRenderer", variant="primary")
282
  init_status = gr.Textbox(label="初始化状态", interactive=False, lines=2)
283
 
284
  # 边界框绘制区域
 
290
  <p style="margin: 5px 0 0 0; color: #1976d2;"><strong>步骤2:</strong> 在右侧为每个框输入详细描述</p>
291
  </div>
292
  """)
293
+ bbox_component = gr.HTML(load_bbox_component())
294
 
295
  # 隐藏的输入框用于接收边界框数据
296
  bbox_data_input = gr.Textbox(visible=False, elem_id="bbox_data")
 
356
  generate_btn = gr.Button(
357
  "🎨 生成图像",
358
  variant="primary",
 
359
  size="lg"
360
  )
361
 
 
405
  function() {
406
  console.log('DreamRenderer界面已加载');
407
 
408
+ // 给DOM一些时间加载
409
+ setTimeout(function() {
410
+ try {
411
+ // 全局变量
412
+ let isDrawing = false;
413
+ let startX, startY, currentRect;
414
+ let bboxes = [];
415
 
416
+ const canvas = document.getElementById('bboxCanvas');
417
+ if (!canvas) {
418
+ console.error('画布元素未找到');
419
+ return;
420
+ }
421
+
422
+ const ctx = canvas.getContext('2d');
423
 
424
+ // 清除之前的监听器并添加新的
425
+ canvas.replaceWith(canvas.cloneNode(true));
426
+ const newCanvas = document.getElementById('bboxCanvas');
427
+ const newCtx = newCanvas.getContext('2d');
428
 
429
+ // 重新设置样式
430
+ newCanvas.style.display = 'block';
431
+ newCanvas.style.border = '2px solid #4ECDC4';
432
+ newCanvas.style.backgroundColor = 'white';
433
+ newCanvas.style.cursor = 'crosshair';
434
+ newCanvas.style.borderRadius = '8px';
435
 
436
+ // 边界框编辑函数
437
+ window.updateBboxField = function(index, field, value) {
438
+ if (index >= 0 && index < bboxes.length) {
439
+ bboxes[index][field] = value;
440
+ console.log(`更新边界框 ${index} 的 ${field}:`, value);
441
+ updateBboxData();
442
+ }
443
+ };
444
 
445
+ window.deleteBbox = function(index) {
446
+ if (index >= 0 && index < bboxes.length) {
447
+ bboxes.splice(index, 1);
448
+ console.log(`删除边界框 ${index}`);
449
+ redrawCanvas();
450
+ updateBboxData();
451
+ }
452
+ };
453
 
454
+ window.clearAllBboxes = function() {
455
+ bboxes = [];
456
+ console.log('清空所有边界框');
457
+ redrawCanvas();
458
+ updateBboxData();
459
+ };
460
 
461
+ // 重绘画布
462
+ function redrawCanvas() {
463
+ newCtx.clearRect(0, 0, newCanvas.width, newCanvas.height);
464
+ bboxes.forEach((bbox, index) => {
465
+ newCtx.strokeStyle = `hsl(${index * 60}, 70%, 50%)`;
466
+ newCtx.lineWidth = 2;
467
+ newCtx.strokeRect(bbox.x, bbox.y, bbox.width, bbox.height);
468
+
469
+ // 绘制标签
470
+ newCtx.fillStyle = `hsl(${index * 60}, 70%, 50%)`;
471
+ newCtx.font = '12px Arial';
472
+ newCtx.fillText(bbox.label || `区域${index + 1}`, bbox.x + 5, bbox.y - 5);
473
+ });
474
+ }
475
 
476
+ // 更新边界框数据
477
+ function updateBboxData() {
478
+ const relativeBboxes = bboxes.map(b => ({
479
+ x: b.x / newCanvas.width,
480
+ y: b.y / newCanvas.height,
481
+ width: b.width / newCanvas.width,
482
+ height: b.height / newCanvas.height,
483
+ label: b.label || '',
484
+ prompt: b.prompt || ''
485
+ }));
486
+
487
+ const dataString = JSON.stringify(relativeBboxes);
488
+ console.log('📤 更新数据:', relativeBboxes.length, '个边界框');
489
+
490
+ const textarea = document.querySelector('#bbox_data textarea');
491
+ if (textarea) {
492
+ textarea.value = dataString;
493
+ textarea.dispatchEvent(new Event('input', { bubbles: true }));
494
+ }
495
+ }
496
 
497
+ // 添加绘制事件监听器
498
+ newCanvas.addEventListener('mousedown', function(e) {
499
+ isDrawing = true;
500
+ startX = e.offsetX;
501
+ startY = e.offsetY;
502
+ console.log('🎯 开始绘制:', startX, startY);
503
+ });
504
 
505
+ newCanvas.addEventListener('mousemove', function(e) {
506
+ if (!isDrawing) return;
507
+
508
+ const currentX = e.offsetX;
509
+ const currentY = e.offsetY;
510
+
511
+ // 清除画布并重绘所有边界框
512
+ redrawCanvas();
513
+
514
+ // 绘制当前正在绘制的框
515
+ newCtx.strokeStyle = '#007bff';
516
+ newCtx.lineWidth = 2;
517
+ newCtx.setLineDash([5, 5]);
518
+ const width = currentX - startX;
519
+ const height = currentY - startY;
520
+ newCtx.strokeRect(startX, startY, width, height);
521
+ newCtx.setLineDash([]);
522
+ });
523
 
524
+ newCanvas.addEventListener('mouseup', function(e) {
525
+ if (!isDrawing) return;
526
+ isDrawing = false;
527
+
528
+ const endX = e.offsetX;
529
+ const endY = e.offsetY;
530
+ const width = endX - startX;
531
+ const height = endY - startY;
532
+
533
+ // 只有当框足够大时才添加
534
+ if (Math.abs(width) > 10 && Math.abs(height) > 10) {
535
+ const bbox = {
536
+ x: Math.min(startX, endX),
537
+ y: Math.min(startY, endY),
538
+ width: Math.abs(width),
539
+ height: Math.abs(height),
540
+ label: `区域${bboxes.length + 1}`,
541
+ prompt: ''
542
+ };
543
+
544
+ bboxes.push(bbox);
545
+ console.log('✅ 添加边界框:', bbox);
546
+
547
+ redrawCanvas();
548
+ updateBboxData();
549
+ }
550
+
551
+ console.log('🎯 绘制结束,当前边界框数量:', bboxes.length);
552
+ });
553
 
554
+ console.log('🚀 DreamRenderer边界框功能已就绪!');
555
+ } catch (error) {
556
+ console.error('初始化边界框功能时出错:', error);
557
+ }
558
+ }, 1000); // 延迟1秒执行
559
  }
560
  """)
561
 
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- gradio==4.44.0
2
  spaces>=0.28.0
3
  torch>=2.0.0
4
  torchvision
 
1
+ gradio==5.31.0
2
  spaces>=0.28.0
3
  torch>=2.0.0
4
  torchvision