def setUp(self): self.median = Stack('median', 3) self.img1 = Image(img=np.zeros((3, 3, 3), dtype=np.float)) self.img2 = Image(img=np.zeros((3, 3, 3), dtype=np.float)+1) self.img3 = Image(img=np.zeros((3, 3, 3), dtype=np.float)+2) self.img4 = Image(img=np.zeros((3, 3, 3), dtype=np.float)+7)
def add_image(self, img): '''Add a frame to the stack. :param img: image to be added to stack :type img: halostack.image.Image ''' if not isinstance(img, Image): LOGGER.debug("Converting %s to Image object.", img) img = Image(img=img, nprocs=self.nprocs) LOGGER.debug("Adding image to %s stack.", self.mode) self._update_stack(img)
def _calculate_median(self): '''Calculate the median of the stack and return the resulting image with the original dtype. ''' ch_r = np.median(self.stack['R'], 2) ch_g = np.median(self.stack['G'], 2) ch_b = np.median(self.stack['B'], 2) shape = ch_r.shape[:2] img = np.empty((shape[0], shape[1], 3), dtype=self.stack['R'].dtype) img[:, :, 0] = ch_r.astype(self.stack['R'].dtype) img[:, :, 1] = ch_g.astype(self.stack['G'].dtype) img[:, :, 2] = ch_b.astype(self.stack['B'].dtype) return Image(img=img, nprocs=self.nprocs)
def setUp(self): self.img1 = Image(img=np.zeros((3, 3))) self.img2 = Image(img=np.ones((3, 3))) self.img3 = Image(img=2*np.ones((3, 3))) self.img4 = Image(img=3*np.ones((3, 3))) rgb_arr = np.ones((3, 3, 3)) rgb_arr[:, :, 1] += 1 rgb_arr[:, :, 2] += 2 self.img_rgb = Image(img=rgb_arr) self.img_rand8 = Image(img=np.random.randint(2**8-1, size=(3, 3, 3))) self.img_rand16 = Image(img=np.random.randint(2**16-1, size=(3, 3, 3))) self.img_rand_big1 = Image(img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_big2 = Image(img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_neg = Image(img=np.random.randint(-100, 100, size=(3, 3, 3)))
def _calculate_sigma(self): '''Calculate the sigma-reject average of the stack and return the result as Image(dtype=uint16). ''' shape = self.stack['R'].shape img = np.zeros((shape[0], shape[1], 3), dtype=self.stack['R'].dtype) try: kappa = self._kwargs["kappa"] except (TypeError, KeyError): kappa = 2.0 try: max_iters = self._kwargs["max_iters"] except (TypeError, KeyError): max_iters = max(1, self._num / 8) LOGGER.info("Calculating Sigma-Kappa average.") img[:, :, 0] = _sigma_worker(self.stack['R'], kappa, max_iters) img[:, :, 1] = _sigma_worker(self.stack['G'], kappa, max_iters) img[:, :, 2] = _sigma_worker(self.stack['B'], kappa, max_iters) return Image(img=img, nprocs=self.nprocs)
def halostack_cli(args): '''Commandline interface.''' images = args['fname_in'] stacks = [] for stack in args['stacks']: stacks.append(Stack(stack, len(images), nprocs=args['nprocs'])) base_img_fname = images[0] base_img = Image(fname=base_img_fname, nprocs=args['nprocs']) LOGGER.debug("Using %s as base image.", base_img.fname) images.remove(images[0]) if not args['no_alignment'] and len(images) > 1: view_img = base_img.luminance() if isinstance(args['view_gamma'], float): view_img.enhance({'gamma': args['view_gamma']}) print "\nClick tight area (two opposite corners) for "\ "reference location.\n" args['focus_reference'] = get_two_points(view_img) LOGGER.debug("Reference area: (%d, %d) with radius %d.", args['focus_reference'][0], args['focus_reference'][1], args['focus_reference'][2]) print "Click two corner points for the area where alignment "\ "reference will be in every image.\n" args['focus_area'] = get_two_points(view_img) LOGGER.debug("User-selected search area: (%d, %d) with radius %d.", args['focus_area'][0], args['focus_area'][1], args['focus_area'][2]) del view_img if not args['no_alignment'] and len(images) > 1: LOGGER.debug("Initializing alignment.") aligner = Align(base_img, cor_th=args['correlation_threshold'], nprocs=args['nprocs']) aligner.set_reference(args['focus_reference']) aligner.set_search_area(args['focus_area']) LOGGER.debug("Alignment initialized.") if args['save_prefix'] is not None: fname = intermediate_fname(args['save_prefix'], base_img_fname) base_img.save(fname) if len(args['enhance_images']) > 0: LOGGER.info("Preprocessing image.") base_img.enhance(args['enhance_images']) for stack in stacks: stack.add_image(base_img) # memory management del base_img for img_fname in images: # Read image img = Image(fname=img_fname, nprocs=args['nprocs']) if not args['no_alignment'] and len(images) > 1: # align image img = aligner.align(img) if img is None: LOGGER.warning("Skipping image.") continue if args['save_prefix'] is not None: fname = intermediate_fname(args['save_prefix'], img_fname) img.save(fname) if len(args['enhance_images']) > 0: LOGGER.info("Preprocessing image.") img.enhance(args['enhance_images']) for stack in stacks: stack.add_image(img) for i in range(len(stacks)): img = stacks[i].calculate() img.save(args['stack_fnames'][i], enhancements=args['enhance_stacks'])
class TestImage(unittest.TestCase): def setUp(self): self.img1 = Image(img=np.zeros((3, 3))) self.img2 = Image(img=np.ones((3, 3))) self.img3 = Image(img=2*np.ones((3, 3))) self.img4 = Image(img=3*np.ones((3, 3))) rgb_arr = np.ones((3, 3, 3)) rgb_arr[:, :, 1] += 1 rgb_arr[:, :, 2] += 2 self.img_rgb = Image(img=rgb_arr) self.img_rand8 = Image(img=np.random.randint(2**8-1, size=(3, 3, 3))) self.img_rand16 = Image(img=np.random.randint(2**16-1, size=(3, 3, 3))) self.img_rand_big1 = Image(img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_big2 = Image(img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_neg = Image(img=np.random.randint(-100, 100, size=(3, 3, 3))) def test_add(self): result = self.img1 + self.img2 correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_radd(self): result = 2 + self.img1 correct_result = 2 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_sub(self): result = self.img3 - self.img2 correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_mul(self): result = self.img3 * self.img4 correct_result = 6 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_rmul(self): result = 2 * self.img3 correct_result = 4 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_div(self): result = self.img3 / 2 correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) result = self.img4 / self.img3 correct_result = 1.5 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_abs(self): result = abs(-1 * self.img2) correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_lt(self): result = self.img1 < self.img2 correct_result = np.ones((3, 3)) < 2 self.assertItemsEqual(result, correct_result) def test_le(self): result = self.img1 <= self.img2 correct_result = np.ones((3, 3)) < 2 self.assertItemsEqual(result, correct_result) def test_gt(self): result = self.img1 > self.img2 correct_result = np.ones((3, 3)) > 2 self.assertItemsEqual(result, correct_result) def test_ge(self): result = self.img1 >= self.img2 correct_result = np.ones((3, 3)) >= 2 self.assertItemsEqual(result, correct_result) def test_eq(self): result = self.img1 == self.img1 correct_result = np.ones((3, 3)) == 1 self.assertItemsEqual(result, correct_result) def test_getitem(self): result = self.img1[0, 0] correct_result = 0 self.assertEqual(result, correct_result) def test_setitem(self): self.img1[0, 0] = 1 result = self.img1[0, 0] correct_result = 1 self.assertEqual(result, correct_result) def test_min(self): result = self.img1.min() correct_result = 0 self.assertEqual(result, correct_result) def test_max(self): self.img1[0, 0] = 1 result = self.img1.max() correct_result = 1 self.assertEqual(result, correct_result) def test_luminance(self): # B&W image result = self.img2.luminance() self.assertItemsEqual(self.img2.img, result.img) # RGB image result = self.img_rgb.luminance() self.assertItemsEqual(self.img3.img, result.img) def test_channel_differences(self): # B-R img = 1*self.img_rgb img._blue_red_subtract(1) self.assertItemsEqual(self.img3.img, img.img) img = 1*self.img_rgb img._green_red_subtract(2) self.assertItemsEqual(self.img4.img, img.img) img = 1*self.img_rgb img._green_red_subtract(None) self.assertItemsEqual(self.img4.img, img.img) def test_rgb_subtract(self): img = 1*self.img_rgb img._rgb_subtract(None) correct_result = np.zeros((3, 3, 3)) correct_result[:, :, 1] = 1 correct_result[:, :, 2] = 2 self.assertItemsEqual(correct_result, img.img) def test_scale_values(self): self.img_rand8.img = _scale(self.img_rand8.img, 8) self.assertTrue(self.img_rand8.img.dtype == 'uint8') self.assertTrue(self.img_rand8.min() == 0) self.assertTrue(self.img_rand8.max() == 255) self.img_rand16.img = _scale(self.img_rand16.img, 16) self.assertTrue(self.img_rand16.img.dtype == 'uint16') self.assertTrue(self.img_rand16.min() == 0) self.assertTrue(self.img_rand16.max() == 2**16-1) self.img_rand_big1.img = _scale(self.img_rand_big1.img, 8) self.assertTrue(self.img_rand_big1.img.dtype == 'uint8') self.assertTrue(self.img_rand_big1.min() == 0) self.assertTrue(self.img_rand_big1.max() == 255) self.img_rand_big2.img = _scale(self.img_rand_big2.img, 16) self.assertTrue(self.img_rand_big2.img.dtype == 'uint16') self.assertTrue(self.img_rand_big2.min() == 0) self.assertTrue(self.img_rand_big2.max() == 2**16-1) self.img_rand_neg.img = _scale(self.img_rand_neg.img, 8) self.assertTrue(self.img_rand_neg.min() >= 0) def assertItemsEqual(self, a, b): if isinstance(a, np.ndarray): self.assertTrue(np.all(a == b)) self.assertTrue(a.shape == b.shape) else: for i in range(len(a)): self.assertEqual(a[i], b[i]) self.assertEqual(len(a), len(b))
#!/usr/bin/env python from halostack.image import Image import sys import os # input file fname_in = sys.argv[1] # form the output filename head, tail = os.path.split(fname_in) tail = tail.split('.')[:-1] tail.append('png') tail = 'br_' + '.'.join(tail) out_fname = os.path.join(head, tail) # the actual halostack bit is only three lines # read image img = Image(fname=fname_in) # combined gradient removal and B-R img.enhance({'gradient': None, 'br': None}) # save the resulting image img.save(out_fname)
#!/usr/bin/env python from halostack.image import Image import sys import os # input file fname_in = sys.argv[1] # form the output filename head, tail = os.path.split(fname_in) tail = tail.split('.')[:-1] tail.append('png') tail = 'br_' + '.'.join(tail) out_fname = os.path.join(head, tail) # the actual halostack bit is only four lines # read image img = Image(fname=fname_in, nprocs=4) # change data type to 64-bit float img.set_dtype('float64') # combined gradient removal and B-R img.enhance({'gradient': None, 'br': None}) # save the resulting image img.save(out_fname)
def setUp(self): self.img1 = Image(img=np.zeros((3, 3))) self.img2 = Image(img=np.ones((3, 3))) self.img3 = Image(img=2 * np.ones((3, 3))) self.img4 = Image(img=3 * np.ones((3, 3))) rgb_arr = np.ones((3, 3, 3)) rgb_arr[:, :, 1] += 1 rgb_arr[:, :, 2] += 2 self.img_rgb = Image(img=rgb_arr) self.img_rand8 = Image(img=np.random.randint(2**8 - 1, size=(3, 3, 3))) self.img_rand16 = Image( img=np.random.randint(2**16 - 1, size=(3, 3, 3))) self.img_rand_big1 = Image( img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_big2 = Image( img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_neg = Image( img=np.random.randint(-100, 100, size=(3, 3, 3)))
class TestImage(unittest.TestCase): def setUp(self): self.img1 = Image(img=np.zeros((3, 3))) self.img2 = Image(img=np.ones((3, 3))) self.img3 = Image(img=2 * np.ones((3, 3))) self.img4 = Image(img=3 * np.ones((3, 3))) rgb_arr = np.ones((3, 3, 3)) rgb_arr[:, :, 1] += 1 rgb_arr[:, :, 2] += 2 self.img_rgb = Image(img=rgb_arr) self.img_rand8 = Image(img=np.random.randint(2**8 - 1, size=(3, 3, 3))) self.img_rand16 = Image( img=np.random.randint(2**16 - 1, size=(3, 3, 3))) self.img_rand_big1 = Image( img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_big2 = Image( img=np.random.randint(30 * (2**16 - 1), size=(3, 3, 3))) self.img_rand_neg = Image( img=np.random.randint(-100, 100, size=(3, 3, 3))) def test_add(self): result = self.img1 + self.img2 correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_radd(self): result = 2 + self.img1 correct_result = 2 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_sub(self): result = self.img3 - self.img2 correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_mul(self): result = self.img3 * self.img4 correct_result = 6 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_rmul(self): result = 2 * self.img3 correct_result = 4 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_div(self): result = self.img3 / 2 correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) result = self.img4 / self.img3 correct_result = 1.5 * np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_abs(self): result = abs(-1 * self.img2) correct_result = np.ones((3, 3)) self.assertItemsEqual(result.img, correct_result) def test_lt(self): result = self.img1 < self.img2 correct_result = np.ones((3, 3)) < 2 self.assertItemsEqual(result, correct_result) def test_le(self): result = self.img1 <= self.img2 correct_result = np.ones((3, 3)) < 2 self.assertItemsEqual(result, correct_result) def test_gt(self): result = self.img1 > self.img2 correct_result = np.ones((3, 3)) > 2 self.assertItemsEqual(result, correct_result) def test_ge(self): result = self.img1 >= self.img2 correct_result = np.ones((3, 3)) >= 2 self.assertItemsEqual(result, correct_result) def test_eq(self): result = self.img1 == self.img1 correct_result = np.ones((3, 3)) == 1 self.assertItemsEqual(result, correct_result) def test_getitem(self): result = self.img1[0, 0] correct_result = 0 self.assertEqual(result, correct_result) def test_setitem(self): self.img1[0, 0] = 1 result = self.img1[0, 0] correct_result = 1 self.assertEqual(result, correct_result) def test_min(self): result = self.img1.min() correct_result = 0 self.assertEqual(result, correct_result) def test_max(self): self.img1[0, 0] = 1 result = self.img1.max() correct_result = 1 self.assertEqual(result, correct_result) def test_luminance(self): # B&W image result = self.img2.luminance() self.assertItemsEqual(self.img2.img, result.img) # RGB image result = self.img_rgb.luminance() self.assertItemsEqual(self.img3.img, result.img) def test_channel_differences(self): # B-R img = 1 * self.img_rgb img._blue_red_subtract(1) self.assertItemsEqual(self.img3.img, img.img) img = 1 * self.img_rgb img._green_red_subtract(2) self.assertItemsEqual(self.img4.img, img.img) img = 1 * self.img_rgb img._green_red_subtract(None) self.assertItemsEqual(self.img4.img, img.img) def test_rgb_subtract(self): img = 1 * self.img_rgb img._rgb_subtract(None) correct_result = np.zeros((3, 3, 3)) correct_result[:, :, 1] = 1 correct_result[:, :, 2] = 2 self.assertItemsEqual(correct_result, img.img) def test_scale_values(self): self.img_rand8.img = _scale(self.img_rand8.img, 8) self.assertTrue(self.img_rand8.img.dtype == 'uint8') self.assertTrue(self.img_rand8.min() == 0) self.assertTrue(self.img_rand8.max() == 255) self.img_rand16.img = _scale(self.img_rand16.img, 16) self.assertTrue(self.img_rand16.img.dtype == 'uint16') self.assertTrue(self.img_rand16.min() == 0) self.assertTrue(self.img_rand16.max() == 2**16 - 1) self.img_rand_big1.img = _scale(self.img_rand_big1.img, 8) self.assertTrue(self.img_rand_big1.img.dtype == 'uint8') self.assertTrue(self.img_rand_big1.min() == 0) self.assertTrue(self.img_rand_big1.max() == 255) self.img_rand_big2.img = _scale(self.img_rand_big2.img, 16) self.assertTrue(self.img_rand_big2.img.dtype == 'uint16') self.assertTrue(self.img_rand_big2.min() == 0) self.assertTrue(self.img_rand_big2.max() == 2**16 - 1) self.img_rand_neg.img = _scale(self.img_rand_neg.img, 8) self.assertTrue(self.img_rand_neg.min() >= 0) def assertItemsEqual(self, a, b): if isinstance(a, np.ndarray): self.assertTrue(np.all(a == b)) self.assertTrue(a.shape == b.shape) else: for i in range(len(a)): self.assertEqual(a[i], b[i]) self.assertEqual(len(a), len(b))