43 lines
3.6 KiB
Python
43 lines
3.6 KiB
Python
import unittest,struct
|
|
import numpy as np
|
|
import terrain_component_cleanup as m
|
|
class GeometryTests(unittest.TestCase):
|
|
def palette(self):
|
|
p=np.tile(np.arange(256,dtype=np.uint8)[:,None],(1,3));p[:,1]=(p[:,1].astype(int)*3%256).astype(np.uint8);return p
|
|
def sources(self):
|
|
a=np.full((32,32),152,np.uint8);a[:12,:]=197;a[:,13:18]=18;a[:12,18:]=226;a[12:16,18:]=226;a[17:23,18:]=226;a[24:,18:]=226;a[20,1]=242;return [a,a[:,::-1].copy()]
|
|
def fields(self):
|
|
y,x=np.indices((512,1024));return {i:np.stack([(x*19+y*11+i*7)%256,(x*13+y*17)%256,(x*3+y*7)%256],axis=-1).astype(float)for i in range(5)}
|
|
def test_source_decode_includes_honest_protected_indices(self):
|
|
a=self.sources()[0];data=struct.pack('<5i',1,1,0,32,32)+a.tobytes();self.assertTrue(np.array_equal(m.decode_source32(data),a));self.assertEqual(m.decode_source32(data)[20,1],242)
|
|
def test_bad_format_and_truncated_source_rejected(self):
|
|
for b in [b'',struct.pack('<5i',0,1,0,32,32)+bytes(1024),struct.pack('<5i',1,1,0,32,32)+bytes(1023)]:
|
|
with self.assertRaises(ValueError):m.decode_source32(b)
|
|
def test_nonwater_protected_class_not_reclassified_as_ordinary(self):
|
|
a=self.sources()[0];a[2,2]=249
|
|
with self.assertRaises(ValueError):m.material_labels(a,12)
|
|
def test_material_masks_and_approach_are_exact(self):
|
|
a=self.sources()[0];labels=m.material_labels(a,12);self.assertEqual(labels[20,1],0);self.assertEqual(labels[5,13],1);self.assertEqual(labels[5,2],2);self.assertEqual(labels[10,22],4);self.assertEqual(labels[20,22],3);self.assertEqual(labels[16,22],0);self.assertEqual(labels[23,22],0)
|
|
def test_registered_pair_geometry_and_protected_samples(self):
|
|
sources=self.sources();pal=self.palette();out,owners,protected,guide=m.derive_pair(sources,pal,self.fields());expected=m.material_labels(guide,48);self.assertTrue(np.array_equal(owners,np.repeat(np.repeat(expected,4,0),4,1)));self.assertTrue(np.array_equal(out[protected],np.repeat(np.repeat(pal[guide],4,0),4,1)[protected]));self.assertEqual(out.shape,(512,1024,3));self.assertTrue(protected.any());self.assertTrue(np.any(out[~protected]!=np.repeat(np.repeat(pal[guide],4,0),4,1)[~protected]))
|
|
def test_different_genuine_texture_changes_only_its_component(self):
|
|
s=self.sources();p=self.palette();f=self.fields();out,owners,_,_=m.derive_pair(s,p,f);g={k:v.copy()for k,v in f.items()};g[3]=255-g[3];new,_,_,_=m.derive_pair(s,p,g);self.assertTrue(np.array_equal(new[owners!=3],out[owners!=3]));self.assertTrue(np.any(new[owners==3]!=out[owners==3]))
|
|
def test_missing_component_rejected(self):
|
|
f=self.fields();del f[3]
|
|
with self.assertRaises(ValueError):m.derive_pair(self.sources(),self.palette(),f)
|
|
def test_both_frames_required(self):
|
|
with self.assertRaises(ValueError):m.derive_pair(self.sources()[:1],self.palette(),self.fields())
|
|
def test_crop_cannot_escape_genuine_image(self):
|
|
a=np.zeros((8,8,3),np.uint8)
|
|
for box in [(-1,0,3,3),(0,0,9,8),(0,0,0,2)]:
|
|
with self.assertRaises(ValueError):m.donor_field(a,box,(8,8))
|
|
def test_identity_mesh_preserves_every_rgb_pixel(self):
|
|
a=np.arange(16*16*3,dtype=np.uint8).reshape(16,16,3);knots=[0,.5,1];self.assertTrue(np.array_equal(m.warp_landmarks(a,knots,knots,knots,knots),a))
|
|
def test_landmark_rows_are_moved_without_inventing_texture(self):
|
|
a=np.zeros((32,32,3),np.uint8);a[8:10]=[100,150,200];b=m.warp_landmarks(a,[0,1],[0,.5,1],[0,1],[0,.25,1]);self.assertGreater(b[16,:,1].max(),100);self.assertEqual(b.shape,a.shape)
|
|
def test_reversed_missing_nan_mesh_knots_rejected(self):
|
|
a=np.zeros((8,8,3),np.uint8)
|
|
for k in [[0,.7,.6,1],[.1,1],[0,float('nan'),1],[0,0,1]]:
|
|
with self.assertRaises(ValueError):m.warp_landmarks(a,[0,1],k,[0,1],k)
|
|
if __name__=='__main__':unittest.main()
|