Update app.py
Browse files
app.py
CHANGED
|
@@ -102,7 +102,7 @@ bbox_max_x = min(frame_width, max(x_coords) + 20)
|
|
| 102 |
bbox_min_y = max(0, min(y_coords) - 20)
|
| 103 |
bbox_max_y = min(frame_height, max(y_coords) + 20)
|
| 104 |
|
| 105 |
-
# Helper functions
|
| 106 |
def euclidean_distance(p1, p2):
|
| 107 |
return np.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
|
| 108 |
|
|
@@ -551,73 +551,46 @@ def process_frame(frame, state):
|
|
| 551 |
|
| 552 |
return frame, instruction, state
|
| 553 |
|
| 554 |
-
def
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
frames = []
|
| 561 |
-
instructions = []
|
| 562 |
-
temp_file = "output_video.mp4"
|
| 563 |
-
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
| 564 |
-
out = cv2.VideoWriter(temp_file, fourcc, 20.0, (frame_width, frame_height))
|
| 565 |
-
|
| 566 |
-
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
| 567 |
-
progress(0, desc="Processing video frames")
|
| 568 |
-
|
| 569 |
-
for i in progress.tqdm(range(frame_count), desc="Processing frames"):
|
| 570 |
-
ret, frame = cap.read()
|
| 571 |
-
if not ret:
|
| 572 |
-
break
|
| 573 |
-
frame, instruction, state = process_frame(frame, state)
|
| 574 |
-
frames.append(frame)
|
| 575 |
-
instructions.append(instruction)
|
| 576 |
-
out.write(frame)
|
| 577 |
-
|
| 578 |
-
cap.release()
|
| 579 |
-
out.release()
|
| 580 |
-
pose.close()
|
| 581 |
-
|
| 582 |
-
return temp_file, instructions[-1] if instructions else "Processing complete.", state
|
| 583 |
-
|
| 584 |
-
def process_image(image):
|
| 585 |
-
state = None
|
| 586 |
-
frame = image
|
| 587 |
frame, instruction, state = process_frame(frame, state)
|
| 588 |
-
return frame, instruction
|
| 589 |
|
| 590 |
# Gradio interface
|
| 591 |
with gr.Blocks() as demo:
|
| 592 |
gr.Markdown("# AI-Based BPPV Maneuver Guider")
|
| 593 |
-
gr.Markdown("
|
| 594 |
|
| 595 |
with gr.Row():
|
| 596 |
with gr.Column():
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
process_button = gr.Button("Process")
|
| 600 |
with gr.Column():
|
| 601 |
-
|
| 602 |
-
output_image = gr.Image(label="Processed Image")
|
| 603 |
instruction_output = gr.Textbox(label="Instructions")
|
| 604 |
|
| 605 |
state = gr.State()
|
| 606 |
|
| 607 |
-
|
| 608 |
-
|
| 609 |
-
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
|
| 620 |
-
|
|
|
|
|
|
|
| 621 |
)
|
| 622 |
|
| 623 |
if __name__ == "__main__":
|
|
|
|
| 102 |
bbox_min_y = max(0, min(y_coords) - 20)
|
| 103 |
bbox_max_y = min(frame_height, max(y_coords) + 20)
|
| 104 |
|
| 105 |
+
# Helper functions
|
| 106 |
def euclidean_distance(p1, p2):
|
| 107 |
return np.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
|
| 108 |
|
|
|
|
| 551 |
|
| 552 |
return frame, instruction, state
|
| 553 |
|
| 554 |
+
def webcam_stream(frame, state):
|
| 555 |
+
"""
|
| 556 |
+
Process webcam frames in real-time for Gradio streaming.
|
| 557 |
+
"""
|
| 558 |
+
if frame is None:
|
| 559 |
+
return None, "No frame received.", state
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 560 |
frame, instruction, state = process_frame(frame, state)
|
| 561 |
+
return frame, instruction, state
|
| 562 |
|
| 563 |
# Gradio interface
|
| 564 |
with gr.Blocks() as demo:
|
| 565 |
gr.Markdown("# AI-Based BPPV Maneuver Guider")
|
| 566 |
+
gr.Markdown("Use your webcam to guide you through the Epley Maneuver for BPPV treatment. Follow the on-screen instructions. Note: Webcam streaming works best when running locally.")
|
| 567 |
|
| 568 |
with gr.Row():
|
| 569 |
with gr.Column():
|
| 570 |
+
webcam_input = gr.Video(label="Webcam Feed", source="webcam", live=True)
|
| 571 |
+
reset_button = gr.Button("Reset State")
|
|
|
|
| 572 |
with gr.Column():
|
| 573 |
+
output_image = gr.Image(label="Processed Frame", streaming=True)
|
|
|
|
| 574 |
instruction_output = gr.Textbox(label="Instructions")
|
| 575 |
|
| 576 |
state = gr.State()
|
| 577 |
|
| 578 |
+
# Stream webcam frames
|
| 579 |
+
webcam_input.stream(
|
| 580 |
+
fn=webcam_stream,
|
| 581 |
+
inputs=[webcam_input, state],
|
| 582 |
+
outputs=[output_image, instruction_output, state],
|
| 583 |
+
_js="""(inputs) => {
|
| 584 |
+
// Ensure webcam is accessed
|
| 585 |
+
return inputs;
|
| 586 |
+
}"""
|
| 587 |
+
)
|
| 588 |
+
|
| 589 |
+
# Reset state button
|
| 590 |
+
reset_button.click(
|
| 591 |
+
fn=lambda: None,
|
| 592 |
+
inputs=None,
|
| 593 |
+
outputs=state
|
| 594 |
)
|
| 595 |
|
| 596 |
if __name__ == "__main__":
|