xiaoming32236046 commited on
Commit
40be5d0
1 Parent(s): 70f3e38

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -144
app.py CHANGED
@@ -1,148 +1,60 @@
1
- import numpy as np
2
- import cv2
3
- import matplotlib.pyplot as plt
4
  import gradio as gr
5
- import tempfile
6
- import os
7
- import json
8
-
9
- def calculate_snr(image, roi_json):
10
- roi_points = json.loads(roi_json)
11
-
12
- # 创建临时文件来保存上传的图像
13
- with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_file:
14
- temp_filename = temp_file.name
15
- cv2.imwrite(temp_filename, image)
16
-
17
- # 读取图像
18
- img = cv2.imread(temp_filename, cv2.IMREAD_GRAYSCALE)
19
-
20
- # 计算信号和背景区域
21
- signal_mask = np.zeros(img.shape, np.uint8)
22
- cv2.fillPoly(signal_mask, [np.array(roi_points)], 255)
23
- signal = cv2.bitwise_and(img, img, mask=signal_mask)
24
-
25
- background_mask = cv2.bitwise_not(signal_mask)
26
- background = cv2.bitwise_and(img, img, mask=background_mask)
27
-
28
- # 计算信号区域的平均强度
29
- signal_mean = np.mean(signal[signal_mask == 255])
30
-
31
- # 计算背景区域的标准差
32
- background_std = np.std(background[background_mask == 255])
33
-
34
- # 计算SNR
35
- snr = signal_mean / background_std if background_std != 0 else float('inf')
36
 
37
- # 创建图像结果
38
- plt.figure(figsize=(10, 5))
39
- plt.subplot(121)
40
- plt.imshow(signal, cmap='gray')
41
- plt.title('Signal ROI')
42
- plt.subplot(122)
43
- plt.imshow(background, cmap='gray')
44
- plt.title('Background ROI')
45
 
46
- # 保存图像结果到临时文件
47
- result_filename = tempfile.mktemp(suffix='.png')
48
- plt.savefig(result_filename)
49
- plt.close()
50
-
51
- # 删除临时文件
52
- os.unlink(temp_filename)
53
-
54
- return (
55
- f"信号平均强度: {signal_mean:.2f}\n"
56
- f"背景标准差: {background_std:.2f}\n"
57
- f"信噪比(SNR): {snr:.2f}",
58
- result_filename
59
- )
60
-
61
- # 自定义HTML组件和JavaScript代码
62
- html_code = """
63
- <div>
64
- <canvas id="roi-canvas" width="500" height="500" style="border:1px solid #000000;"></canvas>
65
- <button onclick="startDrawing()">Start Drawing</button>
66
- <button onclick="stopDrawing()">Stop Drawing</button>
67
- <button onclick="clearCanvas()">Clear</button>
68
- <textarea id="roi-points" style="display:none;"></textarea>
69
- </div>
70
- <script>
71
- let canvas = document.getElementById('roi-canvas');
72
- let ctx = canvas.getContext('2d');
73
- let roi = [];
74
- let drawing = false;
75
-
76
- canvas.addEventListener('mousedown', (e) => {
77
- drawing = true;
78
- roi.push({x: e.offsetX, y: e.offsetY});
79
- });
80
-
81
- canvas.addEventListener('mousemove', (e) => {
82
- if (drawing) {
83
- let lastPoint = roi[roi.length - 1];
84
- ctx.beginPath();
85
- ctx.moveTo(lastPoint.x, lastPoint.y);
86
- ctx.lineTo(e.offsetX, e.offsetY);
87
- ctx.strokeStyle = 'green';
88
- ctx.lineWidth = 2;
89
- ctx.stroke();
90
- ctx.closePath();
91
- roi.push({x: e.offsetX, y: e.offsetY});
92
- }
93
- });
94
-
95
- canvas.addEventListener('mouseup', () => {
96
- drawing = false;
97
- document.getElementById('roi-points').value = JSON.stringify(roi);
98
- });
99
-
100
- function startDrawing() {
101
- drawing = true;
102
- }
103
-
104
- function stopDrawing() {
105
- drawing = false;
106
- }
107
-
108
- function clearCanvas() {
109
- ctx.clearRect(0, 0, canvas.width, canvas.height);
110
- roi = [];
111
- document.getElementById('roi-points').value = '';
112
- }
113
- </script>
114
- """
115
-
116
- # 创建Gradio接口
117
- with gr.Blocks() as demo:
118
- with gr.Row():
119
- image_input = gr.Image(label="上传图像")
120
- roi_output = gr.HTML(html_code, label="绘制ROI区域")
121
- roi_data = gr.Textbox(label="ROI Data", visible=False)
122
-
123
- calculate_button = gr.Button("计算SNR")
124
- result_text = gr.Textbox(label="结果")
125
- result_image = gr.Image(label="ROI 图像")
126
-
127
- def extract_roi_data(html_output):
128
- return html_output
129
-
130
- image_input.change(
131
- fn=lambda x: "",
132
- inputs=image_input,
133
- outputs=roi_output
134
- )
135
-
136
- roi_output.change(
137
- fn=extract_roi_data,
138
- inputs=roi_output,
139
- outputs=roi_data
140
- )
141
-
142
- calculate_button.click(
143
- fn=calculate_snr,
144
- inputs=[image_input, roi_data],
145
- outputs=[result_text, result_image]
146
- )
147
 
