Beispiel #1
0
def save_img_file(img, file_path, file_type=None):

    img = place_dnp(img)
    ext = os.path.splitext(file_path)[-1][1:]

    if not file_type:
        file_type = ext if ext == 'png' or ext == 'tiff' else 'tiff' if img.dtype == 'uint16' else 'png'

    # try libtiff import or use png instead if import fails
    TIFF, file_type = try_tiff_import(file_type)

    # compose new file path string if extension type changed
    file_path = os.path.splitext(file_path)[-2] if file_path.endswith(
        ('.tiff', '.png', '.bmp')) else file_path
    file_path = file_path + '.' + file_type

    if file_type == 'tiff':
        obj = TIFF.open(file_path, mode='w')
        obj.write_image(misc.Normalizer(img).uint16_norm(),
                        compression=None,
                        write_rgb=True)
        obj.close()

    elif file_type == 'png' or file_type == 'bmp':

        Image.fromarray(misc.Normalizer(img).uint8_norm()).save(file_path,
                                                                file_type,
                                                                optimize=True)

    return True
Beispiel #2
0
    def main(self):

        # compose bayer image from input image buffer
        self.comp_bayer()

        # auto white balance
        if 'awb' in self.cfg.lfpimg.keys():
            self._bay_img = self.correct_awb(self._bay_img,
                                             self.cfg.lfpimg['bay'],
                                             gains=self.cfg.lfpimg['awb'])
            self._reshape_bayer()
            self._bay_img = self.desaturate_clipped(
                self._bay_img, gains=self.cfg.lfpimg['awb'])
            self._reshape_bayer()

        # debayer to rgb image
        if 'bay' in self.cfg.lfpimg.keys() and len(self._bay_img.shape) == 2:
            self.bay2rgb()

        # color matrix correction
        if 'ccm' in self.cfg.lfpimg.keys():
            self._rgb_img = self.correct_color(self._rgb_img,
                                               ccm_mat=np.reshape(
                                                   self.cfg.lfpimg['ccm'],
                                                   (3, 3)).T)

        # perform gamma correction
        if 'gam' in self.cfg.lfpimg.keys():
            self._rgb_img = self.correct_gamma(self._rgb_img,
                                               gamma=self.cfg.lfpimg['gam'])

        # convert to uint16
        self._rgb_img = misc.Normalizer(self._rgb_img).uint16_norm()

        return True
Beispiel #3
0
    def wht_bal(self, method=None, msg_opt=True):

        # status update
        if msg_opt:
            msg = 'Auto white balance' if self.p_hi != 1 else 'Color adjustment'
            self.sta.status_msg(msg=msg, opt=self.cfg.params[self.cfg.opt_prnt])
            self.sta.progress(0, opt=self.cfg.params[self.cfg.opt_prnt])

        ch_num = self.vp_img_arr.shape[-1] if len(self.vp_img_arr.shape) > 4 else 3
        for i in range(ch_num):
            if method is None:

                # channel selection
                ref_ch = self.ref_img[..., i]
                img_ch = self.vp_img_arr[..., i]

                # define level limits
                min = np.percentile(ref_ch, self.p_lo*100)
                max = np.percentile(ref_ch, self.p_hi*100)

                # normalization of color channel
                self.vp_img_arr[..., i] = misc.Normalizer(img_ch, min=min, max=max).uint16_norm()

            else:
                # brightness and contrast method
                self.set_stretch(ref_ch=self.ref_img[..., i])
                self.apply_stretch(ch=i)

            # status update
            if msg_opt:
                self.sta.progress((i+1)/ch_num*100, opt=self.cfg.params[self.cfg.opt_prnt])

        return True
Beispiel #4
0
def plot_hist(data, dtype=None):

    data = misc.Normalizer(data).uint16_norm()

    dtype = str(
        data.dtype) if dtype is None and type(dtype) is np.ndarray else str(
            dtype)
    if dtype.startswith(('int', 'uint')):
        bins = np.iinfo(np.dtype(dtype)).max
    else:
        bins = int(data.max() - data.min())

    h = np.histogram(data, bins=bins)

    import matplotlib.pyplot as plt
    plt.switch_backend('Agg')
    plt.figure()
    plt.plot(h[1][:-1], h[0])
    plt.savefig('iwas.png')
    try:
        plt.show()
    except:
        pass

    return True
