예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
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
예제 #4
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 = 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
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
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
예제 #8
0
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
예제 #9
0
    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)
예제 #10
0
    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))
예제 #11
0
    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)
예제 #12
0
    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')
예제 #13
0
    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')
예제 #14
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'))
예제 #15
0
    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
예제 #16
0
    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)
예제 #17
0
    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)
예제 #18
0
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
예제 #19
0
    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
예제 #20
0
    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
예제 #21
0
    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)
예제 #22
0
    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
예제 #23
0
    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
예제 #24
0
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
예제 #25
0
    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
예제 #26
0
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
예제 #27
0
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
예제 #28
0
    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
예제 #29
0
    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
예제 #30
0
 def fp(self, fp):
     self._fp = fp
     mkdir_p(self._fp) if not os.path.exists(self._fp) else None