|
import gradio as gr |
|
import cv2 |
|
import numpy as np |
|
from sam_segment import segment_image_with_prompt |
|
|
|
|
|
SEGMENT_COLORS = [ |
|
((255, 99, 71), (255, 99, 71)), |
|
((65, 105, 225), (65, 105, 225)), |
|
((50, 205, 50), (50, 205, 50)), |
|
((255, 215, 0), (255, 215, 0)), |
|
((238, 130, 238), (238, 130, 238)), |
|
((0, 191, 255), (0, 191, 255)), |
|
((255, 165, 0), (255, 165, 0)), |
|
((106, 90, 205), (106, 90, 205)), |
|
] |
|
|
|
def segment_image(input_image, model_size, conf_threshold, iou_threshold): |
|
""" |
|
使用FastSAM模型对输入图片进行分割 |
|
""" |
|
try: |
|
|
|
results = segment_image_with_prompt( |
|
image=input_image, |
|
model_size=model_size, |
|
conf=conf_threshold, |
|
iou=iou_threshold, |
|
) |
|
|
|
|
|
output_image = input_image.copy() |
|
|
|
|
|
h, w = output_image.shape[:2] |
|
|
|
|
|
final_mask = np.zeros_like(output_image) |
|
accumulated_mask = np.zeros((h, w), dtype=np.uint8) |
|
|
|
|
|
for idx, points in enumerate(results["segments"]): |
|
|
|
contour_points = np.array(points).reshape(-1, 2).astype(np.int32) |
|
|
|
|
|
mask = np.zeros((h, w), dtype=np.uint8) |
|
|
|
|
|
cv2.fillPoly(mask, [contour_points], 1) |
|
|
|
|
|
mask = cv2.bitwise_and(mask, cv2.bitwise_not(accumulated_mask)) |
|
accumulated_mask = cv2.bitwise_or(accumulated_mask, mask) |
|
|
|
|
|
color_idx = idx % len(SEGMENT_COLORS) |
|
fill_color, stroke_color = SEGMENT_COLORS[color_idx] |
|
|
|
|
|
fill_mask = np.zeros_like(output_image) |
|
fill_mask[mask > 0] = fill_color |
|
final_mask = cv2.addWeighted(final_mask, 1.0, fill_mask, 0.3, 0) |
|
|
|
|
|
cv2.drawContours(final_mask, [contour_points], -1, stroke_color, 2) |
|
|
|
|
|
output_image = cv2.addWeighted(output_image, 1.0, final_mask, 0.5, 0) |
|
|
|
return output_image |
|
|
|
except Exception as e: |
|
print(f"分割过程中出错: {str(e)}") |
|
return input_image |
|
|
|
|
|
demo = gr.Interface( |
|
fn=segment_image, |
|
inputs=[ |
|
gr.Image(label="输入图片"), |
|
gr.Radio( |
|
choices=["small", "large"], |
|
value="large", |
|
label="模型大小", |
|
info="small: 更快但精度较低, large: 更慢但精度更高" |
|
), |
|
gr.Slider( |
|
minimum=0.1, |
|
maximum=1.0, |
|
value=0.4, |
|
step=0.1, |
|
label="置信度阈值", |
|
info="值越高,检测越严格" |
|
), |
|
gr.Slider( |
|
minimum=0.1, |
|
maximum=1.0, |
|
value=0.3, |
|
step=0.1, |
|
label="IoU阈值", |
|
info="值越低则保留更多重叠区域,值越高则保留更少重叠区域" |
|
) |
|
], |
|
outputs=gr.Image(label="分割结果"), |
|
title="FastSAM图像分割演示", |
|
description="上传一张图片,调整参数,模型将对图片中的对象进行分割。", |
|
examples=[ |
|
[ |
|
"./images/test_1.png", |
|
"large", |
|
0.3, |
|
0.3 |
|
], |
|
[ |
|
"./images/test_2.jpg", |
|
"large", |
|
0.3, |
|
0.3 |
|
], |
|
[ |
|
"./images/test_3.jpg", |
|
"large", |
|
0.3, |
|
0.3 |
|
], |
|
[ |
|
"./images/test_4.jpg", |
|
"large", |
|
0.3, |
|
0.3 |
|
], |
|
[ |
|
"./images/test_5.jpg", |
|
"large", |
|
0.3, |
|
0.3 |
|
], |
|
[ |
|
"./images/test_6.jpg", |
|
"large", |
|
0.3, |
|
0.3 |
|
], |
|
[ |
|
"./images/test_7.jpg", |
|
"large", |
|
0.3, |
|
0.3 |
|
] |
|
] |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch(share=True) |