Beispiel #5
0
    def auto_wht_bal(self, method=None):

        # status update
        self.sta.status_msg(msg='Auto white balance',
                            opt=self.cfg.params[self.cfg.opt_prnt])
        self.sta.progress(None, opt=self.cfg.params[self.cfg.opt_prnt])

        ch_num = self.vp_img_arr.shape[-1] if len(
            self.vp_img_arr.shape) > 4 else 3
        for i in range(ch_num):
            if method is None:

                # channel selection
                ref_ch = self.ref_img[..., i]
                img_ch = self.vp_img_arr[..., i]

                # normalization of color channel
                self.vp_img_arr[..., i] = misc.Normalizer(
                    img=img_ch,
                    min=np.percentile(ref_ch, self.p_lo * 100),
                    max=np.percentile(ref_ch, self.p_hi * 100)).uint16_norm()
            else:
                # brightness and contrast method
                self.set_stretch(ref_ch=self.ref_img[..., i])
                self.apply_stretch(ch=i)

            # status update
            self.sta.progress((i + 1) / ch_num * 100,
                              opt=self.cfg.params[self.cfg.opt_prnt])

        return True
    def channel_bal(self):

        # status update
        self.sta.status_msg(msg='Contrast balance',
                            opt=self.cfg.params[self.cfg.opt_prnt])
        self.sta.progress(None, opt=self.cfg.params[self.cfg.opt_prnt])

        ch_num = self.vp_img_arr.shape[-1] if len(
            self.vp_img_arr.shape) > 4 else 3

        min = float('Inf')
        max = 0.
        for i in range(ch_num):
            min = np.min(
                [min,
                 np.percentile(self.ref_img[..., i], self.p_lo * 100)])
            max = np.max(
                [max,
                 np.percentile(self.ref_img[..., i], self.p_hi * 100)])

        # normalization of color channel
        self.vp_img_arr = misc.Normalizer(self.vp_img_arr, min=min,
                                          max=max).uint16_norm()

        # status update
        self.sta.progress(100, opt=self.cfg.params[self.cfg.opt_prnt])

        return True
Beispiel #7
0
    def bay2rgb(self, method=2):

        # print status
        self.sta.status_msg('Debayering', self.cfg.params[self.cfg.opt_prnt])
        self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt])

        # Bayer to RGB conversion
        if method == 0:
            self._rgb_img = demosaicing_CFA_Bayer_bilinear(
                self._bay_img, self.cfg.lfpimg['bay'])
        elif method == 1:
            self._rgb_img = demosaicing_CFA_Bayer_Malvar2004(
                self._bay_img, self.cfg.lfpimg['bay'])
        else:
            self._rgb_img = demosaicing_CFA_Bayer_Menon2007(
                self._bay_img, self.cfg.lfpimg['bay'])

        # normalize image
        min = np.percentile(self._rgb_img, 0.05)
        max = np.max(self.rgb_img)
        self._rgb_img = misc.Normalizer(self._rgb_img, min=min,
                                        max=max).type_norm()

        # update status message
        self.sta.progress(100, self.cfg.params[self.cfg.opt_prnt])

        return True
Beispiel #8
0
    def export_vp_stack(self, type='png', downscale=None):

        # print status
        self.sta.status_msg('Write viewpoint image stack',
                            self.cfg.params[self.cfg.opt_prnt])
        self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt])

        # downscale image
        downscale = True if downscale is None else downscale
        views_stacked_img = misc.img_resize(self.views_stacked_img.copy(), 1 / self._M) \
            if downscale else self.views_stacked_img.copy()

        # normalization
        p_lo = np.percentile(misc.rgb2gray(self.central_view), 0.05)
        p_hi = np.percentile(misc.rgb2gray(self.central_view), 99.995)
        views_stacked_img = misc.Normalizer(views_stacked_img,
                                            min=p_lo,
                                            max=p_hi).uint8_norm()

        # export all viewpoints in single image
        views_stacked_path = os.path.join(
            self.cfg.exp_path, 'views_stacked_img_' + str(self._M) + 'px')
        misc.save_img_file(views_stacked_img,
                           file_path=views_stacked_path,
                           file_type=type)

        self.sta.progress(100, self.cfg.params[self.cfg.opt_prnt])

        return True
