yanranxiaoxi commited on
Commit
7d6aa54
1 Parent(s): 2c978d0

First commit

Browse files
Files changed (3) hide show
  1. README.md +3 -3
  2. app.py +151 -0
  3. requirements.txt +9 -0
README.md CHANGED
@@ -1,13 +1,13 @@
1
  ---
2
- title: Skin Lesion Base
3
  emoji: 📊
4
  colorFrom: pink
5
  colorTo: purple
6
  sdk: streamlit
7
- sdk_version: 1.37.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Skin Lesion Base Demo
3
  emoji: 📊
4
  colorFrom: pink
5
  colorTo: purple
6
  sdk: streamlit
7
+ sdk_version: 1.29.0
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
  ---
12
 
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import streamlit as st
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from matplotlib.backends.backend_agg import FigureCanvasAgg
7
+ from PIL import Image
8
+ from streamlit_image_select import image_select
9
+ from tqdm import tqdm
10
+ import os
11
+ import shutil
12
+ from PIL import Image
13
+ import torch
14
+ import matplotlib.pyplot as plt
15
+ from datasets import load_dataset
16
+ from transformers import AutoProcessor, AutoModelForMaskGeneration
17
+
18
+ def show_mask(image, mask, ax=None):
19
+ fig, axes = plt.subplots()
20
+ axes.imshow(np.array(image))
21
+ color = np.array([30/255, 144/255, 255/255, 0.6])
22
+ h, w = mask.shape[-2:]
23
+ mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
24
+ axes.imshow(mask_image)
25
+ canvas = FigureCanvasAgg(fig)
26
+ canvas.draw()
27
+ pil_image = Image.frombytes('RGB', canvas.get_width_height(), canvas.tostring_rgb())
28
+ plt.close(fig)
29
+ return pil_image
30
+ def get_bounding_box(ground_truth_map):
31
+ y_indices, x_indices = np.where(ground_truth_map > 0)
32
+ x_min, x_max = np.min(x_indices), np.max(x_indices)
33
+ y_min, y_max = np.min(y_indices), np.max(y_indices)
34
+ H, W = ground_truth_map.shape
35
+ x_min = max(0, x_min - np.random.randint(0, 20))
36
+ x_max = min(W, x_max + np.random.randint(0, 20))
37
+ y_min = max(0, y_min - np.random.randint(0, 20))
38
+ y_max = min(H, y_max + np.random.randint(0, 20))
39
+ bbox = [x_min, y_min, x_max, y_max]
40
+ return bbox
41
+ def get_output(image,prompt):
42
+ inputs = processor(image,input_boxes=[[prompt]],return_tensors='pt').to(device)
43
+ model.eval()
44
+ with torch.no_grad():
45
+ outputs = model(**inputs,multimask_output=False)
46
+ output_proba = torch.sigmoid(outputs.pred_masks.squeeze(1))
47
+ output_proba = output_proba.cpu().numpy().squeeze()
48
+ output = (output_proba > 0.5).astype(np.uint8)
49
+ return output
50
+ def generate_image(np_array):
51
+ return Image.fromarray((np_array*255).astype('uint8'),mode='L')
52
+ def iou_calculation(result1, result2):
53
+ intersection = np.logical_and(result1, result2)
54
+ union = np.logical_or(result1, result2)
55
+ iou_score = np.sum(intersection) / np.sum(union)
56
+ iou_score = "{:.4f}".format(iou_score)
57
+ return float(iou_score)
58
+ def calculate_pixel_accuracy(image1, image2):
59
+ if image1.size != image2.size or image1.mode != image2.mode:
60
+ image1 = image1.resize(image2.size, Image.BILINEAR)
61
+ if image1.mode != image2.mode:
62
+ image1 = image1.convert(image2.mode)
63
+ width, height = image1.size
64
+ total_pixels = width * height
65
+ image1 = image1.convert("RGB")
66
+ image2 = image2.convert("RGB")
67
+ pixels1 = image1.load()
68
+ pixels2 = image2.load()
69
+ num_correct_pixels = 0
70
+ for y in range(height):
71
+ for x in range(width):
72
+ if pixels1[x, y] == pixels2[x, y]:
73
+ num_correct_pixels += 1
74
+ accuracy = num_correct_pixels / total_pixels
75
+ return accuracy
76
+ def calculate_f1_score(image1, image2):
77
+ if image1.size != image2.size or image1.mode != image2.mode:
78
+ image1 = image1.resize(image2.size, Image.BILINEAR)
79
+ if image1.mode != image2.mode:
80
+ image1 = image1.convert(image2.mode)
81
+ width, height = image1.size
82
+ image1 = image1.convert("L")
83
+ image2 = image2.convert("L")
84
+ np_image1 = np.array(image1)
85
+ np_image2 = np.array(image2)
86
+ np_image1_flat = np_image1.flatten()
87
+ np_image2_flat = np_image2.flatten()
88
+ true_positives = np.sum(np.logical_and(np_image1_flat == 255, np_image2_flat == 255))
89
+ false_positives = np.sum(np.logical_and(np_image1_flat != 255, np_image2_flat == 255))
90
+ false_negatives = np.sum(np.logical_and(np_image1_flat == 255, np_image2_flat != 255))
91
+ precision = true_positives / (true_positives + false_positives + 1e-7)
92
+ recall = true_positives / (true_positives + false_negatives + 1e-7)
93
+ f1_score = 2 * (precision * recall) / (precision + recall + 1e-7)
94
+ return f1_score
95
+ def calculate_dice_coefficient(image1, image2):
96
+ if image1.size != image2.size or image1.mode != image2.mode:
97
+ image1 = image1.resize(image2.size, Image.BILINEAR)
98
+ if image1.mode != image2.mode:
99
+ image1 = image1.convert(image2.mode)
100
+ width, height = image1.size
101
+ image1 = image1.convert("L")
102
+ image2 = image2.convert("L")
103
+ np_image1 = np.array(image1)
104
+ np_image2 = np.array(image2)
105
+ np_image1_flat = np_image1.flatten()
106
+ np_image2_flat = np_image2.flatten()
107
+ true_positives = np.sum(np.logical_and(np_image1_flat == 255, np_image2_flat == 255))
108
+ false_positives = np.sum(np.logical_and(np_image1_flat != 255, np_image2_flat == 255))
109
+ false_negatives = np.sum(np.logical_and(np_image1_flat == 255, np_image2_flat != 255))
110
+ dice_coefficient = (2 * true_positives) / (2 * true_positives + false_positives + false_negatives)
111
+ return dice_coefficient
112
+ device = "cuda" if torch.cuda.is_available() else "cpu"
113
+ st.set_page_config(layout='wide')
114
+ ds = load_dataset('yanranxiaoxi/skin-lesion-mask',split='train')
115
+ s1 = ds[7]['image']
116
+ s2 = ds[8]['image']
117
+ s3 = ds[9]['image']
118
+ s4 = ds[10]['image']
119
+ s1_label = ds[7]['label']
120
+ s2_label = ds[8]['label']
121
+ s3_label = ds[9]['label']
122
+ s4_label = ds[10]['label']
123
+ image_arr = [s1,s2,s3,s4]
124
+ label_arr = [s1_label,s2_label,s3_label,s4_label]
125
+ img = image_select(
126
+ label="选择一个皮肤病变图像",
127
+ images=[
128
+ s1,s2,s3,s4
129
+ ],
130
+ captions=["例 1","例 2","例 3","例 4"],
131
+ return_value='index'
132
+ )
133
+ processor = AutoProcessor.from_pretrained('yanranxiaoxi/skin-lesion-base')
134
+ model = AutoModelForMaskGeneration.from_pretrained('yanranxiaoxi/skin-lesion-focalloss-base-combined')
135
+ model.to(device)
136
+ p = get_bounding_box(np.array(label_arr[img]))
137
+ predicted_mask_array = get_output(image_arr[img],p)
138
+ predicted_mask = generate_image(predicted_mask_array)
139
+ result_image = show_mask(image_arr[img],predicted_mask_array)
140
+ with st.container():
141
+ tab1, tab2 = st.tabs(['可视化','指标'])
142
+ with tab1:
143
+ col1, col2 = st.columns(2)
144
+ with col1:
145
+ st.image(image_arr[img],caption='原始皮肤病变图像',use_column_width=True)
146
+ with col2:
147
+ st.image(result_image,caption='叠加标注遮罩区域',use_column_width=True)
148
+ with tab2:
149
+ st.write(f'IOU 得分:{iou_calculation(label_arr[img],predicted_mask)}')
150
+ st.write(f'像素精确度:{calculate_pixel_accuracy(label_arr[img],predicted_mask)}')
151
+ st.write(f'骰子系数(DC)得分:{calculate_dice_coefficient(label_arr[img],predicted_mask)}')
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit-image-select
2
+ streamlit
3
+ tqdm
4
+ torch
5
+ matplotlib
6
+ Pillow
7
+ transformers
8
+ datasets
9
+ accelerate