def main(self): # load previously calculated calibration and aligned data self.cfg.load_cal_data() if self._lfp_img_align is None: self.load_pickle_file() self.load_lfp_metadata() # micro image crop lfp_obj = LfpCropper(lfp_img_align=self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self._lfp_img_align = lfp_obj.lfp_img_align del lfp_obj # rearrange light-field to sub-aperture images if self.cfg.params[self.cfg.opt_view]: lfp_obj = LfpRearranger(self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self.vp_img_linear = lfp_obj.vp_img_arr del lfp_obj # remove outliers if option is set if self.cfg.params[self.cfg.opt_lier]: obj = LfpOutliers(vp_img_arr=self.vp_img_linear, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_linear = obj.vp_img_arr del obj # color equalization if self.cfg.params[self.cfg.opt_colo]: obj = LfpColorEqualizer(vp_img_arr=self.vp_img_linear, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_linear = obj.vp_img_arr del obj # copy light-field for refocusing process prior to contrast alignment and export self.vp_img_arr = self.vp_img_linear.copy() if self.vp_img_linear is not None else None # color management automation obj = LfpContrast(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_arr = obj.vp_img_arr del obj # reduction of hexagonal sampling artifacts if self.cfg.params[self.cfg.opt_arti]: obj = HexCorrector(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_arr = obj.vp_img_arr del obj # write viewpoint data to hard drive if self.cfg.params[self.cfg.opt_view]: obj = LfpExporter(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.write_viewpoint_data() del obj return True
def __init__(self, lfp_img, cfg, sta=None, method='cubic'): # input variables self._lfp_img = lfp_img[..., np.newaxis] if len( lfp_img.shape) == 2 else lfp_img # add 3rd axis for 2D image self.cfg = cfg self.sta = sta if sta is not None else misc.PlenopticamStatus() # internal variables self._METHOD = method self._CENTROIDS = np.asarray(self.cfg.calibs[self.cfg.mic_list]) self._M = LfpCropper.pitch_max(self.cfg.calibs[self.cfg.mic_list]) self._C = int((self._M - 1) / 2) self._LENS_Y_MAX = int(max(self._CENTROIDS[:, 2])) self._LENS_X_MAX = int(max(self._CENTROIDS[:, 3])) self._DIMS = self._lfp_img.shape if len( self._lfp_img.shape) == 3 else None # output variable self._lfp_out = np.zeros(lfp_img.shape)
def __init__(self, *args, **kwargs): # input variables self._lfp_img = kwargs['lfp_img'] if 'lfp_img' in kwargs else None self._wht_img = kwargs['wht_img'] if 'wht_img' in kwargs else None self.cfg = kwargs['cfg'] if 'cfg' in kwargs else PlenopticamConfig() self.sta = kwargs['sta'] if 'sta' in kwargs else PlenopticamStatus() # add 3rd axis for 2D image self._lfp_img = self._lfp_img[..., np.newaxis] if len(self._lfp_img.shape) == 2 else self._lfp_img # convert to float self._lfp_img = self._lfp_img.astype('float64') self._wht_img = self._wht_img.astype('float64') self._CENTROIDS = np.asarray(self.cfg.calibs[self.cfg.mic_list]) self._M = LfpCropper.pitch_max(self.cfg.calibs[self.cfg.mic_list]) self._C = int((self._M-1)/2) self._LENS_Y_MAX = int(max(self._CENTROIDS[:, 2])) self._LENS_X_MAX = int(max(self._CENTROIDS[:, 3])) self._DIMS = self._lfp_img.shape if len(self._lfp_img.shape) == 3 else None
def main(self): self.cfg.load_cal_data() # micro image crop if not self.sta.interrupt: lfp_obj = LfpCropper(self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self._lfp_img_align = lfp_obj.lfp_img_align del lfp_obj # viewpoint images if self.cfg.params[self.cfg.opt_view] and not self.sta.interrupt: lfp_obj = LfpRearranger(self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self._vp_img_arr = lfp_obj.vp_img_arr del lfp_obj # refocused image stack if self.cfg.params[self.cfg.opt_refo] and not self.sta.interrupt: lfp_obj = LfpRefocuser(vp_img_arr=self._vp_img_arr, cfg=self.cfg, sta=self.sta) lfp_obj.main() self._refo_stack = lfp_obj.refo_stack del lfp_obj # scheimpflug focus if self.cfg.params[self.cfg.opt_pflu] != 'off' and not self.sta.interrupt: lfp_obj = LfpScheimpflug(refo_stack=self._refo_stack, cfg=self.cfg, sta=self.sta) lfp_obj.main() del lfp_obj # print status self.sta.status_msg('Export finished', opt=True) self.sta.progress(100, opt=True) return True
def main(self): self.cfg.load_cal_data() # micro image crop lfp_obj = LfpCropper(lfp_img_align=self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self._lfp_img_align = lfp_obj.lfp_img_align del lfp_obj # viewpoint images if self.cfg.params[self.cfg.opt_view] and not self.sta.interrupt: lfp_obj = LfpRearranger(self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self.vp_img_arr = lfp_obj.vp_img_arr del lfp_obj # histogram equalization if self.cfg.params[self.cfg.opt_cont] and not self.sta.interrupt: obj = HistogramEqualizer(img=self.vp_img_arr) self.vp_img_arr = obj.lum_eq() #self.vp_img_arr = obj.awb_eq() del obj # remove hot pixels if option is set if self.cfg.params[self.cfg.opt_hotp] and not self.sta.interrupt: obj = LfpHotPixels(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_arr = obj.vp_img_arr del obj # color equalization if self.cfg.params[self.cfg.opt_colo] and not self.sta.interrupt: obj = LfpColorEqualizer(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_arr = obj._vp_img_arr del obj if not self.sta.interrupt: obj = LfpContrast(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta, p_lo=0.005, p_hi=0.999) # automatic white balance if self.cfg.params[self.cfg.opt_awb_]: obj.auto_wht_bal() else: obj.channel_bal() obj.p_lo = 0 obj.p_hi = 1 # automatic saturation if self.cfg.params[self.cfg.opt_sat_]: obj.sat_bal() self.vp_img_arr = obj.vp_img_arr del obj # write viewpoint data to hard drive if self.cfg.params[self.cfg.opt_view] and not self.sta.interrupt: obj = LfpExporter(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.write_viewpoint_data() del obj return True
def main(self): self.cfg.load_cal_data() # micro image crop lfp_obj = LfpCropper(lfp_img_align=self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self._lfp_img_align = lfp_obj.lfp_img_align del lfp_obj # rearrange light-field to sub-aperture images if self.cfg.params[self.cfg.opt_view] and not self.sta.interrupt: lfp_obj = LfpRearranger(self._lfp_img_align, cfg=self.cfg, sta=self.sta) lfp_obj.main() self.vp_img_arr = lfp_obj.vp_img_arr del lfp_obj # remove outliers if option is set if self.cfg.params[self.cfg.opt_lier] and not self.sta.interrupt: obj = LfpOutliers(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_arr = obj.vp_img_arr del obj # color equalization if self.cfg.params[self.cfg.opt_colo] and not self.sta.interrupt: obj = LfpColorEqualizer(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta) obj.main() self.vp_img_arr = obj.vp_img_arr del obj # copy light-field for refocusing process prior to contrast alignment and export vp_img_exp = self.vp_img_arr.copy() # color management automation if not self.sta.interrupt: obj = LfpContrast(vp_img_arr=vp_img_exp, cfg=self.cfg, sta=self.sta) obj.main() vp_img_exp = obj.vp_img_arr del obj # reduction of hexagonal sampling artifacts if self.cfg.params[self.cfg.opt_arti] and not self.sta.interrupt: obj = HexCorrector(vp_img_arr=vp_img_exp, cfg=self.cfg, sta=self.sta) obj.main() vp_img_exp = obj.vp_img_arr del obj # write viewpoint data to hard drive if self.cfg.params[self.cfg.opt_view] and not self.sta.interrupt: obj = LfpExporter(vp_img_arr=vp_img_exp, cfg=self.cfg, sta=self.sta) obj.write_viewpoint_data() del obj return True
def main(self): ''' cropping micro images to square shape while interpolating around their detected center (MIC) ''' centroids = np.asarray(self.cfg.calibs[self.cfg.mic_list]) patch_size = LfpCropper.pitch_max(self.cfg.calibs[self.cfg.mic_list]) lens_y_max = int(max(centroids[:, 2])) lens_x_max = int(max(centroids[:, 3])) m, n, P = self.lfp_raw.shape if len( self.lfp_raw.shape) == 3 else (self.lfp_raw.shape[0], self.lfp_raw.shape[1], 1) # initialize variables required for micro image cropping process c = int((patch_size - 1) / 2) # print status self.sta.status_msg('Light field alignment', self.cfg.params[self.cfg.opt_prnt]) if self.cfg.calibs[self.cfg.pat_type] == 'rec': self._lfp_out = np.zeros( [lens_y_max * patch_size, lens_x_max * patch_size, P]) # iterate over each MIC for ly in range(lens_y_max): for lx in range(lens_x_max): # find MIC by indices curr_mic = centroids[(centroids[:, 3] == lx) & (centroids[:, 2] == ly), [0, 1]] # interpolate each micro image with its MIC as the center with consistent micro image size window = self.lfp_raw[int(curr_mic[0]) - c - 1:int(curr_mic[0]) + c + 2, int(curr_mic[1]) - c - 1:int(curr_mic[1]) + c + 2] self._lfp_out[ly * patch_size:(ly+1) * patch_size, lx * patch_size:(lx+1) * patch_size] = \ self._patch_align(window, curr_mic, method=self._method)[1:-1, 1:-1] # check interrupt status if self.sta.interrupt: return False # print progress status for on console self.sta.progress((ly + 1) / lens_y_max * 100, self.cfg.params[self.cfg.opt_prnt]) elif self.cfg.calibs[self.cfg.pat_type] == 'hex': patch_stack = np.zeros([lens_x_max, patch_size, patch_size, P]) hex_stretch = int(np.round(2 * lens_x_max / np.sqrt(3))) interpol_stack = np.zeros([hex_stretch, patch_size, patch_size, P]) self._lfp_out = np.zeros( [lens_y_max * patch_size, hex_stretch * patch_size, P]) # check if lower neighbor of upper left MIC is shifted to left or right hex_odd = self._get_hex_direction(centroids) # iterate over each MIC for ly in range(lens_y_max): for lx in range(lens_x_max): # find MIC by indices curr_mic = centroids[(centroids[:, 3] == lx) & (centroids[:, 2] == ly), [0, 1]] # interpolate each micro image with its MIC as the center with consistent micro image size window = self.lfp_raw[int(curr_mic[0]) - c - 1:int(curr_mic[0]) + c + 2, int(curr_mic[1]) - c - 1:int(curr_mic[1]) + c + 2] patch_stack[lx, :, :] = self._patch_align( window, curr_mic, method=self._method)[1:-1, 1:-1] # do interpolation of two adjacent micro images if np.mod(ly + hex_odd, 2) and lx > 0: patch_stack[ lx - 1, :, :, :] = (patch_stack[lx - 1, :, :, :] + patch_stack[lx, :, :, :]) / 2. # image stretch interpolation in x-direction to compensate for hex-alignment for y in range(patch_size): for x in range(patch_size): for p in range(P): # stack of micro images elongated in x-direction interpol_vals = np.arange( hex_stretch) / hex_stretch * lens_x_max interpol_stack[:, y, x, p] = np.interp( interpol_vals, range(lens_x_max), patch_stack[:, y, x, p]) self._lfp_out[ly * patch_size:ly * patch_size + patch_size, :] = np.concatenate( interpol_stack, axis=1).reshape( (patch_size, hex_stretch * patch_size, P)) # check interrupt status if self.sta.interrupt: return False # print progress status self.sta.progress((ly + 1) / lens_y_max * 100, self.cfg.params[self.cfg.opt_prnt]) elif self.cfg.calibs[self.cfg.pat_type] == 'hex_alt': hex_stretch = int(np.round(2 * lens_x_max / np.sqrt(3))) interpol_stack = np.zeros([hex_stretch, patch_size, patch_size, P]) self._lfp_out = np.zeros( [lens_y_max * patch_size, hex_stretch * patch_size, P]) # get interpolation weights according to micro lens arrangement tb_weight = 1 / (1 + np.sqrt(3)) / 2 lr_weight = np.sqrt(3) / (1 + np.sqrt(3)) / 2 # check if lower neighbor of upper left MIC is shifted to left or right hex_odd = self._get_hex_direction(centroids) # iterate over each MIC for ly in range(lens_y_max): patch_stack = np.zeros( [2 * lens_x_max + 1, patch_size, patch_size, P]) for lx in range(lens_x_max): # interpolate each micro image with its MIC as the center with consistent micro image size r_mic = centroids[(centroids[:, 3] == lx) & (centroids[:, 2] == ly), [0, 1]] r_win = self.lfp_raw[int(r_mic[0]) - c - 1:int(r_mic[0]) + c + 2, int(r_mic[1]) - c - 1:int(r_mic[1]) + c + 2, :] r = self._patch_align(r_win, r_mic, method=self._method)[1:-1, 1:-1, :] patch_stack[2 * lx, :, :, :] = r # do bilinear interpolation of adjacent micro images (do linear if at borders) if lx > 0: l = patch_stack[2 * lx - 2, :, :, :] if ly > 0 and lens_y_max - ly > 0: # interpolate upper adjacent patch while considering hex shift alignment (take same column if row "left-handed", next otherwise) t_mic = centroids[(centroids[:, 3] == lx - np.mod(ly + hex_odd, 2)) & (centroids[:, 2] == ly - 1), [0, 1]] t_win = self.lfp_raw[int(t_mic[0]) - c - 1:int(t_mic[0]) + c + 2, int(t_mic[1]) - c - 1:int(t_mic[1]) + c + 2, :] t = self._patch_align(t_win, t_mic, method=self._method)[1:-1, 1:-1, :] b_mic = centroids[(centroids[:, 3] == lx - np.mod(ly + hex_odd, 2)) & (centroids[:, 2] == ly + 1), [0, 1]] b_win = self.lfp_raw[int(b_mic[0]) - c - 1:int(b_mic[0]) + c + 2, int(b_mic[1]) - c - 1:int(b_mic[1]) + c + 2, :] b = self._patch_align(b_win, b_mic, method=self._method)[1:-1, 1:-1, :] patch_stack[ 2 * lx - 1, :, :, :] = t * tb_weight + b * tb_weight + l * lr_weight + r * lr_weight else: patch_stack[2 * lx - 1, :, :, :] = (l + r) / 2. # shift patch_stack by adding one patch to the front to compensate for hexagonal structure if np.mod( ly + hex_odd - 1, 2 ): # shift first and every other row to left if "they are right-handed" patch_stack[1:, :, :, :] = patch_stack[:-1, :, :, :] patch_stack[0, :, :, :] = np.zeros_like( patch_stack[0, :, :, :]) # image stretch interpolation in x-direction to compensate for hex-alignment for y in range(patch_size): for x in range(patch_size): for p in range(P): # stack of micro images shrinked in x-direction interpol_vals = np.arange( hex_stretch) / hex_stretch * (2 * lens_x_max + 1) interpol_stack[:, y, x, p] = np.interp( interpol_vals, range(2 * lens_x_max + 1), patch_stack[:, y, x, p]) self._lfp_out[ly * patch_size:ly * patch_size + patch_size, :] = np.concatenate( interpol_stack, axis=1).reshape( (patch_size, hex_stretch * patch_size, P)) # check interrupt status if self.sta.interrupt: return False # print progress status self.sta.progress((ly + 1) / lens_y_max * 100, self.cfg.params[self.cfg.opt_prnt]) self._write_lfp_align() return True