Beispiel #9
0
    def export_refo_stack(self, file_type=None):

        # print status
        self.sta.status_msg('Write refocused images',
                            self.cfg.params[self.cfg.opt_prnt])
        self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt])

        refo_stack = misc.Normalizer(self.refo_stack).uint16_norm()
        if self.cfg.params[self.cfg.opt_refi]:
            a_list = np.arange(*np.array(self.cfg.params[self.cfg.ran_refo]) *
                               self.cfg.params[self.cfg.ptc_leng])
            a_list = np.round(a_list / self.cfg.params[self.cfg.ptc_leng], 2)
        else:
            a_list = range(*self.cfg.params[self.cfg.ran_refo])

        # create folder
        string = 'subpixel_' if self.cfg.params[self.cfg.opt_refi] else ''
        folder_path = os.path.join(self.cfg.exp_path,
                                   'refo_' + string + str(self._M) + 'px')
        misc.mkdir_p(folder_path)

        for i, refo_img in enumerate(refo_stack):

            # get depth plane number for filename
            a = a_list[i]

            self.save_refo_slice(a, refo_img, folder_path, file_type=file_type)

            # print status
            percentage = ((i + 1) / len(refo_stack)) * 100
            self.sta.progress(percentage, self.cfg.params[self.cfg.opt_prnt])

        return True
Beispiel #10
0
    def gif_refo(self):

        # export gif animation
        fn = 'refocus_animation_' + str(self.cfg.params[self.cfg.ptc_leng]) + 'px'
        refo_stack = misc.Normalizer(np.asarray(self._refo_stack)).uint8_norm()
        refo_stack = np.concatenate((refo_stack, refo_stack[::-1]), axis=0)      # play forward and backwards
        misc.save_gif(refo_stack, duration=.5, fp=self.cfg.exp_path, fn=fn)

        return True
Beispiel #11
0
    def main(self):

        if self.cfg.calibs[self.cfg.pat_type] == 'hex':
            self.proc_vp_arr(self.ver_hex_bulge,
                             msg='Hexagonal artifact removal')

        self.vp_img_arr = misc.Normalizer(self.vp_img_arr).uint16_norm()

        return True
Beispiel #12
0
    def scheimpflug_from_stack(self):

        a_start, a_stop = (0, len(self.refo_stack))

        if len(self.refo_stack[0].shape) == 3:
            m, n, p = self.refo_stack[0].shape
        else:
            m, n, p = (self.refo_stack[0].shape[0],
                       self.refo_stack[0].shape[1], 1)

        scheimpflug_img = np.zeros([m, n, p])

        # map generation
        a_x = np.linspace(
            0, a_stop - a_start, n + 2,
            dtype='int')[1:-1]  # flooring via integer type while excluding
        a_y = np.linspace(0, a_stop - a_start, m + 2, dtype='int')[1:-1]
        a_map_x = np.outer(np.ones(m, dtype='int'), a_x)
        a_map_y = np.outer(a_y, np.ones(n, dtype='int'))

        # vertical orientation (default)
        a_map = a_map_y
        # horizontal orientation
        if self.cfg.params[self.cfg.opt_pflu] == c.PFLU_VALS[1]:
            a_map = a_map_x
        # diagonal orientation
        elif self.cfg.params[self.cfg.opt_pflu] == (c.PFLU_VALS[2]
                                                    or c.PFLU_VALS[3]):
            # swap refocusing directions if option set
            if self.cfg.params[self.cfg.opt_pflu] == c.PFLU_VALS[3]:
                a_map_x, a_map_y = a_map_x[::-1], a_map_y[::-1]
            a_map = np.mean(np.stack([a_map_x, a_map_y]), dtype='int', axis=0)

        for y in range(m):
            for x in range(n):
                scheimpflug_img[y, x] = self.refo_stack[a_map[y, x]][y, x]

                # check interrupt status
                if self.sta.interrupt:
                    return False

                # print status
                percentage = (((y * n + x + 1) / (m * n)) * 100)
                self.sta.progress(percentage,
                                  self.cfg.params[self.cfg.opt_prnt])

        # write image file to hard drive
        a_ran = self.cfg.params[self.cfg.ran_refo]
        fn = 'scheimpflug_' + str(a_ran[0]) + '_' + str(
            a_ran[-1]) + '_' + self.cfg.params[self.cfg.opt_pflu] + '.png'
        misc.save_img_file(
            misc.Normalizer(scheimpflug_img).uint16_norm(),
            os.path.join(self.fp, fn))

        return True
