Lecture 03 学习讲义
正文
工具
按问题查找
区域、像素与实例提示怎样指定这一次要分的区域?

LAB 16 · 点、框与负提示:分割规则基线

按问题继续

像素连通域、正负点/框提示、局部/整体多义性

对应课堂(6 页)

可先阅读已有结果,再决定是否运行。重算时请核对各节记录的数据、参数、环境与日期。

区域、像素与实例提示怎样指定这一次要分的区域?

学习路径: 像素、边界与对象身份 · 一句话指向哪个对象。两个入口引用同一份现有材料,不需要重复阅读或运行。

这是 P46–47 提示式分割 的按需短练习,不是 SAM 权重实验。输入同一张 RGB 图、一个正点及可选负点/框,颜色距离与连通域规则返回 mask;没有参数训练。

先看 四种已保存输出,再只改一种条件:颜色容差、负点或框。记录返回面积或边界怎样改变,说明变化来自增加的提示信息还是规则本身的假设。

如果疑问是“训练后模型如何学会响应提示”,转到 SAM 的任务训练;如果已经理解接口,可回 CLS 02 接视觉语言主线,无需额外运行本册。

一个点为什么不总能确定一个对象

输入是自行绘制的 48×64 RGB 图像:相邻的红色外壳和深红色内部零件,另有蓝色物体。正点、负点和矩形是使用者给出的条件,而非正确 mask。本例使用颜色距离与连通域的确定性算法,完整读入像素并返回 mask;它不训练,也不是 SAM。我们保留原来的“同一点同时落在局部和整体”例子,但现在实际改变提示和阈值,检查返回区域。

先预测:扩大颜色容差,正点的连通区域会增加还是减少?增加落在外壳上的负点会如何影响结果?负点在此算法中添加的是颜色排除规则,与 SAM 学到的提示编码不同。

此段独立阅读
展开完整实现代码
# Writable ephemeral workspace for detached readonly cloud runs.
import os, tempfile
os.chdir(tempfile.mkdtemp(prefix='lec03_lab16_'))

import numpy as np
from pathlib import Path
import matplotlib; matplotlib.use('Agg')
import matplotlib.pyplot as plt
out=Path('lab16-results'); out.mkdir(exist_ok=True)
image=np.full((48,64,3),.94); image[8:39,7:34]=[.8,.18,.15]
image[18:29,17:27]=[.48,.10,.08]; image[13:37,43:57]=[.12,.25,.8]
def segment(image,positive,tolerance,negative=None,box=None):
    x,y=positive; seed=image[y,x]; allowed=np.linalg.norm(image-seed,axis=-1)<tolerance
    if negative is not None:
        nx,ny=negative
        allowed &= np.linalg.norm(image-image[ny,nx],axis=-1)>.15
    if box is not None:
        x0,y0,x1,y1=box; crop=np.zeros(allowed.shape,bool); crop[y0:y1,x0:x1]=True; allowed &= crop
    result=np.zeros(allowed.shape,bool); stack=[(x,y)]
    while stack:
        x,y=stack.pop()
        if not (0<=x<64 and 0<=y<48) or result[y,x] or not allowed[y,x]: continue
        result[y,x]=True; stack.extend([(x-1,y),(x+1,y),(x,y-1),(x,y+1)])
    return result
configs=[('tight',.2,None,None),('loose',.5,None,None),('negative',.5,(10,10),None),('box',.5,None,(16,17,28,30))]
masks=[segment(image,(21,23),t,n,b) for _,t,n,b in configs]
fig,axs=plt.subplots(1,5,figsize=(12,3)); axs[0].imshow(image); axs[0].plot(21,23,'g+'); axs[0].set_title('RGB + positive point')
for ax,(name,*_),mask in zip(axs[1:],configs,masks): ax.imshow(mask,vmin=0,vmax=1); ax.set_title(name+' area='+str(mask.sum()))
for ax in axs: ax.axis('off')
fig.tight_layout(); fig.savefig(out/'lab16-prompts.png',dpi=150); plt.close(fig)
assert masks[0].sum()==110 and masks[1].sum()==837
print({name:int(m.sum()) for (name,*_),m in zip(configs,masks)})
print('negative removes similar outer-shell pixels; box clips, neither proves learned object semantics')
此段独立阅读
区域、像素与实例提示怎样指定这一次要分的区域?

已完成的基准运行

以下是本轮本地独立 Python 进程的实际标准输出,云端执行另行记录。

{'tight': 110, 'loose': 837, 'negative': 110, 'box': 156}
negative removes similar outer-shell pixels; box clips, neither proves learned object semantics

紧容差只保留内部 110 像素;宽容差合并到 837 像素外壳。负点回到 110,框则保留框内相连部分。这说明提示与算法假设共同决定输出,框还可能截断对象。

同一RGB输入的四种提示结果

SAM 把图像与提示分别编码,由 mask decoder 预测多个候选和质量分数;不是这段颜色规则。真实模型使用流程见 官方 SAM predictor。本次没有执行 SAM checkpoint。比较算法时固定这张图与提示,保存返回 mask,不把任意一个包含正点的 mask 都叫正确答案。下一步只把正点移到蓝色物体,解释颜色阈值是否还足够;与 LAB 11 像素预测 对照:模型类别预测和使用者选择对象是两个问题。

此段独立阅读
区域、像素与实例提示怎样指定这一次要分的区域?

不运行也能检查:一个点包含在两个区域中

在 8×8 网格里,让局部区域为行列 2–3 的四个格子,整体区域为行列 1–6 的 36 个格子。点 (2,2) 同时属于两者,所以“包含正点”无法唯一规定目标。当前上方 RGB 实验进一步用容差、负点和框实际选择区域。

此段独立阅读
4 / 4