def test_imagefuncs(self): self.a2.subtract_image(self.a2.image,offset=0) self.assertTrue(np.all(self.a2.image<=0.0001),"Failed to subtract image from itself") x=np.linspace(-3*np.pi,3*np.pi,101) X,Y=np.meshgrid(x,x) i=ImageFile(np.sin(X)*np.cos(Y)) i2=i.clone j=i.fft() self.assertTrue(np.all(np.unique(np.argmax(j,axis=1))==np.array([47,53])),"FFT of image test failed") j.imshow() self.assertTrue(len(plt.get_fignums())==1,"Imshow didn't open one window") plt.close("all") self.a2.imshow(title=None,figure=None) self.a2.imshow(title="Hello",figure=1) self.assertTrue(len(plt.get_fignums())==1,"Imshow with arguments didn't open one window") plt.close("all") i=i2 k=i+0.2*X-0.1*Y+0.2 k.level_image(mode="norm") j=k-i self.assertLess(np.max(j),0.01,"Level Image failed") i2=i.clone i2.quantize([-0.5,0,0.5]) self.assertTrue(np.all(np.unique(i2.data)==np.array([-0.5,0,0.5])),"Quantise levels failed") i2=i.clone i2.quantize([-0.5,0,0.5],levels=[-0.25,0.25]) self.assertTrue(np.all(np.unique(i2.data)==np.array([-0.5,0,0.5])),"Quantise levels failed") i2=i.clone i2.rotate(np.pi/4) i2.fft() self.assertTrue(np.all(np.unique(np.argmax(i2,axis=1))==np.array([46, 47, 49, 50, 51, 53])),"FFT of image test failed")
def test_mask(self): im = ImageFile(np.arange(12).reshape(3,4)) im.mask = np.zeros(im.shape, dtype=bool) im.mask.data[1,1] = True ist2 = ImageStack(np.arange(60).reshape(4,3,5)) ist2.insert(1, im) #Insert an image with a mask self.assertTrue(ist2[1].mask.data.shape==ist2[1].shape) self.assertTrue(ist2[1].mask[1,1]==True, 'inserting an image with a mask into an ImageStack has failed') ist2[3].mask = np.ones(im.shape, dtype=bool) self.assertTrue(np.all(ist2[3].mask), 'setting mask on an image stack item not working')
def test_load_from_ImageFile(self): #uses the ImageFile.im attribute to set up ImageArray. Memory overlaps imfi = ImageFile(self.arr) imarr = ImageArray(imfi) self.assertTrue(np.array_equal(imarr, imfi.image), 'Initialising from ImageFile failed') self.assertTrue(shares_memory(imarr, imfi.image))
def test_constructors(self): self.imgFile = ImageFile( os.path.join(thisdir, 'coretestdata/im1_annotated.png')) self.d = Data(self.imgFile) self.imgFile2 = ImageFile(self.d) del self.imgFile2["Stoner.class"] del self.imgFile2["x_vector"] del self.imgFile2["y_vector"] self.assertTrue( np.all(self.imgFile.image == self.imgFile2.image), "Roundtripping constructor through Data failed to dupliocate data." ) self.assertEqual( self.imgFile.metadata, self.imgFile2.metadata, "Roundtripping constructor through Data failed to duplicate metadata: {} {}" .format(self.imgFile2.metadata ^ self.imgFile.metadata, self.imgFile.metadata ^ self.imgFile2.metadata))
def test_ImageStack2(self): self.assertTrue( self.istack2.shape == (91, 100, 100), "ImageStack2.shape wrong at {}".format(self.istack2.shape)) i = ImageFile(np.zeros((100, 100))).draw.circle(50, 50, 25) self.m1 = self.istack2.mean() self.istack2.align(i, method="imreg_dft") data = self.istack2.slice_metadata(["tvec", "angle", "scale"], output="Data") self.assertTrue(data.shape == (91, 4), "Slice metadata went a bit funny") self.assertTrue( sorted( data.column_headers) == ['angle', 'scale', 'tvec_0', 'tvec_1'], "slice metadata column headers wrong at {}".format( data.column_headers)) self.m2 = self.istack2.mean() self.assertTrue( np.abs(self.m1.mean() - self.m2.mean()) / self.m1.mean() < 1E-2, "Problem calculating means of stacks.") s1 = self.istack2[:, 45:55, 45:55] s2 = self.istack2[:, 50, :] s3 = self.istack2[:, :, 50] s4 = self.istack2[50, :, :] self.assertEqual(s1.shape, (91, 10, 10), "3D slicing to produce 3D stack didn't work.") self.assertEqual(s2.shape, (91, 100), "3D slicing to 2D section z-y plane failed.") self.assertEqual(s3.shape, (91, 100), "3D slicing to 2D section z-x plane failed.") self.assertEqual(s4.shape, (100, 100), "3D slicing to 2D section x-y plane failed.") self.assertEqual(len(self.istack2.images), 91, "len(ImageFolder.images) failed.") sa = [] for im in self.istack2.images: sa.append(im.shape) sa = np.array(sa) self.assertTrue(np.all(sa == np.ones((91, 2)) * 100), "Result from iterating over images failed.") self.istack2.adjust_contrast() self.assertEqual((np.array( self.istack2.min()).mean(), np.array(self.istack2.max()).mean()), (-1.0, 1.0), "Adjust contrast failure") self.im1 = self.istack2[0] self.im1.normalise() self.im1.convert(np.int32) self.im2 = self.im1.convert(np.float32) conv_err = (self.istack2[0].image - self.im2.image).max() self.assertTrue( conv_err < 1E-7, "Problems double converting images:{}.".format(conv_err)) self.im1 = self.istack2[0].convert(np.int64) self.im1 = self.im1.convert(np.int8) self.im2 = self.istack2[0].convert(np.int8) self.assertTrue( abs((self.im2 - self.im1).max()) <= 2.0, "Failed up/down conversion to integer images.")
def setUp(self): self.td = ImageFolder(testdir, pattern='*.png') self.ks = ImageStack2(testdir) self.ks = ImageStack2(self.td) #load in two ways self.assertTrue(len(self.ks)==len(os.listdir(testdir))) self.istack2=ImageStack2() for theta in np.linspace(0,360,91): i=ImageFile(np.zeros((100,100))) x,y=10*np.cos(np.pi*theta/180)+50,10*np.sin(np.pi*theta/180)+50 i.draw.circle(x,y,25) self.istack2.insert(0,i)
def _load_asc(self, filename): """Load a single scan file from ascii data.""" with open(filename, "r") as data: if not data.readline().startswith("# Daisy frame view snapshot"): raise ValueError(f"{filename} lacked the correct header line") tmp = ImageFile() for line in data: if not line.startswith("# "): break parts = [x.strip() for x in line[2:].strip().split(":")] key = parts[0] value = ":".join(parts[1:]) units = PARAM_RE.match(value) if units and units.groups()[1]: key += f" [{units.groups()[1]}]" value = units.groups()[0] tmp.metadata[key] = value xpx = tmp["x-pixels"] ypx = tmp["y-pixels"] metadata = tmp.metadata tmp.image = genfromtxt(filename).reshape((xpx, ypx)) tmp.metadata = metadata tmp.filename = tmp["display"] self.append(tmp) return self
def test_methods(self): b = np.arange(12).reshape(3, 4) ifi = ImageFile(b) ifi.asfloat(normalise=False, clip_negative=False) #convert in place self.assertTrue(ifi.image.dtype.kind == 'f') self.assertTrue(np.max(ifi) == 11.0) ifi.image == ifi.image * 5 ifi.rescale_intensity() self.assertTrue( np.allclose(ifi.image, np.linspace(0, 1, 12).reshape(3, 4))) ifi.crop(0, 3, 0, None) self.assertTrue(ifi.shape == ( 3, 3)) #check crop is forced to overwrite ifi despite shape change
def test_methods(self): b=np.arange(12).reshape(3,4) ifi = ImageFile(b) ifi.asfloat(normalise=False, clip_negative=False) #convert in place self.assertTrue(ifi.image.dtype.kind == 'f') self.assertTrue(np.max(ifi) == 11.0) ifi.image == ifi.image*5 ifi.rescale_intensity() self.assertTrue(np.allclose(ifi.image, np.linspace(0,1,12).reshape(3,4))) ifi.crop(0,3,0,None) self.assertTrue(ifi.shape==(3,3)) #check crop is forced to overwrite ifi despite shape change
def average(self, weights=None, _box=None): """Get an array of average pixel values for the stack. Pass through to numpy average Returns: average(ImageArray): average values """ if not self.size: raise RuntimeError("Cannot average Imagefolder if images have different sizes") stack = np.stack(self.images, axis=0) average = np.average(stack, axis=0, weights=weights) ret = average.view(ImageArray) ret.metadata = self.metadata.common_metadata return ImageFile(ret[ret._box(_box)])
def test_funcs(self): b=self.a.translate((2.5,3)) self.c=b.correct_drift(ref=self.a) self.d=b.align(self.a,method="scharr") tv=np.array(self.d["tvec"])*10 cd=np.array(self.c["correct_drift"])*10 shift=np.array([25,30]) d1=mag(cd-shift) d2=mag(tv-(-shift[::-1])) self.assertLess(d1,1.5,"Drift Correct off by more than 0.1 pxiels.") self.assertLess(d2,1.5,"Scharr Alignment off by more than 0.1 pxiels.") a1=ImageFile(self.a1.clone) a1.as_float() a1.image=np.sqrt(a1.image)/2+0.25 a1.adjust_contrast() self.assertEqual(a1.span(),(0.0,1.0),"Either adjust_contrast or span failed with an ImageFile")
def test_methods(self): b = np.arange(12).reshape(3, 4) ifi = ImageFile(b) ifi.asfloat() #convert in place self.assertTrue(ifi.image.dtype.kind == 'f') ifi.image == ifi.image * 5 ifi.rescale_intensity() self.assertTrue( np.allclose(ifi.image, np.linspace(0, 1, 12).reshape(3, 4)))
def test_operators(self): i = ImageFile(np.zeros((10, 10))) i = i + 1 i += 4 i += i.clone i += i.clone.data self.assertEqual(i.sum(), 2000, "Addition operators failed") i /= 4 self.assertEqual(i.sum(), 500, "Division operators failed") i = i / 5 self.assertEqual(i.sum(), 100, "Division operators failed") i2 = i.clone i -= 0.75 i2 -= 0.25 i3 = i2 // i self.assertEqual(i3.sum(), 50, "Division operators failed") i = ImageFile(np.zeros((10, 5))) i = ~i self.assertEqual(i.shape, (5, 10), "Invert to rotate failed") i.image = i.image.astype("uint8") i = -i self.assertEqual(i.sum(), 50 * 255, "Negate operators failed")
def test_load_save_all(self): tmpdir = tempfile.mkdtemp() pth = path.join(__home__, "..") datadir = path.join(pth, "sample-data") image = ImageFile(path.join(datadir, "kermit.png")) ims = {} fmts = ["uint8", "uint16", "uint32", "float32"] modes = {"uint8": "L", "uint32": "RGBX", "float32": "F"} for fmt in fmts: ims[fmt] = image.clone.convert(fmt) ims[fmt].save_tiff(path.join(tmpdir, "kermit-{}.tiff".format(fmt))) ims[fmt].save_tiff(path.join( tmpdir, "kermit-forcetype{}.tiff".format(fmt)), forcetype=True) ims[fmt].save_npy(path.join(tmpdir, "kermit-{}.npy".format(fmt))) if fmt != "uint16": im = Image.fromarray((ims[fmt].view(np.ndarray)), modes[fmt]) im.save( path.join(tmpdir, "kermit-nometadata-{}.tiff".format(fmt))) del ims[fmt]["Loaded from"] for fmt in fmts: iml = ImageFile(path.join(tmpdir, "kermit-{}.tiff".format(fmt))) del iml["Loaded from"] self.i = ims[fmt] self.i2 = iml self.assertEqual( ims[fmt], iml, "Round tripping tiff with format {} failed".format(fmt)) iml = ImageFile(path.join(tmpdir, "kermit-{}.npy".format(fmt))) del iml["Loaded from"] self.assertTrue( np.all(ims[fmt].data == iml.data), "Round tripping npy with format {} failed".format(fmt)) if fmt != "uint16": im = ImageFile( path.join(tmpdir, "kermit-nometadata-{}.tiff".format(fmt))) self.assertTrue( np.all(im.data == ims[fmt].data), "Loading from tif without metadata failed for {}".format( fmt)) shutil.rmtree(tmpdir) i8 = image.convert("uint8")
def setUp(self): self.a = np.linspace(0, 5, 12).reshape(3, 4) self.ifi = ImageFile(self.a)
Created on Tue Feb 20 21:22:18 2018 @author: phygbu """ from Stoner.Image import ImageFile, ImageFolder, ImageStack import numpy as np import unittest import os import Stoner Stoner.Options.multiprocessing = False testdir = os.path.join(os.path.dirname(__file__), "coretestdata", "testims") istack2 = ImageStack() for theta in np.linspace(0, 360, 91): i = ImageFile(np.zeros((100, 100))) x, y = 10 * np.cos(np.pi * theta / 180) + 50, 10 * np.sin( np.pi * theta / 180) + 50 i.draw.circle(x, y, 25) i.filename = "Angle {}".format(theta) istack2.insert(0, i) class ImageStackTest(unittest.TestCase): def setUp(self): self.td = ImageFolder(testdir, pattern='*.png') self.ks = ImageStack(testdir) self.ks = ImageStack(self.td) #load in two ways self.assertTrue(len(self.ks) == len(os.listdir(testdir))) self.istack2 = istack2.clone
# -*- coding: utf-8 -*- """ Created on Tue Feb 20 21:22:18 2018 @author: phygbu """ from Stoner.Image import ImageFile,ImageFolder, ImageStack import numpy as np import unittest import os testdir=os.path.join(os.path.dirname(__file__),"coretestdata","testims") istack2=ImageStack() for theta in np.linspace(0,360,91): i=ImageFile(np.zeros((100,100))) x,y=10*np.cos(np.pi*theta/180)+50,10*np.sin(np.pi*theta/180)+50 i.draw.circle(x,y,25) i.filename="Angle {}".format(theta) istack2.insert(0,i) class ImageStack2Test(unittest.TestCase): def setUp(self): self.td = ImageFolder(testdir, pattern='*.png') self.ks = ImageStack(testdir) self.ks = ImageStack(self.td) #load in two ways self.assertTrue(len(self.ks)==len(os.listdir(testdir))) self.istack2=istack2.clone def test_ImageStack2(self):
def test_methods(self): b = np.arange(12).reshape(3, 4) ifi = ImageFile(b) ifi.asfloat(normalise=False, clip_negative=False) #convert in place self.assertTrue(ifi.image.dtype.kind == 'f') self.assertTrue(np.max(ifi) == 11.0) ifi.image == ifi.image * 5 ifi.rescale_intensity() self.assertTrue( np.allclose(ifi.image, np.linspace(0, 1, 12).reshape(3, 4))) ifi.crop(0, 3, 0, None) self.assertTrue(ifi.shape == ( 3, 3)) #check crop is forced to overwrite ifi despite shape change datadir = path.join(__home__, "..", "sample-data") image = ImageFile(path.join(datadir, "kermit.png")) i2 = image.clone.box(5, _=True) self.assertEqual(i2.shape, (469, 349), "Failed to trim box by integer") i2 = image.clone.box(0.25, _=True) self.assertEqual(i2.shape, (269, 269), "Failed to trim box by float") i2 = image.clone.box([0.1, 0.2, 0.05, 0.1], _=True) self.assertEqual(i2.shape, (24, 36), "Failed to trim box by sequence of floats") self.assertAlmostEqual(image.aspect, 0.7494780793, places=6, msg="Aspect ratio failed") self.assertEqual(image.centre, (239.5, 179.5), "Failed to read image.centre") i2 = image.CW self.assertEqual(i2.shape, (359, 479), "Failed to rotate clockwise") i3 = i2.CCW self.assertEqual(i3.shape, (479, 359), "Failed to rotate counter-clockwise") i2 = image.clone self.assertAlmostEqual((i2 - 127).mean(), 39086.4687283, places=2, msg="Subtract integer failed.") try: i2 - "Gobble" except TypeError: pass else: self.AssertTrue( False, "Subtraction of string didn't raise not implemented") attrs = [x for x in dir(image) if not x.startswith("_")] expected = 881 self.assertEqual( len(attrs), expected, "Length of ImageFile dir failed. {}:{}".format( expected, len(attrs))) self.assertTrue(image._repr_png_().startswith(b'\x89PNG\r\n'), "Failed to do ImageFile png representation")
def setUp(self): self.a = np.linspace(0, 5, 12).reshape(3, 4) self.ifi = ImageFile(self.a) self.imgFile = ImageFile( os.path.join(thisdir, 'coretestdata/im1_annotated.png'))
def test_draw(self): i = ImageFile(np.zeros((200, 200))) attrs = [x for x in dir(i.draw) if not x.startswith("_")] counts = {(2, 7): 19, (3, 5): 19} expected = counts.get(version_info[0:2], 20) self.assertEqual(len(attrs), expected, "Directory of DrawProxy failed")
def test_mask(self): i = np.ones((200, 200), dtype="uint8") * np.linspace( 1, 200, 200).astype("uint8") i = ImageFile(i) self.i = i i.mask.draw.rectangle(100, 50, 100, 100) self.assertAlmostEqual(i.mean(), 117.1666666666666, msg="Mean after masked rectangle failed") i.mask.invert() self.assertAlmostEqual( i.mean(), 50.5, msg="Mean after inverted masked rectangle failed") i.mask.clear() self.assertAlmostEqual(i.mean(), 100.5, msg="Mean after clearing mask failed") i.mask.draw.square(100, 50, 100) self.assertAlmostEqual(i.mean(), 117.1666666666666, msg="Mean after masked rectangle faile") i.mask.clear() i.mask.draw.annulus(100, 50, 35, 25) self.assertAlmostEqual(i.mean(), 102.96850393700, msg="Mean after annular block mask failed") i.mask = False i.mask.draw.annulus(100, 50, 25, 35) self.assertAlmostEqual(i.mean(), 51.0, msg="Mean after annular pass mask failed") i.mask[:, :] = False self.assertFalse(np.any(i.mask), "Setting Mask by index failed") i.mask = -i.mask self.assertTrue(np.all(i.mask), "Setting Mask by index failed") i.mask = ~i.mask self.assertFalse(np.any(i.mask), "Setting Mask by index failed") i.mask.draw.circle(100, 100, 20) st = repr(i.mask) self.assertEqual(st.count("X"), i.mask.sum(), "String representation of mask failed") self.assertTrue(np.all(i.mask.image == i.mask._mask), "Failed to access mak data by image attr") i.mask = False i2 = i.clone i.mask.draw.rectangle(100, 100, 100, 50, angle=np.pi / 2) i2.mask.draw.rectangle(100, 100, 50, 100) self.i2 = i2 self.assertTrue(np.all(i.mask.image == i2.mask.image), "Drawing rectange with angle failed") self.assertTrue(i.mask._repr_png_().startswith(b'\x89PNG\r\n'), "Failed to do mask png representation") i = ImageFile(np.zeros((100, 100))) i2 = i.clone i2.draw.circle(50, 50, 25) i.mask = i2 self.assertEqual(i.mask.sum(), i2.sum(), "Setting mask from ImageFile Failed") i2.mask = i.mask self.assertTrue(np.all(i.mask.image == i2.mask.image), "Failed to set mask by mask proxy") i = ImageFile(np.ones((100, 100))) i.mask.draw.square(50, 50, 10) i.mask.rotate(angle=np.pi / 4) i.mask.invert() i2 = ImageFile(np.zeros((100, 100))) i2.draw.square(50, 50, 10, angle=np.pi / 4) self.assertAlmostEqual(i.sum(), i2.sum(), delta=1.5, msg="Check on rotated mask failed !")