148
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import numpy as np
3
+ from PIL import Image, ImageDraw
4
+ import io
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ def calculate_snr(image, roi_mask):
7
+ # Convert image to numpy array
8
+ img_array = np.array(image)
 
 
 
 
 
9
 
10
+ # Create ROI and background masks
11
+ roi = img_array * roi_mask
12
+ bg = img_array * (1 - roi_mask)
13
+
14
+ # Calculate mean and standard deviation
15
+ roi_mean = np.mean(roi[roi != 0])
16
+ bg_mean = np.mean(bg[bg != 0])
17
+ bg_std = np.std(bg[bg != 0])
18
+
19
+ # Calculate SNR
20
+ snr = (roi_mean - bg_mean) / bg_std
21
+
22
+ return snr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ def process_image(input_image, roi_coordinates):
25
+ image = Image.open(io.BytesIO(input_image))
26
+
27
+ # Create a mask for the ROI
28
+ mask = Image.new('L', image.size, 0)
29
+ draw = ImageDraw.Draw(mask)
30
+ draw.polygon(roi_coordinates, fill=255)
31
+
32
+ # Convert mask to binary numpy array
33
+ mask_array = np.array(mask) / 255
34
+
35
+ # Calculate SNR
36
+ snr = calculate_snr(image.convert('L'), mask_array)
37
+
38
+ # Visualize the ROI on the image
39
+ overlay = Image.new('RGBA', image.size, (0, 0, 0, 0))
40
+ draw = ImageDraw.Draw(overlay)
41
+ draw.polygon(roi_coordinates, fill=(255, 0, 0, 64))
42
+ result_image = Image.alpha_composite(image.convert('RGBA'), overlay)
43
+
44
+ return result_image, f"SNR: {snr:.2f}"
45
+
46
+ iface = gr.Interface(
47
+ fn=process_image,
48
+ inputs=[
49
+ gr.Image(type="numpy", label="Upload Fluorescence Image"),
50
+ gr.ImageMask(label="Draw ROI", source="upload")
51
+ ],
52
+ outputs=[
53
+ gr.Image(type="pil", label="Result"),
54
+ gr.Textbox(label="Signal-to-Noise Ratio (SNR)")
55
+ ],
56
+ title="Fluorescence Staining Quality Assessment",
57
+ description="Upload a fluorescence image and draw the region of interest (ROI) to calculate the Signal-to-Noise Ratio (SNR)."
58
+ )
59
+
60
+ iface.launch()