File size: 5,600 Bytes
840f4e2 676e2ff 840f4e2 2ef17d8 840f4e2 ef1e412 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
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
# 创建Gradio界面
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 # IoU阈值,降低默认值
],
[
"./images/test_2.jpg", # 图片路径
"large", # 模型大小
0.3, # 置信度阈值
0.3 # IoU阈值,降低默认值
],
[
"./images/test_3.jpg", # 图片路径
"large", # 模型大小
0.3, # 置信度阈值
0.3 # IoU阈值,降低默认值
],
[
"./images/test_4.jpg", # 图片路径
"large", # 模型大小
0.3, # 置信度阈值
0.3 # IoU阈值,降低默认值
],
[
"./images/test_5.jpg", # 图片路径
"large", # 模型大小
0.3, # 置信度阈值
0.3 # IoU阈值,降低默认值
],
[
"./images/test_6.jpg", # 图片路径
"large", # 模型大小
0.3, # 置信度阈值
0.3 # IoU阈值,降低默认值
],
[
"./images/test_7.jpg", # 图片路径
"large", # 模型大小
0.3, # 置信度阈值
0.3 # IoU阈值,降低默认值
]
]
)
# 启动应用
if __name__ == "__main__":
demo.launch(share=True) |