Lecture 03一个点为什么不总能确定一个对象 · 实现代码
一个点为什么不总能确定一个对象 · 实现代码
按问题继续
像素连通域、正负点/框提示、局部/整体多义性
展开完整实现代码
# 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')