コード例 #1
0
    def test_register_nddata(self):
        from astropy.nddata import NDData
        from skimage.transform import SimilarityTransform

        transf = SimilarityTransform(rotation=np.pi / 2.0, translation=(1, 0))

        nd = NDData([[0.0, 1.0], [2.0, 3.0]],
                    mask=[[True, False], [False, False]])
        registered_img, footp = aa.apply_transform(transf,
                                                   nd,
                                                   nd,
                                                   propagate_mask=True)
        err = np.linalg.norm(registered_img -
                             np.array([[2.0, 0.0], [3.0, 1.0]]))
        self.assertLess(err, 1e-6)
        err_mask = footp == np.array([[False, True], [False, False]])
        self.assertTrue(all(err_mask.flatten()))

        # Test now if there is no assigned mask during creation
        nd = NDData([[0.0, 1.0], [2.0, 3.0]])
        registered_img, footp = aa.apply_transform(transf,
                                                   nd,
                                                   nd,
                                                   propagate_mask=True)
        err = np.linalg.norm(registered_img -
                             np.array([[2.0, 0.0], [3.0, 1.0]]))
        self.assertLess(err, 1e-6)
        err_mask = footp == np.array([[False, False], [False, False]])
        self.assertTrue(all(err_mask.flatten()))
コード例 #2
0
def sources(sourcelist, imagelist=None, reference=None):
    """
    Takes a NxM list of sources, where N is the number of images and M is the
        number of sources in each image
    Operates in-place.
    Arguments:
        catalogs -- list of sources
    Keyword Arguments:
        imagelist -- An optional list of images which map 1:1 to sources
            if provided, the calculated transformations will be applied to
            images
        reference -- A set of points to use as a reference; default 0th index
    """
    # FIXME this is really slow, move to Cython or do some numpy magic with
    # Sources class
    aligned = []

    if reference is None:
        reference = sourcelist[0]
    if imagelist is None:
        imagelist = [None] * len(sourceslist)

    npref = [[r.x, r.y] for r in reference]
    for cat, im in zip(sourcelist, imagelist):
        npc = [[c.x, c.y] for c in cat]
        T, _ = astroalign.find_transform(npc, npref)
        if im is not None:
            astroalign.apply_transform(T, im, im)
        for source in cat:
            source.transform(T)
コード例 #3
0
    def test_register_ccddata(self):
        from ccdproc import CCDData
        from skimage.transform import SimilarityTransform

        transf = SimilarityTransform(rotation=np.pi / 2.0, translation=(1, 0))

        cd = CCDData(
            [[0.0, 1.0], [2.0, 3.0]],
            mask=[[True, False], [False, False]],
            unit="adu",
        )
        registered_img, footp = aa.apply_transform(transf,
                                                   cd,
                                                   cd,
                                                   propagate_mask=True)
        err = np.linalg.norm(registered_img -
                             np.array([[2.0, 0.0], [3.0, 1.0]]))
        self.assertLess(err, 1e-6)
        err_mask = footp == np.array([[False, True], [False, False]])
        self.assertTrue(all(err_mask.flatten()))

        cd = CCDData([[0.0, 1.0], [2.0, 3.0]], unit="adu")
        registered_img, footp = aa.apply_transform(transf,
                                                   cd,
                                                   cd,
                                                   propagate_mask=True)
        err = np.linalg.norm(registered_img -
                             np.array([[2.0, 0.0], [3.0, 1.0]]))
        self.assertLess(err, 1e-6)
        err_mask = footp == np.array([[False, False], [False, False]])
        self.assertTrue(all(err_mask.flatten()))
コード例 #4
0
    def test_register_npma(self):
        from skimage.transform import SimilarityTransform

        transf = SimilarityTransform(rotation=np.pi / 2.0, translation=(1, 0))
        nparr = np.array([[0.0, 1.0], [2.0, 3.0]])
        mask = [[True, False], [False, False]]

        ma = np.ma.array(nparr, mask=mask)
        registered_img, footp = aa.apply_transform(transf,
                                                   ma,
                                                   ma,
                                                   propagate_mask=True)
        err = np.linalg.norm(registered_img -
                             np.array([[2.0, 0.0], [3.0, 1.0]]))
        self.assertLess(err, 1e-6)
        err_mask = footp == np.array([[False, True], [False, False]])
        self.assertTrue(all(err_mask.flatten()))

        ma = np.ma.array(nparr)
        registered_img, footp = aa.apply_transform(transf,
                                                   ma,
                                                   ma,
                                                   propagate_mask=True)
        err = np.linalg.norm(registered_img -
                             np.array([[2.0, 0.0], [3.0, 1.0]]))
        self.assertLess(err, 1e-6)
        err_mask = footp == np.array([[False, False], [False, False]])
        self.assertTrue(all(err_mask.flatten()))
