Exemple #1
0
def detector_drift_adjust_aps_1id(imgstacks,
                                  slit_cnr_ref,
                                  medfilt2_kernel_size=3,
                                  medfilt_kernel_size=3,
                                  ncore=None,
                                  ):
    """
    Adjust each still image based on the slit corners and generate report fig

    Parameters
    ----------
    imgstacks : np.ndarray
        tomopy images stacks (axis_0 is the oemga direction)
    slit_cnr_ref : np.ndarray
        reference slit corners from white field images
    medfilt2_kernel_size : int, optional
        2D median filter kernel size for slit conner detection
    medfilt_kernel_size  : int, optional
        1D median filter kernel size for slit conner detection
    ncore : int, optional
        number of cores used for speed up

    Returns
    -------
    np.ndarray
        adjusted imgstacks
    np.ndarray
        detected corners on each still image
    np.ndarray
        transformation matrices used to adjust each image
    """
    ncore = mproc.mp.cpu_count() - 1 if ncore is None else ncore

    def quick_diff(x): return np.amax(np.absolute(x))

    # -- find all projection corners (slow)
    # NOTE:
    #  Here we are using an iterative approach to find stable slit corners
    #  from each image
    #  1. calculate all slit corners with the given kernel size, preferably
    #     a small one for speed.
    #  2. double the kernel size and calculate again, but this time we are
    #     checking whether the slit corners are stable.
    #  3. find the ids (n_imgs) for those that are difficult, continue
    #     increasing the kernel size until all slit corners are found, or max
    #     number of iterations.
    #  4. move on to next step.
    nlist = range(imgstacks.shape[0])
    proj_cnrs = _calc_proj_cnrs(imgstacks, ncore, nlist,
                                'quadrant+',
                                medfilt2_kernel_size,
                                medfilt_kernel_size,
                                )
    cnrs_found = np.array([quick_diff(proj_cnrs[n, :, :] - slit_cnr_ref) < 15
                           for n in nlist])
    kernels = [(medfilt2_kernel_size+2*i, medfilt_kernel_size+2*j)
               for i in range(15)
               for j in range(15)]
    counter = 0

    while not cnrs_found.all():
        nlist = [idx for idx, cnr_found in enumerate(cnrs_found)
                 if not cnr_found]
        # NOTE:
        #   Check to see if we run out of candidate kernels:
        if counter > len(kernels):
            # we are giving up here...
            for idx, n_img in enumerate(nlist):
                proj_cnrs[n_img, :, :] = slit_cnr_ref
            break
        else:
            # test with differnt 2D and 1D kernels
            ks2d, ks1d = kernels[counter]

        _cnrs = _calc_proj_cnrs(imgstacks, ncore, nlist,
                                'quadrant+', ks2d, ks1d)
        for idx, _cnr in enumerate(_cnrs):
            n_img = nlist[idx]
            cnr = proj_cnrs[n_img, :, :]  # previous results
            # NOTE:
            #  The detector corner should not be far away from reference
            #  -> adiff < 15
            #  The detected corner should be stable
            #  -> rdiff < 0.1 (pixel)s
            adiff = quick_diff(_cnr - slit_cnr_ref)
            rdiff = quick_diff(_cnr - cnr)
            if rdiff < 0.1 and adiff < 15:
                cnrs_found[n_img] = True
            else:
                # update results
                proj_cnrs[n_img, :, :] = _cnr  # update results for next iter

        # next
        counter += 1

    # -- calculate affine transformation (fast)
    img_correct_F = np.ones((imgstacks.shape[0], 3, 3))
    for n_img in range(imgstacks.shape[0]):
        img_correct_F[n_img, :, :] = calc_affine_transform(
            proj_cnrs[n_img, :, :], slit_cnr_ref)

    # -- apply affine transformation (slow)
    tmp = []
    with cf.ProcessPoolExecutor(ncore) as e:
        for n_img in range(imgstacks.shape[0]):
            tmp.append(e.submit(affine_transform,
                                # input image
                                imgstacks[n_img, :, :],
                                # rotation matrix
                                img_correct_F[n_img, 0:2, 0:2],
                                # offset vector
                                offset=img_correct_F[n_img, 0:2,  2],
                                )
                       )
    imgstacks = np.stack([me.result() for me in tmp], axis=0)

    return imgstacks, proj_cnrs, img_correct_F