Beispiel #13
0
    def export_thumbnail(self, type='tiff'):

        thumb = misc.Normalizer(self.central_view.copy()).type_norm()

        # export central viewpoint as thumbnail image
        fp = os.path.join(self.cfg.exp_path, 'thumbnail')
        misc.save_img_file(thumb,
                           file_path=fp,
                           file_type=type,
                           tag=self.cfg.params[self.cfg.opt_dbug])

        return True
Beispiel #14
0
    def thresh_hist_stretch(self, th=2e-10, bins=2**16-1):

        h = np.histogram(self.central_view, bins=bins)
        hn = h[0] / h[0].sum()
        x_vals = np.where(hn / len(hn) > th)[0] / bins

        hs = np.diff(h[0][::128] / h[0][::128].sum())
        s_vals = np.where(hs > 1.5e-4)[0] / (bins / 128)

        #img = misc.Normalizer(self.central_view.copy(), min=x_vals[1], max=self.central_view.max()).type_norm()
        self.proc_vp_arr(misc.Normalizer().type_norm, msg='Histogram crop', min=x_vals[1], max=1)

        return True
Beispiel #15
0
    def post_lum(self, ch=None):

        self.vp_img_arr = misc.Normalizer(self.vp_img_arr).uint16_norm()

        # channel selection
        ch = ch if ch is not None else 0
        ref_ch = misc.clr_spc_conv.yuv_conv(self.central_view)[..., ch]

        # define level limits
        self._min = np.percentile(ref_ch, self.p_lo * 100)
        self._max = np.percentile(ref_ch, self.p_hi * 100)

        self.proc_vp_arr(self.lum_norm, msg='Luminance normalization')
Beispiel #16
0
    def main(self):

        # apply auto white balance gains while considering image highlights
        self.safe_bayer_awb()

        # debayer to rgb image
        if 'bay' in self.cfg.lfpimg.keys() and len(self._bay_img.shape) == 2:
            self.bay2rgb(2)

        # convert to uint16
        self._rgb_img = misc.Normalizer(self._rgb_img).uint16_norm()

        return True
Beispiel #17
0
    def gif_refo(self):

        # image normalization
        refo_stack = misc.Normalizer(self.refo_stack).uint8_norm()

        # append reversed array copy to play forward and backwards
        refo_stack = np.concatenate((refo_stack, refo_stack[::-1]), axis=0)

        # export gif animation
        fn = 'refocus_animation_' + str(
            self.cfg.params[self.cfg.ptc_leng]) + 'px'
        misc.save_gif(refo_stack, duration=.5, fp=self.cfg.exp_path, fn=fn)

        return True
Beispiel #18
0
    def _write_lfp_align(self):

        # convert to 16bit unsigned integer
        self._lfp_out = misc.Normalizer(self._lfp_out).uint16_norm()

        # create output data folder
        misc.mkdir_p(self.cfg.exp_path, self.cfg.params[self.cfg.opt_prnt])

        # write aligned light field as pickle file to avoid recalculation
        with open(os.path.join(self.cfg.exp_path, 'lfp_img_align.pkl'), 'wb') as f:
            pickle.dump(self._lfp_out, f)

        if self.cfg.params[self.cfg.opt_dbug]:
            misc.save_img_file(self._lfp_out, os.path.join(self.cfg.exp_path, 'lfp_img_align.tiff'))