コード例 #5
0
def hdu_shift_images(hdu_list,
                     method='fft',
                     register_method='asterism',
                     footprint=False,
                     logger=logger):
    """Calculate and apply shifts in a set of ccddata images.

    The function process the list inplace. Original data altered.

    methods:
        - "asterism" : align images using asterism matching (astroalign)
        - "chi2" : align images using chi2 minimization (image_registration)
        - "fft" : align images using fourier transform correlation (skimage)
    """
    if method == "asterism":
        logger.info("Registering images with astroalign.")
        if astroalign is None:
            raise RuntimeError("astroaling module not available.")
        im0 = hdu_list[0].data
        for i in hdu_list[1:]:
            transf, _ = astroalign.find_transform(i.data, im0)
            i.data = astroalign.apply_transform(transf, i.data, im0)
            if footprint:
                i.footprint = astroalign.apply_transform(
                    transf, np.ones(i.data.shape, dtype=bool), im0)
            # s_method = 'similarity_transform'
    else:
        if method == 'chi2':
            shifts = create_chi2_shift_list([ccd.data for ccd in hdu_list])
        else:
            shifts = create_fft_shift_list([ccd.data for ccd in hdu_list])
        logger.info(f"Aligning CCDData with shifts: {shifts}")
        for ccd, shift in zip(hdu_list, shifts):
            # if method == 'fft':
            #     s_method = method
            # else:
            #     s_method = 'simple'
            # ccd.data = apply_shift(ccd.data, shift, method=s_method,
            #                        logger=logger)
            #     s_method = 'simple'
            ccd.data, ccd.masks = apply_shift(ccd.data, shift, logger=logger)
            sh_string = [str(i) for i in shift]
            ccd.header['hierarch astropop register_shift'] = ",".join(
                sh_string)
            # if footprint:
            #     ccd.footprint = apply_shift(np.ones_like(ccd.data, dtype=bool),
            #                                 shift, method='simple',
            #                                 logger=logger)
            if footprint:
                [], [], ccd.footprint = apply_shift(np.ones_like(ccd.data,
                                                                 dtype=bool),
                                                    shift,
                                                    logger=logger)
    for i in hdu_list:
        i.header['hierarch astropop registered'] = True
        # i.header['hierarch astropop register_method'] = method
        # i.header['hierarch astropop transform_method'] = s_method

    return hdu_list
コード例 #6
0
    def _align(self, img: Image) -> Image:
        reference = self.db.get_stacked_image(str(img.key))

        if reference is None:
            logging.info(f"no reference found for {img.key}")
            return img

        assert img.data.dtype == np.float32 and img.data.min() >= 0.0 and img.data.max() <= 1.0, f"{img.data.dtype} {img.data.max()} {img.data.min()}"
        assert reference.data.dtype == np.float32 and reference.data.min() >= 0.0 and reference.data.max() <= 1.0, f"{reference.data.dtype} {reference.data.max()} {reference.data.min()}"
        assert reference.data.ndim == img.data.ndim, f"{reference.data.ndim} {img.data.ndim}"
        assert reference.data.shape == img.data.shape, f"{reference.data.shape} {img.data.shape}"

        with Timer(f"aligning image for {img.key}"):
            if img.data.ndim == 2:
                registered, footprint = aa.register(img.data, reference.data, fill_value=0.0)
                img.data = registered
            elif img.data.ndim == 3:
                transform, _ = aa.find_transform(img.data[0], reference.data[0])

                for i in range(3):
                    transformed, _ = aa.apply_transform(transform, img.data[i], reference.data[i], fill_value=0.0)
                    img.data[i] = transformed
            else:
                raise Exception(f"invalid image dimensions {img.data.ndim}")

        assert img.data.dtype == np.float32 and img.data.min() >= 0.0 and img.data.max() <= 1.0, f"{img.data.dtype} {img.data.max()} {img.data.min()}"

        return img
コード例 #7
0
def stack(files, refimage):

    y, x = refimage.shape[-2], refimage.shape[-1]

    #creating empty arrays to hold each of RGB channels stacks
    stacksR = np.zeros((y, x, len(files)))
    stacksG = np.zeros((y, x, len(files)))
    stacksB = np.zeros((y, x, len(files)))

    rawHDU = fits.open(files[0])
    rawHEADER = rawHDU[0].header

    for i in range(len(files)):

        rawDATA = get_img(files[i])  #Image part of the file

        try:
            p = align(rawDATA[0], refimage)  #getting transformation
            rawDATAred = aa.apply_transform(p, rawDATA[0], refimage)
            rawDATAgrn = aa.apply_transform(p, rawDATA[1], refimage)
            rawDATAblu = aa.apply_transform(p, rawDATA[2], refimage)

            stacksR[:, :, i] = rawDATAred
            stacksG[:, :, i] = rawDATAgrn
            stacksB[:, :, i] = rawDATAblu

        except:
            print('oops file %s didnt meet alignment criteria' % files[i])
            files.remove(files[i])
            continue

    reds = np.median(stacksR, axis=2)
    grns = np.median(stacksG, axis=2)
    blue = np.median(stacksB, axis=2)

    procDATA = np.array([reds, grns, blue])
    procHDU = fits.PrimaryHDU(procDATA)  #new file, processed
    procHDU.header = rawHEADER  #replacing header

    #specify your filename
    procHDU.writeto('stacked.fits', overwrite=True)