Exemple #2
0
def detector_drift_adjust_aps_1id(
    imgstacks,
    slit_cnr_ref,
    medfilt2_kernel_size=3,
    medfilt_kernel_size=3,
    ncore=None,
):
    """
    Adjust each still image based on the slit corners and generate report fig

    Parameters
    ----------
    imgstacks : np.ndarray
        tomopy images stacks (axis_0 is the oemga direction)
    slit_cnr_ref : np.ndarray
        reference slit corners from white field images
    medfilt2_kernel_size : int, optional
        2D median filter kernel size for slit conner detection
    medfilt_kernel_size  : int, optional
        1D median filter kernel size for slit conner detection
    ncore : int, optional
        number of cores used for speed up

    Returns
    -------
    np.ndarray
        adjusted imgstacks
    np.ndarray
        detected corners on each still image
    np.ndarray
        transformation matrices used to adjust each image
    """
    ncore = mproc.mp.cpu_count() - 1 if ncore is None else ncore

    def quick_diff(x):
        return np.amax(np.absolute(x))

    # -- find all projection corners (slow)
    # NOTE:
    #  Here we are using an iterative approach to find stable slit corners
    #  from each image
    #  1. calculate all slit corners with the given kernel size, preferably
    #     a small one for speed.
    #  2. double the kernel size and calculate again, but this time we are
    #     checking whether the slit corners are stable.
    #  3. find the ids (n_imgs) for those that are difficult, continue
    #     increasing the kernel size until all slit corners are found, or max
    #     number of iterations.
    #  4. move on to next step.
    nlist = range(imgstacks.shape[0])
    proj_cnrs = _calc_proj_cnrs(
        imgstacks,
        ncore,
        nlist,
        'quadrant+',
        medfilt2_kernel_size,
        medfilt_kernel_size,
    )
    cnrs_found = np.array(
        [quick_diff(proj_cnrs[n, :, :] - slit_cnr_ref) < 15 for n in nlist])
    kernels = [(medfilt2_kernel_size + 2 * i, medfilt_kernel_size + 2 * j)
               for i in range(15) for j in range(15)]
    counter = 0

    while not cnrs_found.all():
        nlist = [
            idx for idx, cnr_found in enumerate(cnrs_found) if not cnr_found
        ]
        # NOTE:
        #   Check to see if we run out of candidate kernels:
        if counter > len(kernels):
            # we are giving up here...
            for idx, n_img in enumerate(nlist):
                proj_cnrs[n_img, :, :] = slit_cnr_ref
            break
        else:
            # test with differnt 2D and 1D kernels
            ks2d, ks1d = kernels[counter]

        _cnrs = _calc_proj_cnrs(imgstacks, ncore, nlist, 'quadrant+', ks2d,
                                ks1d)
        for idx, _cnr in enumerate(_cnrs):
            n_img = nlist[idx]
            cnr = proj_cnrs[n_img, :, :]  # previous results
            # NOTE:
            #  The detector corner should not be far away from reference
            #  -> adiff < 15
            #  The detected corner should be stable
            #  -> rdiff < 0.1 (pixel)s
            adiff = quick_diff(_cnr - slit_cnr_ref)
            rdiff = quick_diff(_cnr - cnr)
            if rdiff < 0.1 and adiff < 15:
                cnrs_found[n_img] = True
            else:
                # update results
                proj_cnrs[n_img, :, :] = _cnr  # update results for next iter

        # next
        counter += 1

    # -- calculate affine transformation (fast)
    img_correct_F = np.ones((imgstacks.shape[0], 3, 3))
    for n_img in range(imgstacks.shape[0]):
        img_correct_F[n_img, :, :] = calc_affine_transform(
            proj_cnrs[n_img, :, :], slit_cnr_ref)

    # -- apply affine transformation (slow)
    tmp = []
    with cf.ProcessPoolExecutor(ncore) as e:
        for n_img in range(imgstacks.shape[0]):
            tmp.append(
                e.submit(
                    affine_transform,
                    # input image
                    imgstacks[n_img, :, :],
                    # rotation matrix
                    img_correct_F[n_img, 0:2, 0:2],
                    # offset vector
                    offset=img_correct_F[n_img, 0:2, 2],
                ))
    imgstacks = np.stack([me.result() for me in tmp], axis=0)

    return imgstacks, proj_cnrs, img_correct_F