Beispiel #19
0
    def main(self):

        # check interrupt status
        if self.sta.interrupt:
            return False

        # remove hexagonal artifact
        if self.cfg.calibs[self.cfg.pat_type] == 'hex':
            self.proc_vp_arr(self.ver_hex_bulge, msg='Hexagonal artifact removal')

        # normalize light-field
        self.vp_img_arr = misc.Normalizer(self.vp_img_arr).uint16_norm()

        return True
Beispiel #20
0
    def auto_hist_align(img, ref_img, opt=None):

        if opt:
            p_lo, p_hi = (0.005, 99.9)  #(0.001, 99.999)
            min_perc = np.percentile(misc.rgb2gray(ref_img), p_lo)
            max_perc = np.percentile(ref_img, p_hi)
        else:
            p_lo, p_hi = (0.5, 99.9)
            min_perc = np.percentile(ref_img, p_lo)
            max_perc = np.percentile(ref_img, p_hi)

        img = misc.Normalizer(img, min=min_perc, max=max_perc).type_norm()

        return img
Beispiel #21
0
    def lum_norm(self, img, ch=None):

        # set default channel
        ch = ch if ch is not None else 0

        # RGB to YUV conversion
        img = misc.clr_spc_conv.yuv_conv(img)

        # normalization of Y (luminance channel)
        img = misc.Normalizer(img, min=self._min, max=self._max).uint16_norm()

        # YUV to RGB conversion
        img = misc.clr_spc_conv.yuv_conv(img, inverse=True)

        return img
Beispiel #22
0
def robust_awb(img, t=0.3, max_iter=1000):
    ''' inspired by Jun-yan Huo et al. and http://web.stanford.edu/~sujason/ColorBalancing/Code/robustAWB.m '''

    img = misc.Normalizer(img).type_norm(lim_min=0, lim_max=1.0)
    ref_pixel = img[0, 0, :].copy()

    u = .01  # gain step size
    a = .8  # double step threshold
    b = .001  # convergence threshold

    gains_adj = np.array([1., 1., 1.])

    for i in range(max_iter):
        img_yuv = plenopticam.misc.clr_spc_conv.yuv_conv(img)
        f = (abs(img_yuv[..., 1]) + abs(img_yuv[..., 2])) / img_yuv[..., 0]
        grays = np.zeros(img_yuv.shape)
        grays[f < t] = img_yuv[f < t]
        if np.sum(f < t) == 0:
            print('No valid gray pixels found.')
            break

        u_bar = np.mean(grays[..., 1])  # estimate
        v_bar = np.mean(grays[..., 2])  # estimate

        # rgb_est = misc.yuv_conv(np.array([100, u_bar, v_bar]), inverse=True)    # convert average gray from YUV to RGB

        # U > V: blue needs adjustment otherwise red is treated
        err, ch = (u_bar, 2) if abs(u_bar) > abs(v_bar) else (v_bar, 0)

        if abs(err) >= a:
            delta = 2 * np.sign(
                err) * u  # accelerate gain adjustment if far off
        elif abs(err) < b:  # converged when u_bar and v_bar < b
            # delta = 0
            #self.sta.status_msg('AWB convergence reached', self.cfg.params[self.cfg.opt_prnt])
            break
        else:
            delta = err * u

        # negative feedback loop
        gains_adj[ch] -= delta

        img = np.dot(img, np.diag(gains_adj))

    # take gains only if result is obtained by convergence
    gains = img[0, 0, :] / ref_pixel if i != max_iter - 1 else (1, 1, 1)

    return img, gains