コード例 #8
0
def align_image(image_name_1, image_name_2, new_file_name):
    
    
    File_List = [image_name_1, image_name_2]
    
    with fits.open(f'RAW_DATA/{File_List[0]}') as image_hdu_1:
    
        Data_1 = image_hdu_1[0].data
        image_hdu_1.close()
        
        
    with fits.open(f'RAW_DATA/{File_List[1]}') as image_hdu_2:
    
        Data_2 = image_hdu_2[0].data  # Creating a numpy array of the exposure
        image_hdu_2.close()

    
    Image_Data = [Data_1, Data_2]
    
    transf, (source_list, target_list) = aa.find_transform(Image_Data[0], Image_Data[1])
    
    Aligned_Image_Data, footprint = aa.apply_transform(transf, Image_Data[0], Image_Data[1]) # Aligning 


    plt.style.use(astropy_mpl_style)
    Norm = ImageNormalize(stretch = SqrtStretch())

    plt.figure(1)
    plt.imshow(Image_Data[0], cmap = 'gray', interpolation = 'bicubic', norm = Norm, vmin = 700, vmax = 800)
    plt.colorbar()

    plt.figure(2)
    plt.imshow(Image_Data[1], cmap = 'gray', interpolation = 'bicubic', norm = Norm)
    plt.colorbar()

    plt.figure(3)
    plt.imshow(Aligned_Image_Data, cmap = 'gray', interpolation = 'bicubic', norm = Norm)
    plt.colorbar()
    
    
    with fits.open(f'RAW_DATA/{File_List[0]}', mode = 'update') as image_hdu_3:
    
        image_hdu_3[0].data = Aligned_Image_Data
        image_hdu_3.flush()
        image_hdu_3.writeto(f'AlIGNED/{new_file_name}', overwrite = True)  # Writing to a new fits file
    

    return 
コード例 #9
0
    def check_if_register_ok(self, numstars):
        """Helper function to test register with common test code
        for 3, 4, 5, and 6 stars"""
        from skimage.transform import estimate_transform

        if numstars > 6:
            raise NotImplementedError

        # x and y of stars in the ref frame (int's)
        self.star_refx = np.array([100, 120, 400, 400, 200, 200])[:numstars]
        self.star_refy = np.array([150, 200, 200, 320, 210, 350])[:numstars]
        self.num_stars = numstars
        # Fluxes of stars
        self.star_f = np.array(numstars * [700.0])

        (
            self.image,
            self.image_ref,
            self.star_ref_pos,
            self.star_new_pos,
        ) = simulate_image_pair(
            shape=(self.h, self.w),
            translation=(self.x_offset, self.y_offset),
            rot_angle_deg=50.0,
            noise_level=50,
            num_stars=self.num_stars,
            star_refx=self.star_refx,
            star_refy=self.star_refy,
            star_flux=self.star_f,
        )

        aligned, footprint = aa.register(self.image_ref, self.image)

        source = self.star_ref_pos
        dest = self.star_new_pos.copy()
        t_true = estimate_transform("similarity", source, dest)
        aligned_true, fp = aa.apply_transform(t_true, self.image_ref,
                                              self.image)

        err = np.linalg.norm((aligned_true - aligned)[fp], 1) / np.linalg.norm(
            (aligned_true)[fp], 1)
        self.assertLess(err, 1e-1)
コード例 #10
0
    def _apply_single_channel_transformation(image,
                                             reference,
                                             transformation,
                                             results_dict,
                                             channel=None):
        """
        apply a transformation on a specific channel (RGB) of a color image, or whole data of a b&w image.

        :param image: the image to apply transformation to
        :type image: Image

        :param reference: the align reference image
        :type reference: Image

        :param transformation: the transformation to apply
        :type transformation: skimage.transform._geometric.SimilarityTransform

        :param results_dict: the dict into which transformation result is to be stored. dict key is the channel number for a
               color image, or 0 for a b&w image
        :type results_dict: dict

        :param channel: the 0 indexed number of the color channel to process (0=red, 1=green, 2=blue)
        :type channel: int
        """

        if channel is not None:
            target_index = channel
            source_data = image.data[channel]
            reference_data = reference.data[channel]
        else:
            target_index = 0
            source_data = image.data
            reference_data = reference.data

        results_dict[target_index] = np.float32(
            al.apply_transform(transformation, source_data, reference_data))
