"""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))