Beispiel #23
0
    def gif_vp_img(self, duration, pattern='circle'):

        # micro image size estimate
        M = max(self.cfg.calibs[self.cfg.ptc_mean]
                ) if self.cfg.calibs else self.cfg.params[self.cfg.ptc_leng]

        # filter images forming a pattern
        lf_radius = min(int((M + 1) // 4), self._C)
        img_set = self.reorder_vp_arr(pattern=pattern, lf_radius=lf_radius)

        # image normalization
        img_set = misc.Normalizer(img_set).uint8_norm()

        # export gif animation
        fn = 'view_animation_' + str(lf_radius * 2 + 1) + 'px'
        misc.save_gif(img_set, duration=duration, fp=self.cfg.exp_path, fn=fn)

        return True
Beispiel #24
0
    def con_bal(self):

        # find extrema from reference image
        self.ref_img = yuv_conv(self.central_view)[..., 0]
        max = self.ref_img.max()
        min = self.ref_img.min()

        # convert to yuv space
        self.proc_vp_arr(yuv_conv, msg='Convert to YUV')

        # boost luminance channel
        self.sta.status_msg(msg='Contrast balance', opt=self.cfg.params[self.cfg.opt_prnt])
        self._vp_img_arr[..., 0] = misc.Normalizer(self._vp_img_arr[..., 0]).type_norm(max=max, min=min)
        self.sta.progress(100, opt=self.cfg.params[self.cfg.opt_prnt])

        # convert to rgb space
        self.proc_vp_arr(yuv_conv, inverse=True, msg='Convert to RGB')

        return True
Beispiel #25
0
    def lum_norm(self, img, ch=None, dtype=None):

        # set default channel
        ch = ch if ch is not None else 0

        # set default data type
        dtype = img.dtype if dtype is None else dtype

        # RGB to YUV conversion
        img = misc.clr_spc_conv.yuv_conv(img)

        # normalization of Y (luminance channel) for given data type
        img[...,
            ch] = misc.Normalizer(img=img[..., ch],
                                  min=np.percentile(img[..., ch],
                                                    self.p_lo * 100),
                                  max=np.percentile(img[..., ch],
                                                    self.p_hi * 100),
                                  dtype=dtype).type_norm()

        # YUV to RGB conversion
        img = misc.clr_spc_conv.yuv_conv(img, inverse=True)

        return img
Beispiel #26
0
    def decode_lytro_file(self):

        # Lytro type decoding
        with open(self._lfp_path, mode='rb') as file:

            # LFC and raw type decoding
            obj = LfpDecoder(file, self.cfg, self.sta, lfp_path=self._lfp_path)
            obj.main()
            self._lfp_img = obj.bay_img
            self._json_dict = obj.json_dict
            del obj

            # save bayer image as file (if not already present)
            if not os.path.exists(self.fp) and not self.sta.interrupt:
                self.sta.status_msg(msg='Save raw image',
                                    opt=self.cfg.params[self.cfg.opt_prnt])
                self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt])
                misc.save_img_file(misc.Normalizer(
                    self._lfp_img).uint16_norm(),
                                   self.fp,
                                   file_type='tiff')
                self.sta.progress(100, self.cfg.params[self.cfg.opt_prnt])

        return True
Beispiel #27
0
    def export_viewpoints(self, type='tiff'):

        # print status
        self.sta.status_msg('Write viewpoint images',
                            self.cfg.params[self.cfg.opt_prnt])
        self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt])

        ptc_leng = self.cfg.params[self.cfg.ptc_leng]

        # create folder
        folderpath = os.path.join(self.cfg.exp_path,
                                  'viewpoints_' + str(ptc_leng) + 'px')
        misc.mkdir_p(folderpath)

        # normalize image array to 16-bit unsigned integer
        vp_img_arr = misc.Normalizer(self.vp_img_arr).uint16_norm()

        # export viewpoint images as image files
        for j in range(ptc_leng):
            for i in range(ptc_leng):

                misc.save_img_file(vp_img_arr[j, i],
                                   os.path.join(folderpath,
                                                str(j) + '_' + str(i)),
                                   file_type=type,
                                   tag=self.cfg.params[self.cfg.opt_dbug])

                # print status
                percentage = (((j * self._M + i + 1) / self._M**2) * 100)
                self.sta.progress(percentage,
                                  self.cfg.params[self.cfg.opt_prnt])

                if self.sta.interrupt:
                    return False

        return True