コード例 #11
0
def main(ref_path, new_path, objname):
    # alineo las imagenes
    refdata = fits.getdata(os.path.join(STACK_PATH, ref_path))[250:-250,
                                                               250:-250]
    newdata = fits.getdata(os.path.join(STACK_PATH, new_path))[250:-250,
                                                               250:-250]

    try:
        trf, _ = aa.find_transform(newdata.astype('<f8'),
                                   refdata.astype('<f8'))
        new_aligned = aa.apply_transform(t, newdata.astype('<f8'),
                                         refdata.astype('<f8'))
        from skimage.transform import warp
        init_mask = np.zeros_like(newdata)

        outside_px_mask = warp(init_mask,
                               inverse_map=trf.inverse,
                               output_shape=refdata.shape,
                               order=3,
                               mode='constant',
                               cval=1.,
                               clip=False,
                               preserve_range=False)
        useful = np.where(outside_px_mask == 0)
        max_x = np.max(useful[0])
        min_x = np.min(useful[0])
        max_y = np.max(useful[1])
        min_y = np.min(useful[1])

        new_cropped = new_aligned[min_x:max_x, min_y:max_y]
        new_mask = outside_px_mask[min_x:max_x, min_y:max_y]
        ref_cropped = refdata[min_x:max_x, min_y:max_y]

    except:
        try:
            aa.MIN_MATCHES_FRACTION = 0.01
            ref = si.SingleImage(refdata.astype('<f8'))
            new = si.SingleImage(newdata.astype('<f8'))

            ref.best_sources.sort(order='flux')
            new.best_sources.sort(order='flux')

            #~ import ipdb; ipdb.set_trace()

            rs = np.empty((len(ref.best_sources), 2))
            j = 0
            for x, y in ref.best_sources[['x', 'y']]:
                rs[j] = x, y
                j += 1

            ns = np.empty((len(new.best_sources), 2))
            j = 0
            for x, y in new.best_sources[['x', 'y']]:
                ns[j] = x, y
                j += 1

            if abs(len(ns) - len(rs)) > 50:
                max_l = np.max([len(ns), len(rs)])
                ns = ns[:max_l]
                rs = rs[:max_l]

            trf, _ = aa.find_transform(ns, rs)
            new_aligned = aa.apply_transform(trf, newdata.astype('<f8'),
                                             refdata.astype('<f8'))
            from skimage.transform import warp
            init_mask = np.zeros_like(newdata)

            outside_px_mask = warp(init_mask,
                                   inverse_map=trf.inverse,
                                   output_shape=refdata.shape,
                                   order=3,
                                   mode='constant',
                                   cval=1.,
                                   clip=False,
                                   preserve_range=False)
            useful = np.where(outside_px_mask == 0)
            max_x = np.max(useful[0])
            min_x = np.min(useful[0])
            max_y = np.max(useful[1])
            min_y = np.min(useful[1])

            new_cropped = new_aligned[min_x:max_x, min_y:max_y]
            new_mask = outside_px_mask[min_x:max_x, min_y:max_y]
            ref_cropped = refdata[min_x:max_x, min_y:max_y]
        except:
            #~ import ipdb; ipdb.set_trace()
            raise
    # las copio al lugar designado en la pipeline
    ref_h = fits.getheader(os.path.join(STACK_PATH, ref_path))
    fits.writeto(data=ref_cropped.astype('<f4'),
                 header=ref_h,
                 filename=REFERENCE_IMAGE,
                 overwrite=True)

    new_h = fits.getheader(os.path.join(STACK_PATH, new_path))
    fits.writeto(data=new_cropped.astype('<f4'),
                 header=new_h,
                 filename=NEW_IMAGE,
                 overwrite=True)

    # creo un file con los detalles
    meta = {}
    meta['object'] = objname
    meta['orig_ref_path'] = ref_path
    meta['orig_new_path'] = new_path

    with open(DETAILS_FILE, 'w') as fp:
        json.dump(meta, fp)

    return 0
コード例 #12
0
        dst = np.array([xc0, yc0]).T
        tform = aa.estimate_transform('affine', src, dst)
        print("# ----- Parameters of the transformation ----- #")
        print(f"Rotation: {tform.rotation*180.0/np.pi:.2f} degrees")
        print("Scale factor: ({:.2f}, {:.2f})".format(*tform.scale))
        print("Translation: (x, y) = ({:.2f}, {:.2f})".format(
            *tform.translation))
        print(f"Tranformation matrix:\n{tform.params}")
        print("\n")

        if ((n_mch < ip.min_npoi) |
            (np.sqrt(np.sum(tform.translation**2.0)) > trans_tol)):
            print("Warning: please check this image visually: al" + wimg[i])
            os.system('cp -rpv ' + wimg[i] + ' al' + wimg[i])
        else:
            aligned_image, footprint = aa.apply_transform(
                tform, s1.dat, s0.dat)
            fits.writeto('al' + wimg[i], aligned_image, s1.hdr, overwrite=True)
    else:
        os.system('cp -rpv ' + wimg[i] + ' al' + wimg[i])
        ysize, xsize = fits.getdata(wimg[i], ext=0).shape
    filt.append(wname.split('w')[1].split('_')[0])
