def export_refo_stack(self, type=None): refo_stack = Normalizer(np.asarray(self._refo_stack)).uint16_norm() # create folder string = '' if self.cfg.params[self.cfg.opt_refo] == 2 or self.cfg.params[ self.cfg.opt_refi]: string = 'subpixel_' elif self.cfg.params[self.cfg.opt_refo] == 1 or self.cfg.params[ self.cfg.opt_view]: string = '' 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 = range(*self.cfg.params[self.cfg.ran_refo])[i] # account for sub-pixel precise depth value a = round(float(a) / self._M, 2) if self.cfg.params[self.cfg.opt_refi] else a # write image file misc.save_img_file(refo_img, os.path.join(folder_path, str(a)), file_type=type) return True
def main(self): # check interrupt status if self.sta.interrupt: return False # print status self.sta.status_msg('Scheimpflug extraction \n', self.cfg.params[self.cfg.opt_prnt]) self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt]) # create output folder misc.mkdir_p(self.fp) # iterate through directions for direction in list(c.PFLU_VALS): self.cfg.params[self.cfg.opt_pflu] = direction self.sta.status_msg(direction + ':') if self.refo_stack is not None: self.scheimpflug_from_stack() elif self.lfp_img is not None: self.scheimpflug_from_scratch() return True
def export_refo_stack(refo_stack, cfg, type='tiff'): refo_stack = misc.uint16_norm(refo_stack) patch_len = cfg.params[cfg.ptc_leng] # create folder string = '' if cfg.params[cfg.opt_refo] == 2 or cfg.params[cfg.opt_refi]: string = 'subpixel_' elif cfg.params[cfg.opt_refo] == 1 or cfg.params[cfg.opt_view]: string = '' folder_path = os.path.join(cfg.params[cfg.lfp_path].split('.')[0], 'refo_' + string + str(patch_len) + 'px') misc.mkdir_p(folder_path) for i, refo_img in enumerate(refo_stack): # get depth plane number for filename a = range(*cfg.params[cfg.ran_refo])[i] # account for sub-pixel precise depth value a = round(float(a)/patch_len, 2) if cfg.params[cfg.opt_refi] else a # write image file misc.save_img_file(refo_img, os.path.join(folder_path, str(a)), type=type) return True
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 = 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) # print status percentage = (((j*self._M+i+1)/self._M**2)*100) self.sta.progress(percentage, self.cfg.params[self.cfg.opt_prnt]) return True
def test_cal(self): # set config for unit test purposes sta = PlenopticamStatus() cfg = PlenopticamConfig() cfg.reset_values() cfg.params[cfg.opt_dbug] = False cfg.params[ cfg. opt_prnt] = False # prevent Travis CI to terminate after reaching 4MB logfile size cfg.params[cfg.opt_vign] = False cfg.params[cfg.opt_sat_] = True for fn_lfp, fn_wht in zip(self.fnames_lfp, self.fnames_wht): # generate console output to prevent abort in Travis CI print(fn_wht) # update file paths and calibration data in config cfg.params[cfg.lfp_path] = os.path.join(self.fp, fn_lfp) cfg.params[cfg.cal_path] = os.path.join(self.fp, fn_wht) # create folder (if it doesn't already exist) mkdir_p(os.path.splitext(cfg.params[cfg.lfp_path])[0]) # test light field calibration wht_img = load_img_file(cfg.params[cfg.cal_path]) cal_obj = LfpCalibrator(wht_img=wht_img, cfg=cfg, sta=sta) ret_val = cal_obj.main() del cal_obj # assertion self.assertEqual(True, ret_val)
def test_custom_cal(self): for fn_lfp, fn_wht in zip(self.loader.opex_fnames_lfp, self.loader.opex_fnames_wht): # generate console output to prevent abort in Travis CI print(fn_wht) # update file paths and calibration data in config self.cfg.params[self.cfg.lfp_path] = join(self.fp, fn_lfp) self.cfg.params[self.cfg.cal_path] = join(self.fp, fn_wht) # create folder (if it doesn't already exist) mkdir_p(splitext(self.cfg.params[self.cfg.lfp_path])[0]) # test light field calibration wht_img = load_img_file(self.cfg.params[self.cfg.cal_path]) cal_obj = LfpCalibrator(wht_img=wht_img, cfg=self.cfg, sta=self.sta) ret_val = cal_obj.main() del cal_obj # assertion self.assertEqual(True, ret_val)
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
def crop_imgs(folder, coords_lists): img_tiles, files = list(), list() exts = ('tif', 'tiff', 'png') misc.mkdir_p(os.path.join(folder, 'auto-crop')) files = [ f for f in os.listdir(folder) if f.endswith(exts) and not f.startswith('.') ] files.sort() for i, file in enumerate(files): coords_nested = coords_lists[i] for j, coords in enumerate(coords_nested): if coords[0] != 0 and coords[1] != 0: cy, cx, h, w = coords img = misc.load_img_file(os.path.join(folder, file)) tile = img[cy - h // 2:cy + h // 2, cx - w // 2:cx + w // 2, ...] img_tiles.append(tile) fn, ext = os.path.splitext(file) misc.save_img_file(tile, os.path.join(folder, 'auto-crop', fn + '_crop' + str(j)), 'png', tag=True) return img_tiles, files
def test_lfp(self): # set config for unit test purposes cfg = PlenopticamConfig() cfg.params[cfg.opt_dbug] = True for fn_lfp, fn_wht in zip(self.fnames_lfp, self.fnames_wht): # update file paths and calibration data in config cfg.params[cfg.lfp_path] = os.path.join(self.fp, fn_lfp) cfg.params[cfg.cal_path] = os.path.join(self.fp, fn_wht) cfg.params[cfg.cal_meta] = os.path.splitext( cfg.params[cfg.cal_path])[0] + '.json' cfg.load_cal_data() # create folder (if it doesn't already exist) misc.mkdir_p(os.path.splitext(cfg.params[cfg.lfp_path])[0]) # test light field alignment lfp_img = misc.load_img_file(cfg.params[cfg.lfp_path]) lfp_obj = LfpAligner(lfp_img=lfp_img, cfg=cfg, sta=None) ret_val = lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj # assertion self.assertEqual(True, ret_val) # test light field extraction lfp_obj = LfpExtractor(lfp_img_align=lfp_img, cfg=cfg, sta=None) ret_val = lfp_obj.main() del lfp_obj # assertion self.assertEqual(True, ret_val)
def download_data(self, url, fp=None): """ download data form provided url string """ # path handling self.fp = fp if fp is not None else self.fp mkdir_p(self.fp) if not os.path.exists(self.fp) else None # skip download if file exists if os.path.exists(os.path.join(self.fp, os.path.basename(url))): print('Download skipped as %s already exists' % os.path.basename(url)) return None print('Downloading file %s to %s' % (os.path.basename(url), self.fp)) with open(os.path.join(self.fp, os.path.basename(url)), 'wb') as f: # establish internet connection for data download try: r = requests.get(url, stream=True) total_length = r.headers.get('content-length') except requests.exceptions.ConnectionError: raise (Exception('Check your internet connection, which is required for downloading test data.')) if total_length is None: # no content length header f.write(r.content) else: dl = 0 total_length = int(total_length) for data in r.iter_content(chunk_size=4096): dl += len(data) f.write(data) self.sta.progress(dl/total_length * 100, self.cfg.params[self.cfg.opt_prnt]) print('\n Finished download of %s' % os.path.basename(url))
def test_cal(self): # set config for unit test purposes sta = PlenopticamStatus() cfg = PlenopticamConfig() cfg.reset_values() cfg.params[cfg.opt_dbug] = False cfg.params[cfg.opt_prnt] = True for fn_lfp, fn_wht in zip(self.fnames_lfp, self.fnames_wht): # update file paths and calibration data in config cfg.params[cfg.lfp_path] = os.path.join(self.fp, fn_lfp) cfg.params[cfg.cal_path] = os.path.join(self.fp, fn_wht) # create folder (if it doesn't already exist) mkdir_p(os.path.splitext(cfg.params[cfg.lfp_path])[0]) # test light field calibration wht_img = load_img_file(cfg.params[cfg.cal_path]) cal_obj = LfpCalibrator(wht_img=wht_img, cfg=cfg, sta=sta) ret_val = cal_obj.main() del cal_obj # assertion self.assertEqual(True, ret_val)
def process(self): # reset self.var_init() # status update self.sta.status_msg('Loading data', self.cfg.params[self.cfg.opt_prnt]) self.sta.progress(None, self.cfg.params[self.cfg.opt_prnt]) # disable button activity self.toggle_btn_list(self.all_btn_list) self.cmd_wid.btn_list[3].config(text='Stop') # read light field photo and calibration source paths self.fetch_paths() # remove output folder if option is set misc.rmdir_p( self.cfg.exp_path) if self.cfg.params[self.cfg.dir_remo] else None # remove calibrated light-field if calibration or devignetting option is set if self.cfg.params[self.cfg.opt_cali] or self.cfg.params[ self.cfg.opt_vign]: misc.rm_file(join(self.cfg.exp_path, 'lfp_img_align.pkl')) if self.cfg.params[self.cfg.opt_cali]: misc.rm_file(self.cfg.params[self.cfg.cal_meta]) # create output data folder (prevent override) misc.mkdir_p(self.cfg.exp_path, self.cfg.params[self.cfg.opt_prnt]) # put tasks in the job queue to be run for task_info in ((self.load_lfp, self.cfg.cond_load_limg, self.cfg.params[self.cfg.lfp_path]), (self.auto_find, self.cfg.cond_auto_find), (self.load_lfp, self.cfg.cond_load_wimg, self.cfg.params[self.cfg.cal_path], True), (self.cal, self.cfg.cond_perf_cali), (self.cfg.load_cal_data, self.cfg.cond_lfp_align), (self.lfp_align, self.cfg.cond_lfp_align), (self.load_pickle_file, True), (self.lfp_extract, True), (self.lfp_refo, self.cfg.params[self.cfg.opt_refo]), (self.finish, True)): self.job_queue.put(task_info) # start polling self.after(POLLING_RATE, self.poll) # cancel if file paths not provided self.sta.validate(checklist=[ self.cfg.params[self.cfg.lfp_path], self.cfg.params[self.cfg.cal_path] ], msg='Canceled due to missing image file path')
def process(self): # status update self.sta.status_msg('Starting ...', self.cfg.params[self.cfg.opt_dbug]) self.sta.progress(None, self.cfg.params[self.cfg.opt_dbug]) # reset self.var_init() self.sta.interrupt = False # disable button activity self.toggle_btn_list(self.cmd_wid.btn_list + self.fil_wid.btn_list) # read light field photo and calibration source paths self.fetch_paths() # remove output folder if option is set misc.rmdir_p(self.cfg.params[self.cfg.lfp_path].split('.') [0]) if self.cfg.params[self.cfg.dir_remo] else None # remove calibrated light-field if calibration option is set if self.cfg.params[self.cfg.opt_cali]: misc.rmdir_p( join(self.cfg.params[self.cfg.lfp_path].split('.')[0], 'lfp_img_align.pkl')) misc.rmdir_p(self.cfg.params[self.cfg.cal_meta]) # create output data folder misc.mkdir_p(self.cfg.params[self.cfg.lfp_path].split('.')[0], self.cfg.params[self.cfg.opt_prnt]) # put tasks in the job queue to be run for task_info in ((self.load_lfp, self.cfg.load_limg_cond0, self.cfg.params[self.cfg.lfp_path]), (self.auto_find, self.cfg.auto_find_cond1), (self.load_lfp, self.cfg.load_wimg_cond2, self.cfg.params[self.cfg.cal_path], True), (self.cal, self.cfg.cali_meta_cond3), (self.cfg.load_cal_data, self.cfg.auto_find_cond1), (self.lfp_align, self.cfg.lfp_align_cond4), (self.load_pickle_file, True), (self.lfp_extract, True)): self.job_queue.put(task_info) # start polling self.after(POLLING_RATE, self.poll) # cancel if file paths not provided self.sta.validate(checklist=[ self.cfg.params[self.cfg.lfp_path], self.cfg.params[self.cfg.cal_path] ], msg='Canceled due to missing image file path')
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'))
def save_refo_slice(self, a, refo_img, folder_path=None, file_type=None, string=None): string = 'subpixel_' if self.cfg.params[self.cfg.opt_refi] and string is None else string if folder_path is None: folder_path = os.path.join(self.cfg.exp_path, 'refo_' + string + str(self._M) + 'px') misc.mkdir_p(folder_path) # account for sub-pixel precise depth value a = round(float(a) / self._M, 2) if self.cfg.params[self.cfg.opt_refi] else a # write image file misc.save_img_file(refo_img, os.path.join(folder_path, str(a)), file_type=file_type) return True
def test_lfp(self): # set config for unit test purposes sta = PlenopticamStatus() cfg = PlenopticamConfig() cfg.reset_values() cfg.params[cfg.opt_dbug] = False cfg.params[ cfg. opt_prnt] = False # prevent Travis CI to terminate after reaching 4MB logfile size for fn_lfp, fn_wht in zip(self.fnames_lfp, self.fnames_wht): # generate console output to prevent abort in Travis CI print(fn_lfp) # update file paths and calibration data in config cfg.params[cfg.lfp_path] = os.path.join(self.fp, fn_lfp) cfg.params[cfg.cal_path] = os.path.join(self.fp, fn_wht) cfg.params[cfg.cal_meta] = os.path.splitext( cfg.params[cfg.cal_path])[0] + '.json' cfg.load_cal_data() # create folder (if it doesn't already exist) mkdir_p(os.path.splitext(cfg.params[cfg.lfp_path])[0]) # test light field alignment lfp_img = load_img_file(cfg.params[cfg.lfp_path]) lfp_obj = LfpAligner(lfp_img=lfp_img, cfg=cfg, sta=sta) ret_val = lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj # assertion self.assertEqual(True, ret_val) # test light field extraction lfp_obj = LfpExtractor(lfp_img_align=lfp_img, cfg=cfg, sta=sta) lfp_obj.main() vp_img_arr = lfp_obj.vp_img_arr del lfp_obj lfp_obj = LfpRefocuser(vp_img_arr=vp_img_arr, cfg=cfg, sta=sta) lfp_obj.main() del lfp_obj # assertion self.assertEqual(True, ret_val)
def test_custom_lfp(self): for fn_lfp, fn_wht in zip(self.loader.opex_fnames_lfp, self.loader.opex_fnames_wht): # generate console output to prevent abort in Travis CI print(fn_lfp) # update file paths and calibration data in config self.cfg.params[self.cfg.lfp_path] = join(self.fp, fn_lfp) self.cfg.params[self.cfg.cal_path] = join(self.fp, fn_wht) self.cfg.params[self.cfg.cal_meta] = splitext( self.cfg.params[self.cfg.cal_path])[0] + '.json' self.cfg.load_cal_data() # create folder (if it doesn't already exist) mkdir_p(splitext(self.cfg.params[self.cfg.lfp_path])[0]) # test light field alignment lfp_img = load_img_file(self.cfg.params[self.cfg.lfp_path]) lfp_obj = LfpAligner(lfp_img=lfp_img, cfg=self.cfg, sta=self.sta) ret_val = lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj # assertion self.assertEqual(True, ret_val) # test light field extraction lfp_obj = LfpExtractor(lfp_img_align=lfp_img, cfg=self.cfg, sta=self.sta) ret_val = lfp_obj.main() vp_img_arr = lfp_obj.vp_img_arr del lfp_obj # assertion self.assertEqual(True, ret_val) lfp_obj = LfpRefocuser(vp_img_arr=vp_img_arr, cfg=self.cfg, sta=self.sta) ret_val = lfp_obj.main() del lfp_obj # assertion self.assertEqual(True, ret_val)
def export_viewpoints(vp_img_arr, cfg, type='tiff'): ptc_leng = cfg.params[cfg.ptc_leng] # create folder folderpath = os.path.join(cfg.params[cfg.lfp_path].split('.')[0], 'viewpoints_' + str(ptc_leng) + 'px') misc.mkdir_p(folderpath) # normalize image array to 16-bit unsigned integer vp_img_arr = misc.uint16_norm(vp_img_arr) # 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)), type=type) return True
def save_params(self, fp=None): if not fp: fp = os.path.join(self._dir_path, 'cfg.json') try: # create config folder (if not already present) misc.mkdir_p(self._dir_path) # write config file with open(fp, 'w+') as f: json.dump(self.params, f, sort_keys=True, indent=4, cls=NumpyTypeEncoder) except PermissionError: pass # raise PlenopticamError('\n\nGrant permission to write to the config file '+fp) return True
def save_refo_slice(self, a, refo_img, folder_path=None, file_type=None, string=None): string = 'subpixel_' if self.cfg.params[ self.cfg.opt_refi] and string is None else string if folder_path is None: folder_path = os.path.join(self.cfg.exp_path, 'refo_' + string + str(self._M) + 'px') misc.mkdir_p(folder_path) # write image file misc.save_img_file(refo_img, os.path.join(folder_path, str(a)), file_type=file_type) return True
def process(self): # status update self.sta.status_msg('Starting ...', self.cfg.params[self.cfg.opt_dbug]) self.sta.progress(None, self.cfg.params[self.cfg.opt_dbug]) # reset self.var_init() self.sta.interrupt = False # disable button activity self.toggle_btn_list(self.cmd_wid.btn_list + self.fil_wid.btn_list) # read light field photo and calibration source paths self.fetch_paths() # safely remove output folder if option is set misc.rmdir_p(self.cfg.params[self.cfg.lfp_path].split('.') [0]) if self.cfg.params[self.cfg.dir_remo] else None # safely create output data folder misc.mkdir_p(self.cfg.params[self.cfg.lfp_path].split('.')[0], self.cfg.params[self.cfg.opt_prnt]) # put tasks in the job queue to be run for task_info in ((self.load_lfp, self.cond0, self.cfg.params[self.cfg.lfp_path]), (self.auto_find, self.cond1), (self.load_lfp, self.cond2, self.cfg.params[self.cfg.cal_path], True), (self.cal, self.cond3), (self.cfg.load_cal_data, True), (self.lfp_align, self.cond4), (self.load_pickle_file, True), (self.lfp_extract, True)): self.job_queue.put(task_info) # start polling self.after(POLLING_RATE, self.poll)
def save_json(fp=None, **kwargs): # filename and file path handling if fp is not None: # json extension handling if os.path.splitext(fp)[-1] != '.json': fn = os.path.basename(os.path.splitext(fp)[0]) + '.json' fp = os.path.join(os.path.dirname(os.path.splitext(fp)[0]), fn) # create folder misc.mkdir_p(os.path.dirname(fp), False) # save calibration data as json file json_dict = kwargs['json_dict'] if 'json_dict' in kwargs else kwargs try: with open(fp, 'wt') as f: json.dump(json_dict, f, sort_keys=True, indent=4) except: return False return True
def test_illum(self): # instantiate config and status objects cfg = PlenopticamConfig() cfg.default_values() sta = PlenopticamStatus() # enable options in config to test more algorithms cfg.params[cfg.cal_meth] = 'grid-fit' cfg.params[cfg.opt_vign] = True cfg.params[cfg.opt_rota] = True cfg.params[cfg.opt_refi] = True cfg.params[cfg.opt_pflu] = True cfg.params[cfg.opt_arti] = True cfg.params[cfg.opt_lier] = True cfg.params[cfg.opt_cont] = True cfg.params[cfg.opt_awb_] = True cfg.params[cfg.opt_sat_] = True cfg.params[cfg.ran_refo] = [0, 1] # compute 3x3 viewpoints only (to reduce computation time) cfg.params[cfg.ptc_leng] = 3 # skip progress prints (prevent Travis from terminating due to reaching 4MB logfile size) sta.prog_opt = False # print current process message (to prevent Travis from stopping after 10 mins) cfg.params[cfg.opt_prnt] = True # use pre-loaded calibration dataset wht_list = [ file for file in os.listdir(self.fp) if file.startswith('caldata') ] lfp_list = [ file for file in os.listdir(self.fp) if file.endswith(('lfr', 'lfp')) ] cfg.params[cfg.cal_path] = os.path.join(self.fp, wht_list[0]) for lfp_file in lfp_list: cfg.params[cfg.lfp_path] = os.path.join(self.fp, lfp_file) print('\nCompute image %s' % os.path.basename(cfg.params[cfg.lfp_path])) # decode light field image obj = LfpReader(cfg, sta) ret = obj.main() # use third of original image size (to prevent Travis from stopping due to memory error) crop_h, crop_w = obj.lfp_img.shape[0] // 3, obj.lfp_img.shape[ 1] // 3 crop_h, crop_w = crop_h + crop_h % 2, crop_w + crop_w % 2 # use even number for correct Bayer arrangement lfp_img = obj.lfp_img[crop_h:-crop_h, crop_w:-crop_w] del obj self.assertEqual(True, ret) # create output data folder mkdir_p(cfg.exp_path, cfg.params[cfg.opt_prnt]) if not cfg.cond_meta_file(): # automatic calibration data selection obj = CaliFinder(cfg, sta) ret = obj.main() wht_img = obj.wht_bay[ crop_h:-crop_h, crop_w:-crop_w] if obj.wht_bay is not None else obj.wht_bay del obj self.assertEqual(True, ret) meta_cond = not (os.path.exists(cfg.params[cfg.cal_meta]) and cfg.params[cfg.cal_meta].lower().endswith('json')) if meta_cond or cfg.params[cfg.opt_cali]: # perform centroid calibration obj = LfpCalibrator(wht_img, cfg, sta) ret = obj.main() cfg = obj.cfg del obj self.assertEqual(True, ret) # load calibration data cfg.load_cal_data() # write centroids as png file if wht_img is not None: obj = CentroidDrawer(wht_img, cfg.calibs[cfg.mic_list], cfg) ret = obj.write_centroids_img( fn=os.path.join(cfg.exp_path, 'wht_img+mics.png')) del obj self.assertEqual(True, ret) # check if light field alignment has been done before if cfg.cond_lfp_align(): # align light field obj = LfpAligner(lfp_img, cfg, sta, wht_img) ret = obj.main() del obj self.assertEqual(True, ret) # load previously computed light field alignment with open(os.path.join(cfg.exp_path, 'lfp_img_align.pkl'), 'rb') as f: lfp_img_align = pickle.load(f) # extract viewpoint data CaliFinder(cfg).main() obj = LfpExtractor(lfp_img_align, cfg=cfg, sta=sta) ret = obj.main() vp_img_arr = obj.vp_img_arr del obj self.assertEqual(True, ret) # do refocusing if cfg.params[cfg.opt_refo]: obj = LfpRefocuser(vp_img_arr, cfg=cfg, sta=sta) ret = obj.main() del obj self.assertEqual(True, ret) return True
def main(): # program info print("\nPlenoptiCam v%s \n" % __version__) # create config object cfg = PlenopticamConfig() cfg.default_values() # parse options cfg = parse_options(sys.argv[1:], cfg) # instantiate status object sta = misc.PlenopticamStatus() sta.bind_to_interrupt(sys.exit) # set interrupt # force relative paths to be absolute cfg.params[cfg.lfp_path] = os.path.abspath(cfg.params[cfg.lfp_path]) cfg.params[cfg.cal_path] = os.path.abspath(cfg.params[cfg.cal_path]) # collect light field image file name(s) based on provided path if os.path.isdir(cfg.params[cfg.lfp_path]): lfp_filenames = [ f for f in os.listdir(cfg.params[cfg.lfp_path]) if f.lower().endswith(SUPP_FILE_EXT) ] cfg.params[cfg.lfp_path] = os.path.join(cfg.params[cfg.lfp_path], 'dummy.ext') elif not os.path.isfile(cfg.params[cfg.lfp_path]): lfp_filenames = [ misc.select_file(cfg.params[cfg.lfp_path], 'Select plenoptic image') ] else: lfp_filenames = [cfg.params[cfg.lfp_path]] if not cfg.params[cfg.cal_path]: # manual calibration data selection sta.status_msg( '\r Please select white image calibration source manually', cfg.params[cfg.opt_prnt]) # open selection window (at current lfp file directory) to set calibration folder path cfg.params[cfg.cal_path] = misc.select_file( cfg.params[cfg.lfp_path], 'Select calibration image') # provide number of found images to user print("\n %s Image(s) found" % len(lfp_filenames)) # cancel if file paths not provided sta.validate(checklist=lfp_filenames + [cfg.params[cfg.lfp_path]], msg='Canceled due to missing image file path') # iterate through light field image(s) for lfp_filename in sorted(lfp_filenames): # change path to next filename cfg.params[cfg.lfp_path] = os.path.join( os.path.dirname(cfg.params[cfg.lfp_path]), lfp_filename) print(cfg.params[cfg.lfp_path]) sta.status_msg(msg='Process file ' + lfp_filename, opt=cfg.params[cfg.opt_prnt]) # remove output folder if option is set misc.rmdir_p(cfg.exp_path) if cfg.params[cfg.dir_remo] else None try: # decode light field image lfp_obj = lfp_reader.LfpReader(cfg, sta) lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj except Exception as e: misc.PlenopticamError(e) continue # create output data folder misc.mkdir_p(cfg.exp_path, cfg.params[cfg.opt_prnt]) if cfg.cond_auto_find(): # automatic calibration data selection obj = lfp_calibrator.CaliFinder(cfg, sta) obj.main() wht_img = obj.wht_bay del obj else: # load white image calibration file wht_img = misc.load_img_file(cfg.params[cfg.cal_path]) # save settings configuration cfg.save_params() # perform calibration if previously computed calibration data does not exist meta_cond = not (os.path.exists(cfg.params[cfg.cal_meta]) and cfg.params[cfg.cal_meta].lower().endswith('json')) if meta_cond or cfg.params[cfg.opt_cali]: # perform centroid calibration cal_obj = lfp_calibrator.LfpCalibrator(wht_img, cfg, sta) cal_obj.main() cfg = cal_obj.cfg del cal_obj # load calibration data cfg.load_cal_data() # check if light field alignment has been done before if cfg.cond_lfp_align(): # align light field lfp_obj = lfp_aligner.LfpAligner(lfp_img, cfg, sta, wht_img) lfp_obj.main() lfp_obj = lfp_obj.lfp_img del lfp_obj # load previously computed light field alignment with open(os.path.join(cfg.exp_path, 'lfp_img_align.pkl'), 'rb') as f: lfp_img_align = pickle.load(f) # extract viewpoint data lfp_calibrator.CaliFinder(cfg).main() obj = lfp_extractor.LfpExtractor(lfp_img_align, cfg=cfg, sta=sta) obj.main() vp_img_arr = obj.vp_img_arr del obj # do refocusing if cfg.params[cfg.opt_refo]: obj = lfp_refocuser.LfpRefocuser(vp_img_arr, cfg=cfg, sta=sta) obj.main() del obj return True
def __init__(self, *args, **kwargs): super(PlenoptiCamTester, self).__init__(*args, **kwargs) # refer to folder where data will be stored self.fp = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data') mkdir_p(self.fp) if not os.path.exists(self.fp) else None
def main(): # create config object cfg = PlenopticamConfig() cfg.default_values() cfg.reset_values() # parse options cfg = parse_options(sys.argv[1:], cfg) # instantiate status object sta = misc.PlenopticamStatus() sta.bind_to_interrupt(sys.exit) # set interrupt # select light field image(s) considering provided folder or file if os.path.isdir(cfg.params[cfg.lfp_path]): lfp_filenames = [ f for f in os.listdir(cfg.params[cfg.lfp_path]) if f.lower().endswith(SUPP_FILE_EXT) ] elif not os.path.isfile(cfg.params[cfg.lfp_path]): lfp_filenames = [ misc.select_file(cfg.params[cfg.lfp_path], 'Select plenoptic image') ] else: lfp_filenames = [cfg.params[cfg.lfp_path]] if not cfg.params[cfg.cal_path]: # open selection window (at current lfp file directory) to set calibration folder path cfg.params[cfg.cal_path] = misc.select_file( cfg.params[cfg.lfp_path], 'Select calibration image') # cancel if file paths not provided sta.validate(checklist=lfp_filenames + [cfg.params[cfg.lfp_path]], msg='Canceled due to missing image file path') # iterate through light field image(s) for lfp_filename in lfp_filenames: # change path to next filename cfg.params[cfg.lfp_path] = os.path.join( os.path.dirname(cfg.params[cfg.lfp_path]), lfp_filename) sta.status_msg(msg=cfg.params[cfg.lfp_path], opt=cfg.params[cfg.opt_prnt]) try: # decode light field image lfp_obj = lfp_reader.LfpReader(cfg, sta, cfg.params[cfg.lfp_path]) lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj except Exception as e: misc.PlenopticamError(e) continue # create output data folder misc.mkdir_p(cfg.exp_path, cfg.params[cfg.opt_prnt]) if cfg.cond_auto_find: # automatic calibration data selection obj = lfp_calibrator.CaliFinder(cfg, sta) obj.main() wht_img = obj.wht_img del obj else: # manual calibration data selection sta.status_msg( '\r Please select white image calibration source manually', cfg.params[cfg.opt_prnt]) # load white image calibration file wht_img = misc.load_img_file(cfg.params[cfg.cal_path]) # save settings configuration cfg.save_params() # perform calibration if previously computed calibration data does not exist meta_cond = not (os.path.exists(cfg.params[cfg.cal_meta]) and cfg.params[cfg.cal_meta].lower().endswith('json')) if meta_cond or cfg.params[cfg.opt_cali]: # perform centroid calibration cal_obj = lfp_calibrator.LfpCalibrator(wht_img, cfg, sta) cal_obj.main() cfg = cal_obj.cfg del cal_obj # load calibration data cfg.load_cal_data() # check if light field alignment has been done before if cfg.cond_lfp_align: # align light field lfp_obj = lfp_aligner.LfpAligner(lfp_img, cfg, sta, wht_img) lfp_obj.main() lfp_obj = lfp_obj.lfp_img del lfp_obj # load previously computed light field alignment with open(os.path.join(cfg.exp_path, 'lfp_img_align.pkl'), 'rb') as f: lfp_img_align = pickle.load(f) # export light field data lfp_calibrator.CaliFinder(cfg).main() exp_obj = lfp_extractor.LfpExtractor(lfp_img_align, cfg) exp_obj.main() del exp_obj
def main(): # parse options cfg = parse_options(sys.argv[1:]) # instantiate status object sta = misc.PlenopticamStatus() sta.bind_to_interrupt(sys.exit) # set interrupt # set calibration folder path cfg.params[cfg.cal_path] = "/Users/Admin/Pictures/Lytro_Illum/CalibFolder" # select light field image cfg.params[cfg.lfp_path] = misc.select_file(cfg.params[cfg.lfp_path], 'Select plenoptic image') # decode light field image lfp_obj = lfp_reader.LfpReader(cfg, sta, cfg.params[cfg.lfp_path]) lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj # create output data folder misc.mkdir_p(cfg.params[cfg.lfp_path].split('.')[0], cfg.params[cfg.opt_prnt]) # check if light field alignment has been done before if not os.path.exists(os.path.join(cfg.params[cfg.lfp_path].split('.')[0], 'lfp_img_align.pkl')): # manual calibration data selection sta.status_msg('\r Please select white image calibration source manually', cfg.params[cfg.opt_prnt]) # open selection window (at directory where current lfp file is located) cfg.params[cfg.cal_path] = misc.select_file(cfg.params[cfg.lfp_path]) if os.path.isdir(cfg.params[cfg.cal_path]) or cfg.params[cfg.cal_path].endswith('.tar'): # automatic calibration data selection obj = lfp_calibrator.CaliFinder(cfg, sta) obj.main() wht_img = obj.wht_img del obj else: # load white image calibration file wht_img = misc.load_img_file(cfg.params[cfg.cal_path]) # save settings configuration cfg.save_params() # perform calibration if previously computed calibration data does not exist meta_cond = not (os.path.exists(cfg.params[cfg.cal_meta]) and cfg.params[cfg.cal_meta].endswith('json')) if meta_cond or cfg.params[cfg.opt_cali]: # perform centroid calibration cal_obj = lfp_calibrator.LfpCalibrator(wht_img, cfg, sta) cal_obj.main() cfg = cal_obj.cfg del cal_obj # load calibration data cfg.load_cal_data() # align light field lfp_obj = lfp_aligner.LfpAligner(lfp_img, cfg, sta, wht_img) lfp_obj.main() lfp_obj = lfp_obj.lfp_img del lfp_obj # load previously computed light field alignment lfp_img_align = pickle.load(open(os.path.join(cfg.params[cfg.lfp_path].split('.')[0], 'lfp_img_align.pkl'), 'rb')) # export light field data exp_obj = lfp_extractor.LfpExtractor(lfp_img_align, cfg) exp_obj.main() del exp_obj
def test_illum(self): # use pre-loaded calibration dataset wht_list = [ file for file in listdir(self.fp) if file.startswith('caldata') ] lfp_list = [ file for file in listdir(self.fp) if file.endswith(('lfr', 'lfp')) ] self.cfg.params[self.cfg.cal_path] = join(self.fp, wht_list[0]) for lfp_file in lfp_list: self.cfg.params[self.cfg.lfp_path] = join(self.fp, lfp_file) print('\nCompute image %s' % basename(self.cfg.params[self.cfg.lfp_path])) # decode light field image obj = LfpReader(self.cfg, self.sta) ret = obj.main() # use third of original image size (to prevent Travis from stopping due to memory error) crop_h, crop_w = obj.lfp_img.shape[0] // 3, obj.lfp_img.shape[ 1] // 3 crop_h, crop_w = crop_h + crop_h % 2, crop_w + crop_w % 2 # use even number for correct Bayer arrangement lfp_img = obj.lfp_img[crop_h:-crop_h, crop_w:-crop_w] del obj self.assertEqual(True, ret) # create output data folder mkdir_p(self.cfg.exp_path, self.cfg.params[self.cfg.opt_prnt]) if not self.cfg.cond_meta_file(): # automatic calibration data selection obj = CaliFinder(self.cfg, self.sta) ret = obj.main() wht_img = obj.wht_bay[ crop_h:-crop_h, crop_w:-crop_w] if obj.wht_bay is not None else obj.wht_bay del obj self.assertEqual(True, ret) meta_cond = not ( exists(self.cfg.params[self.cfg.cal_meta]) and self.cfg.params[self.cfg.cal_meta].lower().endswith('json')) if meta_cond or self.cfg.params[self.cfg.opt_cali]: # perform centroid calibration obj = LfpCalibrator(wht_img, self.cfg, self.sta) ret = obj.main() self.cfg = obj.cfg del obj self.assertEqual(True, ret) # load calibration data self.cfg.load_cal_data() # write centroids as png file if wht_img is not None: obj = CentroidDrawer(wht_img, self.cfg.calibs[self.cfg.mic_list], self.cfg) ret = obj.write_centroids_img(fn='testcase_wht_img+mics.png') del obj self.assertEqual(True, ret) # check if light field alignment has been done before if self.cfg.cond_lfp_align(): # align light field obj = LfpAligner(lfp_img, self.cfg, self.sta, wht_img) ret = obj.main() del obj self.assertEqual(True, ret) # load previously computed light field alignment with open(join(self.cfg.exp_path, 'lfp_img_align.pkl'), 'rb') as f: lfp_img_align = pickle.load(f) # extract viewpoint data CaliFinder(self.cfg).main() obj = LfpExtractor(lfp_img_align, cfg=self.cfg, sta=self.sta) ret = obj.main() vp_img_arr = obj.vp_img_linear del obj self.assertEqual(True, ret) # do refocusing if self.cfg.params[self.cfg.opt_refo]: obj = LfpRefocuser(vp_img_arr, cfg=self.cfg, sta=self.sta) ret = obj.main() del obj self.assertEqual(True, ret) return True
def test_illum(self): # instantiate config and status objects cfg = PlenopticamConfig() cfg.default_values() sta = PlenopticamStatus() # skip concole output message (prevent Travis from terminating due to reaching 4MB logfile size) cfg.params[cfg.opt_prnt] = False # use pre-loaded calibration dataset wht_list = [file for file in os.listdir(self.fp) if file.startswith('caldata')] lfp_list = [file for file in os.listdir(self.fp) if file.endswith(('lfr', 'lfp'))] cfg.params[cfg.cal_path] = os.path.join(self.fp, wht_list[0]) for lfp_file in lfp_list: print('Compute image %s' % os.path.basename(cfg.params[cfg.lfp_path])) cfg.params[cfg.lfp_path] = os.path.join(self.fp, lfp_file) # decode light field image lfp_obj = LfpReader(cfg, sta) ret_val = lfp_obj.main() lfp_img = lfp_obj.lfp_img del lfp_obj self.assertEqual(True, ret_val) # create output data folder mkdir_p(cfg.exp_path, cfg.params[cfg.opt_prnt]) if not cfg.cond_meta_file(): # automatic calibration data selection obj = CaliFinder(cfg, sta) ret_val = obj.main() wht_img = obj.wht_bay del obj self.assertEqual(True, ret_val) meta_cond = not (os.path.exists(cfg.params[cfg.cal_meta]) and cfg.params[cfg.cal_meta].lower().endswith('json')) if meta_cond or cfg.params[cfg.opt_cali]: # perform centroid calibration cal_obj = LfpCalibrator(wht_img, cfg, sta) ret_val = cal_obj.main() cfg = cal_obj.cfg del cal_obj self.assertEqual(True, ret_val) # load calibration data cfg.load_cal_data() # check if light field alignment has been done before if cfg.cond_lfp_align(): # align light field lfp_obj = LfpAligner(lfp_img, cfg, sta, wht_img) ret_val = lfp_obj.main() lfp_obj = lfp_obj.lfp_img del lfp_obj self.assertEqual(True, ret_val) # load previously computed light field alignment with open(os.path.join(cfg.exp_path, 'lfp_img_align.pkl'), 'rb') as f: lfp_img_align = pickle.load(f) # extract viewpoint data CaliFinder(cfg).main() obj = LfpExtractor(lfp_img_align, cfg=cfg, sta=sta) ret_val = obj.main() vp_img_arr = obj.vp_img_arr del obj self.assertEqual(True, ret_val) # do refocusing if cfg.params[cfg.opt_refo]: obj = LfpRefocuser(vp_img_arr, cfg=cfg, sta=sta) ret_val = obj.main() del obj self.assertEqual(True, ret_val) return True
def fp(self, fp): self._fp = fp mkdir_p(self._fp) if not os.path.exists(self._fp) else None