Beispiel #28
0
    # iterate through directories
    for set in [(fp_lytro, coords_lists_lytro), (fp_ours, coords_lists_pcam)]:

        fp, coords_lists = set

        img_tiles, slice_fns = crop_imgs(fp, coords_lists)

        # iterate through file names in directory
        for img_tile, slice_fn in zip(img_tiles, slice_fns):

            # leave out alpha channel if present
            img_tile = img_tile[..., :3]

            # rescale tile for fair comparison
            img_tile = misc.img_resize(
                img_tile, scale_comp_x,
                scale_comp_y) if fp.__contains__('refo_lytro') else img_tile
            img_tile = misc.Normalizer(img_tile).uint8_norm()

            # store results
            s_list.append(
                (slice_fn, blur_metric(img_tile), michelson_contrast(img_tile),
                 brisque_metric(img_tile)))

    for s in s_list:
        print(s)

    s_arr = np.asarray(s_list)
    np.save('refo_metrics', s_list)
Beispiel #29
0
    def scheimpflug_from_scratch(self):

        patch_len = self.cfg.params[self.cfg.ptc_leng]
        a_start, a_stop = self.cfg.params[self.cfg.ran_refo]

        img = self.lfp_img.astype('float') / patch_len
        m, n, P = self.lfp_img.shape
        overlap = int(abs(a_stop) * (patch_len - 1))
        #tilt_vec_y = np.linspace(a_start, planes, m).astype('uint')
        a_x = np.linspace(a_start, a_stop, n + overlap).astype(
            'int'
        )  # flooring values instead of rounding => 1st round, then int()
        a_y = np.zeros(m).astype(
            'int')  #np.linspace(a_start, planes, m).astype('uint')
        a_xy = np.ones([m, n + overlap]).astype('int') * a_x

        # initialize matrices for intermediate and plane results
        hor_refo = np.zeros([m, n + overlap, P], dtype='float')
        ver_refo = np.zeros([m + overlap, n + overlap, P], dtype='float')
        fraction_vec = np.zeros([patch_len, P], dtype='float')

        # horizontal scheimpflug shift and integration
        for y in range(m):
            for x in range(n):

                # prevent from taking adjacent pixel being beyond image border
                if x + patch_len < n:
                    adj_idx = x + patch_len
                else:
                    adj_idx = x

                for p in range(P):
                    fraction_vec[:, p] = np.linspace(img[y, x, p],
                                                     img[y, adj_idx,
                                                         p], patch_len)

                # load refocus value at x,y
                a = a_xy[y, x]

                # consider negative shift
                negative_a = int((patch_len - 1) * abs(a)) if a < 0 else 0

                # centralize row
                row_shift = int((a_y.max() - a) * (patch_len - 1) / 2)

                newX = int(x + np.mod(x, patch_len) *
                           (a - 1) + negative_a) + row_shift
                hor_refo[y, newX:newX +
                         patch_len, :] = hor_refo[y, newX:newX +
                                                  patch_len, :] + fraction_vec

            # check interrupt status
            if self.sta.interrupt:
                return False

            # print progress status
            self.sta.progress((y + 1) / m * 50,
                              self.cfg.params[self.cfg.opt_prnt])

        # vertical scheimpflug shift and integration
        new_n = n + int(abs(a_x.max()) * (patch_len - 1))
        for x in range(new_n):
            for y in range(m):

                if y + patch_len < m:
                    adj_idx = y + patch_len
                else:
                    adj_idx = y

                frac_vec = np.zeros(
                    [patch_len,
                     int(n + abs(a_x.max()) * (patch_len - 1)), P],
                    dtype='float')
                for p in range(P):
                    frac_vec[:, x, p] = np.linspace(hor_refo[y, x, p],
                                                    hor_refo[adj_idx, x,
                                                             p], patch_len)

                # load refocus value at x,y
                a = a_xy[y, x]

                # consider negative shift
                negative_a = int((patch_len - 1) * abs(a)) if a < 0 else 0

                # centralize column
                column_shift = int((a_x.max() - a) * (patch_len - 1) / 2)

                # put interpolated vector to refocusing plane
                newY = int(y + np.mod(y, patch_len) *
                           (a - 1) + negative_a) + column_shift
                ver_refo[newY:newY + patch_len, :, :] = ver_refo[
                    newY:newY + patch_len, :, :] + frac_vec

            # print progress status
            self.sta.progress(((x + 1) / new_n + .5) * 100,
                              self.cfg.params[self.cfg.opt_prnt])

        # write image file to hard drive
        img = misc.Normalizer(ver_refo).uint16_norm()
        misc.save_img_file(
            img,
            os.path.join(self.fp, 'scheimpflug_' + str(patch_len) + 'px.tiff'))

        return True