filt = np.array(filt)
# Output: alw[FILTER]_[NUMBER].fits

# ----- Combining images  ----- #
ufilt, nfilt = np.unique(filt, return_counts=True)

for i in np.arange(len(ufilt)):
    print("Combining " + ufilt[i] + " band...")
    cdat = np.zeros((ysize, xsize))
    cexp = 0.
コード例 #13
0
image = fits.open("light_00001.fit")
rgb_ref = image[0].data
image.close()

plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
new_rvb = np.rollaxis((np.array(rgb_ref) / 65535.)**(1 / 3.), 0, 3)
test = ax.imshow(new_rvb)
plt.draw()
plt.pause(1)

for i in tqdm(nb_im_str):
    image = fits.open("light_" + str(i) + ".fit")
    rgb_new = image[0].data
    image.close()

    p, (pos_img, pos_img_rot) = al.find_transform(rgb_new[1], rgb_ref[1])
    rgb_align = []
    for j in tqdm(range(3)):
        rgb_align.append(
            al.apply_transform(p, rgb_new[j], rgb_ref[j]) + rgb_ref[j])
        rgb_align[j] = np.where(rgb_align[j] < 65535, rgb_align[j], 65535)
    rgb_ref = rgb_align
    new_rvb = np.rollaxis((np.array(rgb_ref) / 65535.)**(1 / 3.), 0, 3)
    test = ax.imshow(new_rvb)
    plt.draw()
    plt.pause(0.1)

plt.show()
コード例 #14
0
ファイル: stack.py プロジェクト: gnthibault/als
def stack_live(work_path, im_path, counter, ref=[], first_ref=[], save_im=False, align=True,
               stack_methode="Sum"):
    """
    function for process image, align and stack

    :param work_path: string, path of work folder
    :param im_path: string, path of process image
    :param ref: np.array, stack image (no for first image)
    :param first_ref: np.array, first image process, ref for alignement (no for first image)
    :param counter: int, number of image stacked
    :param save_im: bool, option for save image in fit
    :param align: bool, option for align image or not
    :param stack_methode: string, stack methode ("sum" or "mean")
    :return: image: np.array 3xMxN or MxN
             im_limit: int, bit limit (255 or 65535)
             im_mode: string, mode : "rgb" or "gray"

    TODO: Add dark possibility
    """

    # test image format ".fit" or ".fits" or other
    if im_path.rfind(".fit") != -1:
        if im_path[im_path.rfind(".fit"):] == ".fit":
            extension = ".fit"
        elif im_path[im_path.rfind(".fit"):] == ".fits":
            extension = ".fits"
        raw_im = False
    else:
        # Other format = raw camera format (cr2, ...)
        extension = im_path[im_path.rfind("."):]
        raw_im = True
    # remove extension of path
    name = im_path.replace(extension, '')
    # remove path, juste save image name
    name = name[name.rfind("/") + 1:]

    if not raw_im:
        # open new image
        new_fit = fits.open(im_path)
        new = new_fit[0].data
        # save header
        new_header = new_fit[0].header
        new_fit.close()
        # test data type
        im_limit, im_type = test_utype(new)
        # test rgb or gray
        new, im_mode = test_and_debayer_to_rgb(new_header, new)
    else:
        print("convert DSLR image ...")
        new = rawpy.imread(im_path).postprocess(gamma=(1, 1), no_auto_bright=True, output_bps=16)
        im_mode = "rgb"
        extension = ".fits"
        im_limit = 2. ** 16 - 1
        im_type = "uint16"
        new = np.rollaxis(new, 2, 0)

    # ____________________________________
    # specific part for no first image
    # choix rgb ou gray scale
    print("alignement and stacking...")

    # choix du mode (rgb or B&W)
    if im_mode == "rgb":
        if align:
            # alignement with green :
            p, __ = al.find_transform(new[1], first_ref[1])

        # stacking
        stack_image = []
        for j in tqdm(range(3)):
            if align:
                # align all color :
                align_image = al.apply_transform(p, new[j], ref[j])

            else:
                align_image = new[j]

            # chose stack methode
            # need convert to float32 for excess value
            if stack_methode == "Sum":
                stack = np.float32(align_image) + np.float32(ref[j])
            elif stack_methode == "Mean":
                stack = ((counter - 1) * np.float32(ref[j]) + np.float32(align_image)) / counter
            else:
                raise ValueError("Stack method is not support")
                
            # filter excess value > limit
            if im_type == 'uint8':
                stack_image.append(np.uint8(np.where(stack < 2 ** 8 - 1, stack, 2 ** 8 - 1)))
            elif im_type == 'uint16':
                stack_image.append(np.uint16(np.where(stack < 2 ** 16 - 1, stack, 2 ** 16 - 1)))
        del stack
        del new

    elif im_mode == "gray":
        if align:
            # alignement
            p, __ = al.find_transform(new, first_ref)
            align_image = al.apply_transform(p, new, ref)
            del p
        else:
            align_image = new

        del new

        # chose stack methode
        # need convert to float32 for excess value
        if stack_methode == "Sum":
            stack = np.float32(align_image) + np.float32(ref)
        elif stack_methode == "Mean":
            stack = ((counter - 1) * np.float32(ref) + np.float32(align_image)) / counter
        else:
            raise ValueError("Stack method is not support")

        # filter excess value > limit
        if im_type == 'uint8':
            stack_image = np.uint8(np.where(stack < 2 ** 8 - 1, stack, 2 ** 8 - 1))
        elif im_type == 'uint16':
            stack_image = np.uint16(np.where(stack < 2 ** 16 - 1, stack, 2 ** 16 - 1))
        del stack
        
    else:
        raise ValueError("Mode not support")

    image = np.array(stack_image)
    # _____________________________

    if save_im:
        # save stack image in fit
        red = fits.PrimaryHDU(data=image)
        red.writeto(work_path + "/" + "stack_image_" + name + extension)
        # delete image in memory
        del red

    return image, im_limit, im_mode
