Files

43 lines
2.5 KiB
Python

"""Adversarial behavior checks independent of card-specific artwork."""
from pathlib import Path
import json
import numpy as np
from PIL import Image,ImageDraw
from line_detector import detect
ROOT=Path(__file__).resolve().parent
r=json.loads((ROOT/'recipe.json').read_text())
def run(a): return detect(Image.fromarray(a),r)
checks={};w,h=192,192
# Uniform dark glass is not a line.
assert not np.any(run(np.full((h,w,3),28,dtype=np.uint8)));checks['uniformDarkPaneRejected']=True
# A continuous seam at a supported width remains protected.
a=np.full((h,w,3),145,dtype=np.uint8);a[:,92:99]=10
v=run(a);assert np.min(v[20:-20,95])>.97;checks['continuousSeamProtected']=True
# Dark blue interruption exceeds the old max-channel gate but is bracketed.
b=a.copy();b[94:98,92:99]=[35,48,82]
q=run(b);unbridged=dict(r,bridgeDistances=[]);q0=detect(Image.fromarray(b),unbridged)
assert q[96,95]>.8 and q[96,95]>q0[96,95]+.1;checks['shortColoredGapBridged']=True
# No protection grows into an extended blank area along a terminated seam.
c=a.copy();c[70:125,92:99]=145
assert run(c)[96,95]<.01;checks['longBrightGapNotBridged']=True
# Both sides must be brighter; a wide shadow's interior/step edge are rejected.
d=np.full((h,w,3),145,dtype=np.uint8);d[:,65:128]=20
assert run(d)[96,96]<.01 and run(d)[96,65]<.01;checks['broadShadowAndStepEdgeRejected']=True
# Isolated flecks lack elongated support, including a 5px dark spot.
e=np.full((h,w,3),145,dtype=np.uint8);e[94:99,94:99]=10
assert run(e)[96,96]<.2;checks['isolatedTextureSpotRejected']=True
# Thicker dividers and dark crossing junctions exercise the expanded widths.
f=np.full((h,w,3),145,dtype=np.uint8);f[:,85:106]=10
assert run(f)[96,95]>.97;checks['wideDividerProtected']=True
f=np.full((h,w,3),145,dtype=np.uint8);f[:,92:99]=10;f[93:100,:]=10
assert run(f)[96,95]>.8;checks['darkCrossingJunctionRecovered']=True
# A sloping/curved divider does not depend on horizontal/vertical alignment.
im=Image.new('RGB',(w,h),(145,145,145));draw=ImageDraw.Draw(im)
draw.line([(40,15),(54,50),(83,92),(115,131),(135,176)],fill=(10,10,10),width=7)
v=detect(im,r);assert v[92,83]>.8;checks['slopingDividerProtected']=True
# Shift edges cannot wrap across the opposite side of a card.
e=np.full((h,w,3),145,dtype=np.uint8);e[:,0:7]=10
assert not np.any(run(e)[:,170:]);checks['noOppositeEdgeWrap']=True
(ROOT/'detector-checks.json').write_text(json.dumps({'status':'passed','checks':checks,'gapProtection':float(q[96,95]),'gapWithoutBridge':float(q0[96,95])},indent=2)+'\n')
print(json.dumps(checks,indent=2))