Beispiel #30
0
    def main(self):

        if self._lfp_path.lower().endswith(SUPP_FILE_EXT):

            # filename and file path from previously decoded data
            dp = os.path.splitext(self._lfp_path)[0]
            fn = os.path.basename(dp) + '.tiff'
            fp = os.path.join(dp, fn)

            # load previously generated tiff if present
            if os.path.exists(fp):
                try:
                    self._lfp_img = misc.load_img_file(fp)
                except FileNotFoundError:
                    # print status
                    self.sta.status_msg(
                        '{0} not found'.format(os.path.basename(
                            self._lfp_path)),
                        self.cfg.params[self.cfg.opt_prnt])
                    self.sta.progress(100, self.cfg.params[self.cfg.opt_prnt])
                    self.sta.error = True
                except TypeError as e:
                    self.sta.status_msg(e, self.cfg.params[self.cfg.opt_prnt])
                    self.sta.progress(100, self.cfg.params[self.cfg.opt_prnt])
                    raise LfpTypeError(e)

            else:
                try:
                    # Lytro type decoding
                    with open(self._lfp_path, mode='rb') as file:

                        # LFC and raw type decoding
                        obj = LfpDecoder(file, self.cfg, self.sta)
                        if self._lfp_path.lower().endswith(SUPP_FILE_EXT[1:]):
                            # LFC type decoding
                            obj.decode_lfc()
                            self.cfg.save_json(os.path.join(
                                dp,
                                os.path.basename(dp) + '.json'),
                                               json_dict=obj.json_dict)
                        elif self._lfp_path.lower().endswith(SUPP_FILE_EXT[0]):
                            # raw type decoding
                            obj.decode_raw()
                        self._lfp_img = obj.rgb_img
                        del obj

                        # save bayer image as file
                        self.sta.status_msg(
                            msg='Save raw image',
                            opt=self.cfg.params[self.cfg.opt_prnt])
                        self.sta.progress(None,
                                          self.cfg.params[self.cfg.opt_prnt])
                        misc.save_img_file(misc.Normalizer(
                            self._lfp_img).uint16_norm(),
                                           fp,
                                           file_type='tiff')
                        self.sta.progress(100,
                                          self.cfg.params[self.cfg.opt_prnt])

                except FileNotFoundError:
                    # print status
                    self.sta.status_msg(
                        '{0} not found'.format(os.path.basename(
                            self._lfp_path)),
                        self.cfg.params[self.cfg.opt_prnt])
                    self.sta.progress(100, self.cfg.params[self.cfg.opt_prnt])
                    self.sta.error = True
                except Exception as e:
                    # unrecognized LFP file type
                    if not obj.json_dict:
                        raise LfpTypeError(e)
                    else:
                        raise PlenopticamError(e)
        else:
            try:
                # read and decode generic image file type
                self._lfp_img = misc.load_img_file(self._lfp_path)
            except TypeError as e:
                raise LfpTypeError(e)

            try:
                # try to load json file (if present)
                json_dict = self.cfg.load_json(self._lfp_path)
                self.cfg.lfpimg = LfpDecoder.filter_json(json_dict)
            except:
                pass

        # write json file
        self.cfg.save_params()

        return True