コード例 #15
0
image_7 = hdu_list_7[0].data
hdu_list_7.close()

#%% Find the image transformation
# The transformation is returned in the `p` object. The two objects `img_6_srcs`
# and `img_7_srcs` give the coordinates of the sources found by the
#`astroalign.find_transform()` fucntion.
p, (img_6_srcs, img_7_srcs) = aa.find_transform(image_6, image_7)

#%% Transform the `source` image
# Unfortunatly, in version 2.4 of `astroalign` we have to convert the image data
# type for our images to unsigned 16 bit integers (`uint16`) to make the
# transform function work properly. We do this using the image method
# `astype('uint16')`.
image_6_aligned, footprint = aa.apply_transform(p,
                                                image_6.astype('uint16'),
                                                image_7.astype('uint16'),
                                                fill_value=1000)

#%% Write the shifted image to a new FITS file
# Creating a new header for the file and add new keyword to the file that
# specifies how the image was aligned.
header_6_aligned = header_6
header_6_aligned['ALINGED'] = 'Aligned to stars07_p.fits'
header_6_aligned

fits.writeto('../images/stars06_aligned_example.fits',
             image_6_aligned,
             header_6_aligned,
             overwrite=True)
コード例 #16
0
def stack_live(work_path,
               new_image,
               ref_name,
               counter,
               save_im=False,
               align=True,
               stack_methode="Sum"):

    # test image format ".fit" or ".fits"
    if new_image.find(".fits") == -1:
        extension = ".fit"
    else:
        extension = ".fits"
    # remove extension
    name = new_image.replace(extension, '')
    # remove path
    name = name[name.rfind("/") + 1:]

    # open new image
    new_fit = fits.open(new_image)
    new = new_fit[0].data
    # save header
    new_header = new_fit[0].header
    new_fit.close()
    # test data type
    new_limit, new_type = test_utype(new)
    # test rgb or gray
    new, new_mode = test_and_debayer_to_rgb(new_header, new)

    # open ref image
    ref_fit = fits.open(work_path + "/" + ref_name)
    ref = ref_fit[0].data
    ref_fit.close()
    # test data type
    ref_limit, ref_type = test_utype(ref)

    if align:
        # open first ref image (for align)
        first_ref_fit = fits.open(work_path + "/" + "first_" + ref_name)
        first_ref = first_ref_fit[0].data
        first_ref_fit.close()

    # test rgb or gray
    if len(ref.shape) == 2:
        ref_mode = "gray"
    elif len(ref.shape) == 3:
        ref_mode = "rgb"
    else:
        raise ValueError("fit format not support")

    # format verification
    if ref_limit != new_limit:
        raise ValueError("ref image and new image is not same format")
    else:
        im_type = ref_type
    if ref_mode == new_mode:
        mode = ref_mode
    else:
        raise ValueError("ref image and new image is not same format")

    # choix rgb ou gray scale
    print("alignement and stacking...")
    if mode == "rgb":
        if align:
            # alignement
            p, __ = al.find_transform(new[1], first_ref[1])
        # stacking
        stack_image = []
        for j in tqdm(range(3)):
            if align:
                align_image = al.apply_transform(p, new[j], ref[j])
            else:
                align_image = new[j]

            if stack_methode == "Sum":
                stack = np.float32(align_image) + np.float32(ref[j])
            elif stack_methode == "Mean":
                stack = ((counter - 1) * np.float32(ref[j]) +
                         np.float32(align_image)) / counter

            if im_type == 'uint8':
                stack_image.append(
                    np.uint8(np.where(stack < 2**8 - 1, stack, 2**8 - 1)))
            elif im_type == 'uint16':
                stack_image.append(
                    np.uint16(np.where(stack < 2**16 - 1, stack, 2**16 - 1)))
            else:
                raise ValueError("Stack methode is not support")

    elif mode == "gray":
        if align:
            # alignement
            p, __ = al.find_transform(new, first_ref)
            align_image = al.apply_transform(p, new, ref)
        else:
            align_image = new

        # stacking
        if stack_methode == "Sum":
            stack = np.float32(align_image) + np.float32(ref)
        elif stack_methode == "Mean":
            stack = ((counter - 1) * np.float32(ref) +
                     np.float32(align_image)) / counter
        else:
            raise ValueError("Stack methode is not support")

        if im_type == 'uint8':
            stack_image = np.uint8(stack)
        elif im_type == 'uint16':
            stack_image = np.uint16(stack)

    else:
        raise ValueError("Mode not support")

    # save new stack ref image in fit
    os.remove(work_path + "/" + ref_name)
    red = fits.PrimaryHDU(data=stack_image)
    red.writeto(work_path + "/" + ref_name)
    if save_im:
        # save stack image in fit
        red = fits.PrimaryHDU(data=stack_image)
        red.writeto(work_path + "/stack_image_" + name + extension)

    # save stack image in tiff (print image)
    os.remove(work_path + "/stack_image.tiff")
    save_tiff(work_path, np.array(stack_image), mode=mode)

    return 1
