cat > /workspace/scratch/lanternfix.py <<'PY'
import cv2,numpy as np,json
s='HH-1041';p='/workspace/scratch/finalmasks/'+s+'.png';m=cv2.imread(p,0)>127;m=m.astype('uint8')*255;ox,oy=json.load(open('/workspace/scratch/detailboxes.json'))[s][:2]
polys=[[[294,882],[318,889],[338,901],[355,913],[366,920],[363,925],[353,931],[328,938],[296,941],[284,938],[285,916]],
[[147,631],[135,645],[126,661],[121,683],[119,710],[119,741],[123,766],[133,789],[150,808],[174,818],[224,823],[273,821],[308,813],[324,800],[333,782],[340,760],[344,733],[346,704],[342,676],[333,652],[312,633]]]
for pp in polys:cv2.fillPoly(m,[np.array(pp,'int32')+[ox,oy]],255)
# Remove the reflected floor under the base; retain its elliptical metal rim.
curve=[[78,1014],[86,1020],[106,1026],[141,1033],[178,1037],[226,1040],[272,1038],[313,1032],[348,1026],[374,1018],[381,1012]]
pp=curve+[[400,1075],[65,1075]];cv2.fillPoly(m,[np.array(pp,'int32')+[ox,oy]],0)
# The little side hook is physically separate from the main silhouette.
cv2.polylines(m,[np.array([[62,816],[58,819],[56,824],[56,832],[58,838],[60,842]],'int32')+[ox,oy]],False,255,3,cv2.LINE_AA)
cv2.imwrite(p,cv2.GaussianBlur(m,(3,3),.4))
PY
python /workspace/scratch/lanternfix.py