Update app.py
Browse files
app.py
CHANGED
@@ -1,36 +1,125 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
from segmentation import segment_image
|
3 |
-
import numpy as np
|
4 |
-
import cv2
|
5 |
|
6 |
-
# Image de test par défaut
|
7 |
-
default_image_path = "./image.png"
|
8 |
|
9 |
-
def segment_and_display(image_path=default_image_path):
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
# Charger l'image de test par défaut
|
17 |
-
default_original_image, default_segmented_image = segment_image(default_image_path)
|
18 |
-
|
19 |
-
# Interface Gradio
|
20 |
-
iface = gr.Interface(
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
)
|
34 |
-
|
35 |
-
# Afficher l'image de test par défaut lorsque l'interface est ouverte
|
36 |
-
iface.launch(share=True, inline=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# import gradio as gr
|
2 |
+
# from segmentation import segment_image
|
3 |
+
# import numpy as np
|
4 |
+
# import cv2
|
5 |
|
6 |
+
# # Image de test par défaut
|
7 |
+
# default_image_path = "./image.png"
|
8 |
|
9 |
+
# def segment_and_display(image_path=default_image_path):
|
10 |
+
# # Appeler la fonction de segmentation
|
11 |
+
# original_image, segmented_image = segment_image(image_path)
|
12 |
|
13 |
+
# # Retourner les images pour l'affichage
|
14 |
+
# return original_image, segmented_image
|
15 |
+
|
16 |
+
# # Charger l'image de test par défaut
|
17 |
+
# default_original_image, default_segmented_image = segment_image(default_image_path)
|
18 |
+
|
19 |
+
# # Interface Gradio
|
20 |
+
# iface = gr.Interface(
|
21 |
+
# fn=segment_and_display,
|
22 |
+
# inputs=gr.Image(type="filepath", label="Upload Image"),
|
23 |
+
# outputs=[
|
24 |
+
# gr.Image(type="numpy", label="Original Image"),
|
25 |
+
# gr.Image(type="numpy", label="Segmented Image")
|
26 |
+
# ],
|
27 |
+
# title="Image Segmentation with K-means (k=2)",
|
28 |
+
# description="Upload an image or use the default test image to see the segmentation result.",
|
29 |
+
# examples=[
|
30 |
+
# [default_image_path]
|
31 |
+
# ],
|
32 |
+
# live=True # Permet de voir les changements en temps réel
|
33 |
+
# )
|
34 |
+
|
35 |
+
# # Afficher l'image de test par défaut lorsque l'interface est ouverte
|
36 |
+
# iface.launch(share=True, inline=True)
|
37 |
+
import gradio as gr # 导入 Gradio 库,用于创建基于 Web 的用户界面
|
38 |
+
from segmentation import segment_image # 从 'segmentation.py' 文件中导入自定义的图像分割函数 segment_image
|
39 |
+
import numpy as np # 导入 NumPy 库,用于数值操作,特别是图像数据处理
|
40 |
+
import cv2 # 导入 OpenCV 库,用于图像处理任务(尽管在 Gradio 部分未直接使用,但在 segment_image 中很可能被使用)
|
41 |
+
import requests # 导入 requests 库,用于向外部 API 发送 HTTP 请求
|
42 |
+
import base64 # 导入 base64 库,用于图像数据的编码和解码
|
43 |
+
|
44 |
+
# 定义图像分割函数
|
45 |
+
def segment_and_display(image_path):
|
46 |
+
# 调用 segment_image 函数(来自 segmentation.py)获取原始图像和分割后的图像
|
47 |
+
original_image, segmented_image = segment_image(image_path)
|
48 |
+
# 返回原始图像、分割后的图像以及图像路径,供后续分析使用
|
49 |
+
return original_image, segmented_image, image_path
|
50 |
+
|
51 |
+
# 定义使用 MedGemma API 进行专业分析的函数
|
52 |
+
def analyze_image_with_question(image_path, question):
|
53 |
+
# 以二进制读取模式打开图像文件
|
54 |
+
with open(image_path, "rb") as img_file:
|
55 |
+
# 读取图像内容为字节
|
56 |
+
image_bytes = img_file.read()
|
57 |
+
# 将图像字节编码为 base64 字符串,并解码为 UTF-8 格式,以便通过 API 传输
|
58 |
+
image_base64 = base64.b64encode(image_bytes).decode("utf-8")
|
59 |
+
|
60 |
+
# 构造用于 API 请求的 JSON 数据体
|
61 |
+
payload = {
|
62 |
+
"inputs": {
|
63 |
+
"image": image_base64, # 包含 base64 编码的图像数据
|
64 |
+
"text": question # 包含用户的提问
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
# 定义 API 请求的 HTTP 头,包括授权令牌
|
69 |
+
headers = {
|
70 |
+
"Authorization": "Bearer YOUR_HF_API_TOKEN" # 占位符:请替换为你的实际 HuggingFace API 访问令牌
|
71 |
+
}
|
72 |
+
|
73 |
+
# 向 MedGemma API 终端发送 POST 请求
|
74 |
+
response = requests.post("https://api-inference.huggingface.co/models/google/medgemma-4b-it",
|
75 |
+
headers=headers, json=payload)
|
76 |
+
|
77 |
+
# 检查 API 请求是否成功(状态码为 200)
|
78 |
+
if response.status_code == 200:
|
79 |
+
# 解析 API 返回的 JSON 响应
|
80 |
+
result = response.json()
|
81 |
+
# 提取并返回 API 响应中生成的文本
|
82 |
+
return result[0]["generated_text"]
|
83 |
+
else:
|
84 |
+
# 如果 API 请求失败,返回错误消息,包括状态码和响应文本
|
85 |
+
return f"Error: {response.status_code} - {response.text}"
|
86 |
+
|
87 |
+
# 使用 Gradio Blocks 组件创建界面,以实现自定义布局
|
88 |
+
with gr.Blocks() as iface:
|
89 |
+
# 在界面中添加一个 Markdown 标题
|
90 |
+
gr.Markdown("# 🧠 医学图像分割 + 专家分析")
|
91 |
+
# 创建一个行,用于水平排列组件
|
92 |
+
with gr.Row():
|
93 |
+
# 为图像输入创建一个列
|
94 |
+
with gr.Column():
|
95 |
+
# 图像输入组件,允许文件上传,type="filepath" 表示函数将接收临时文件的路径
|
96 |
+
image_input = gr.Image(type="filepath", label="上传皮肤图像")
|
97 |
+
# 为显示输出图像创建另一个列
|
98 |
+
with gr.Column():
|
99 |
+
# 用于显示原始图像的输出组件(NumPy 数组)
|
100 |
+
original_output = gr.Image(type="numpy", label="原始图像")
|
101 |
+
# 用于显示分割后图像的输出组件(NumPy 数组)
|
102 |
+
segmented_output = gr.Image(type="numpy", label="分割后图像")
|
103 |
+
|
104 |
+
# 一个 Gradio State 组件,用于在函数调用之间存储图像文件路径
|
105 |
+
image_path_state = gr.State()
|
106 |
+
|
107 |
+
# 当 image_input 组件发生变化时(即上传新图像时)定义一个动作
|
108 |
+
image_input.change(fn=segment_and_display, # 调用 segment_and_display 函数
|
109 |
+
inputs=image_input, # 将 image_input 组件作为输入传递
|
110 |
+
outputs=[original_output, segmented_output, image_path_state]) # 更新这些输出组件
|
111 |
+
|
112 |
+
# 为第二部分添加另一个 Markdown 标题
|
113 |
+
gr.Markdown("## 🩺 询问上传图像相关的医学问题")
|
114 |
+
# 文本框,供用户输入医学问题
|
115 |
+
question_input = gr.Textbox(label="输入你的问题(例如:'这是什么类型的病变?')")
|
116 |
+
# 文本框,用于显示 MedGemma 的回答
|
117 |
+
answer_output = gr.Textbox(label="MedGemma 回答")
|
118 |
+
|
119 |
+
# 当 question_input 文本框被提交时(例如,按 Enter 键时)定义一个动作
|
120 |
+
question_input.submit(fn=analyze_image_with_question, # 调用 analyze_image_with_question 函数
|
121 |
+
inputs=[image_path_state, question_input], # 传递存储的图像路径和问题
|
122 |
+
outputs=answer_output) # 更新 answer_output 文本框
|
123 |
+
|
124 |
+
# 启动 Gradio 界面
|
125 |
+
iface.launch()
|