コード例 #17
0
ファイル: flux_bench.py プロジェクト: gbrammer/astroalign
def benchmark(size=SIZE, stars=STARS, noise=NOISE, repeats=REPEATS, seed=None):
    # get image
    image = get_image(size, stars, noise, seed)
    imagedata = np.ascontiguousarray(image[0])

    # detect sources (we know where they are, actually)
    bkg = sep.Background(imagedata)
    thresh = 3. * bkg.globalrms
    sources = sep.extract(imagedata - bkg.back(), thresh)
    sources.sort(order='flux')

    # perform photometry
    flux, fluxerr, flag = sep.sum_circle(
        imagedata-bkg.back(), sources['x'],
        sources['y'], 3.0, err=bkg.globalrms, gain=1.0)

    dframes = []
    # transform it
    for i_trsf in range(repeats):
        dx, dy = np.random.randint(
            low=-1 * size / 32., high=size / 32., size=2)
        theta = (np.random.random()-0.5)*0.125*np.pi
        s = 0.85+np.random.random()*0.3
        trf = SimilarityTransform(
            translation=(dx, dy), rotation=theta, scale=s)

        target = np.zeros(shape=np.array(imagedata.shape) * 2)
        newimage = aa.apply_transform(trf, imagedata - bkg.back(), target)

        # perform photometry on new places
        src_coords = np.array([sources['x'], sources['y']]).T
        new_coords = trf(src_coords).T
        nflux, nfluxerr, nflag = sep.sum_circle(
            newimage[0], new_coords[0], new_coords[1], 3.0 * s,
            err=bkg.globalrms, gain=1.0)

        # compare fluxes
        good_flux = nflag == 0
        new_to_orig = nflux[good_flux]/flux[good_flux]

        # put everything in a pd dataframe
        df = pd.DataFrame()

        df["idx"] = np.array([i_trsf] * sum(good_flux))
        df["seed"] = np.array([seed] * sum(good_flux))
        df["repeats"] = np.array([repeats] * sum(good_flux))

        df['orig_x'] = sources['x'][good_flux]
        df['orig_y'] = sources['y'][good_flux]
        df['orig_flux'] = flux[good_flux]
        df['orig_fluxerr'] = fluxerr[good_flux]
        df['orig_flag'] = flag[good_flux]

        df['new_x'] = new_coords[0][good_flux]
        df['new_y'] = new_coords[1][good_flux]
        df['new_flux'] = nflux[good_flux]
        df['new_fluxerr'] = nfluxerr[good_flux]
        df['new_flag'] = nflag[good_flux]

        df['flux_ratio'] = new_to_orig

        df['trf_theta'] = theta
        df['trf_dx'] = dx
        df['trf_dy'] = dy
        df['trf_scale'] = s

        slp, intpt, r_val, p_val, std_err = stats.linregress(
            flux[good_flux], nflux[good_flux])
        df['stats_slope'] = slp
        df['stats_intpt'] = intpt
        df['flux_per_area_ratio'] = df['flux_ratio'] / (df['trf_scale'] ** 2)

        dframes.append(df)

    final_df = pd.concat(dframes)

    return final_df
コード例 #18
0
ファイル: starstack.py プロジェクト: MEDiCODEDEV/scripts
def register(*args):
    """Take several images of type numpy.ndarray
       and align (register) them relative to the first image.
    """

    # Multiple color layers? Use just the green layer for alignment.
    def singlelayer(img):
        if len(img.shape) == 3:
            return img[:, :, 1]
        return img

    img1 = singlelayer(args[0])
    img2 = singlelayer(args[1])

    # Register the two images
    img_aligned, footprint = astroalign.register(img1, img2)

    # Plot the results
    # plot_three(img1, img2, img_aligned)

    transf, (pos_img, pos_img_rot) = astroalign.find_transform(img1, img2)

    def print_stats():
        print("Rotation: %2d degrees" % (transf.rotation * 180.0 / np.pi))
        print("\nScale factor: %.2f" % transf.scale)
        print("\nTranslation: (x, y) = (%.2f, %.2f)" %
              tuple(transf.translation))
        print("\nTranformation matrix:\n", transf.params)
        print("\nPoint correspondence:")
        for (x1, y1), (x2, y2) in zip(pos_img, pos_img_rot):
            print("(%.2f, %.2f) in source --> (%.2f, %.2f) in target" %
                  (x1, y1, x2, y2))

    # print_stats()

    # Plot correspondences
    plot_three(img1,
               img2,
               img_aligned,
               pos_img=pos_img,
               pos_img_rot=pos_img_rot,
               transf=transf)

    # Align again using the transform.
    # Will use this to align the other channels after using one
    # channel to register the two images.
    # The documentation doesn't mention a footprint being part of the return,
    # but it is.
    realigned, footprint = astroalign.apply_transform(transf, img1, img2)

    # plot_three(img1, img2, realigned)

    newshape = args[1].shape
    if len(newshape) == 2:
        newshape = args[1].shape + (3, )

    # trying https://stackoverflow.com/a/10445502
    rgbArray = np.zeros(newshape, 'uint8')
    for i in range(newshape[-1]):
        rgbArray[..., i] = realigned
    img = Image.fromarray(rgbArray)

    outfile = '/tmp/out.jpg'
    img.save(outfile)
    print("Saved to", outfile)
コード例 #19
0
 #)
 #target_image_luma = cv.adaptiveThreshold(src=target_image_luma,
 #                                         maxValue=255,
 #                                         adaptiveMethod=cv.ADAPTIVE_THRESH_GAUSSIAN_C,
 #                                         thresholdType=cv.THRESH_BINARY,
 #                                         blockSize=11,
 #                                         C=2)
 cv.imwrite("{:03d}_target.tiff".format(counter), target_image_luma)
 try:
     transf, (source_list, target_list) = aa.find_transform(
         source=source_image_luma,
         target=target_image_luma,
         max_control_points=MAX_CONTROL_POINTS,
         detection_sigma=DETECTION_SIGMA,
         min_area=MIN_AREA)
     projection_0, footprint = aa.apply_transform(
         transf, source_image[:, :, 0], target_image[:, :, 0])
     projection_1, footprint = aa.apply_transform(
         transf, source_image[:, :, 1], target_image[:, :, 1])
     projection_2, footprint = aa.apply_transform(
         transf, source_image[:, :, 2], target_image[:, :, 2])
     projection_image = np.stack(
         [projection_0, projection_1, projection_2], axis=2)
     cv.imwrite("{:03d}.tiff".format(counter),
                projection_image.astype(np.uint8))
     accumulated_image += projection_image
     source_image = target_image
     counter += 1
     output_image = accumulated_image / counter
     print("Normalizing", end=' ', flush=True)
     output_image, max, min = normalize(output_image)
     print(max, min)
コード例 #20
0
ファイル: align.py プロジェクト: umarfb/pt5m-data-reduction
# load reference image and image to be aligned from pt5m
src_img = fits.getdata(filepath + 'r0500344_am.fits')
targ_img = fits.getdata(filepath + 'r0500345_am.fits')

# get fits header for target image
hdr = fits.getheader(filepath + 'r0500345_am.fits')

# increase source image size
#src_img = zoom(src_img, 1.5, order=2)
#fits.writeto('zoom349.fits', src_img)

# known star-to-star correspondence on image
targ_str = np.array([(484.0, 267.0), (878.0, 566.0), (257.0, 443.0),
                     (239.0, 460.0), (899.0, 474.0), (781.0, 374.0)])
src_str = np.array([(334.0, 290.0), (727.0, 589.0), (105.0, 466.0),
                    (88.0, 483.0), (748.0, 498.0), (631.0, 398.0)])

# estimate transform
tform = aa.estimate_transform('affine', targ_str, src_str)
#tform = aa.find_transform(src_img, targ_img)

# apply transformation to image to align
aligned_img = aa.apply_transform(tform, src_img, targ_img)

# update header
hdr['HISTORY'] = 'Aligned'

#aligned_img = aa.register(src_img, targ_img)
os.remove(filename)
fits.writeto(filename, aligned_img, hdr)