diff --git a/.github/workflows/python_no_pycsou.yml b/.github/workflows/python_no_pycsou.yml index fba48a11..3ec9d0b8 100644 --- a/.github/workflows/python_no_pycsou.yml +++ b/.github/workflows/python_no_pycsou.yml @@ -20,10 +20,8 @@ jobs: fail-fast: false max-parallel: 12 matrix: - # TODO: use below with this issue is resolved: https://github.com/actions/setup-python/issues/808 - # os: [ubuntu-latest, macos-latest, windows-latest] - os: [ubuntu-latest, macos-12, windows-latest] - python-version: [3.8, "3.11"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.11"] steps: - uses: actions/checkout@v3 - name: Checkout submodules diff --git a/.github/workflows/python_pycsou.yml b/.github/workflows/python_pycsou.yml index 7640c660..dfdafb9b 100644 --- a/.github/workflows/python_pycsou.yml +++ b/.github/workflows/python_pycsou.yml @@ -20,8 +20,6 @@ jobs: fail-fast: false max-parallel: 12 matrix: - # TODO: use below with this issue is resolved: https://github.com/actions/setup-python/issues/808 - # os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-12, windows-latest] python-version: [3.9, "3.10"] steps: diff --git a/configs/collect_dataset.yaml b/configs/collect_dataset.yaml index 036b1230..75df8597 100644 --- a/configs/collect_dataset.yaml +++ b/configs/collect_dataset.yaml @@ -1,8 +1,6 @@ # python scripts/collect_dataset_on_device.py -cn collect_dataset -#input_dir: /mnt/mirflickr/all -input_dir: /mnt/mirflickr/10 - +input_dir: /mnt/mirflickr/all input_file_ext: jpg # can pass existing folder to continue measurement @@ -10,7 +8,7 @@ output_dir: null output_file_ext: png # files to measure -n_files: 5 +n_files: 15 start_idx: 0 # timing @@ -23,10 +21,10 @@ dummy: False # simply copy file to output folder for testing # ideal image levels max_level: 254 min_level: 200 -max_tries: 2 +max_tries: 6 masks: null # for multi-mask measurements -recon: null #ADMM # parameters for reconstruction (for debugging purposes, not recommended to do during actual measurement as it will significantly increase the time) +recon: null # parameters for reconstruction (for debugging purposes, not recommended to do during actual measurement as it will significantly increase the time) # -- display parameters display: @@ -43,8 +41,9 @@ display: landscape: False # whether to force landscape capture: - measure_bg: 2 # measure bg every x images + measure_bg: False # measure bg every x images, set False if not measuring background bg_fp: "black_background" + framerate: 10 skip: False # to test looping over displaying images config_pause: 3 iso: 100 diff --git a/configs/collect_dataset_background.yaml b/configs/collect_dataset_background.yaml new file mode 100644 index 00000000..9f509eda --- /dev/null +++ b/configs/collect_dataset_background.yaml @@ -0,0 +1,26 @@ +# python scripts/measure/collect_dataset_on_device.py -cn collect_dataset_background +defaults: + - collect_dataset + - _self_ + + +output_dir: /mnt/mirflickr/all_measured_20240813-183259 + +# files to measure +n_files: 25000 + +min_level: 160 +max_tries: 3 + + +# -- display parameters +display: + screen_res: [1920, 1200] # width, height + image_res: [600, 600] # useful if input images don't have the same dimension, set it to this + vshift: -34 + +capture: + measure_bg: 1 # measure bg every x images, set False if not measuring background + awb_gains: [1.8, 1.1] # red, blue + fact_increase: 1.35 # multiplicative factor to increase exposure + fact_decrease: 1.3 diff --git a/scripts/measure/collect_dataset_on_device.py b/scripts/measure/collect_dataset_on_device.py index 3cc83f19..4b1314b2 100644 --- a/scripts/measure/collect_dataset_on_device.py +++ b/scripts/measure/collect_dataset_on_device.py @@ -161,9 +161,7 @@ def collect_dataset(config): camera.close() # -- now set up camera with desired settings - camera = PiCamera( - framerate=1 / config.capture.exposure, sensor_mode=0, resolution=tuple(res) - ) + camera = PiCamera(sensor_mode=0, resolution=tuple(res), framerate=config.capture.framerate) # Set ISO to the desired value camera.resolution = tuple(res) @@ -204,83 +202,83 @@ def collect_dataset(config): brightness_vals = [] n_tries_vals = [] - with open(output_dir / "bg_mappings.json", 'a') as outfile: - bg_name = None - current_bg = {} - shutter_speed = init_shutter_speed - for i, _file in enumerate(tqdm.tqdm(files[start_idx:])): - - # save file in output directory as PNG - output_fp = output_dir / _file.name - output_fp = output_fp.with_suffix(f".{config.output_file_ext}") - - # if not done, perform measurement - if not os.path.isfile(output_fp): - - if config.dummy: - shutil.copyfile(_file, output_fp) - time.sleep(1) - - else: + bg_name = None + current_bg = {} + shutter_speed = init_shutter_speed + for i, _file in enumerate(tqdm.tqdm(files[start_idx:])): + + # save file in output directory as PNG + output_fp = output_dir / _file.name + output_fp = output_fp.with_suffix(f".{config.output_file_ext}") + + # if not done, perform measurement + if not os.path.isfile(output_fp): + if config.dummy: + shutil.copyfile(_file, output_fp) + time.sleep(1) + else: + + # display img + display_img(_file, config, init_brightness) + # capture img + output, _, _, camera = capture_screen(MAX_LEVEL, MAX_TRIES, MIN_LEVEL, _file, brightness_vals, camera, config, down, + exposure_vals, g, i, init_brightness, shutter_speed, None, + n_tries_vals, + output_fp, start_idx) + + if config.capture.measure_bg: + # name of background for current image + bg_name = plib.Path(config.capture.bg_fp + str(i)).with_suffix(f".{config.output_file_ext}") + bg = output_dir / bg_name + + # append current file to bg list + if str(bg_name) not in current_bg: + current_bg[str(bg_name)] = str(_file.name) + else: + current_bg[str(bg_name)].append(str(_file.name)) # capture background periodically - if i % config.capture.measure_bg == 0: - bg_name = plib.Path(config.capture.bg_fp + str(i)).with_suffix(f".{config.output_file_ext}") - bg = output_dir / bg_name - + if i % config.capture.measure_bg == 0 or (i == n_files - 1): bg_name = str(bg_name) # push the last bg-capture pairs - #mappings.update(current_bg) if current_bg: - json.dump(current_bg, outfile, indent=4) + with open(output_dir / "bg_mappings.json", 'a') as outfile: + json.dump(current_bg, outfile, indent=4) current_bg = {} - current_bg[bg_name] = [] - #current_bg[bg_name].append(str(_file.name)) - + #current_bg[bg_name] = None + # display bg display_img(None, config, brightness=init_brightness) # capture bg - output, shutter_speed, init_brightness, camera = capture_screen(MAX_LEVEL, MAX_TRIES, MIN_LEVEL, + output, shutter_speed, init_brightness, camera = capture_screen(MAX_LEVEL, 0, MIN_LEVEL, plib.Path(config.capture.bg_fp + str(i)).with_suffix(f".{config.output_file_ext}"), brightness_vals, camera, config, down, exposure_vals, g, i, init_brightness, shutter_speed, None, n_tries_vals, bg, start_idx) - current_bg[bg_name].append(str(_file.name)) - #print(f"current_bg: {current_bg}") - # display img - display_img(_file, config, init_brightness) - - import pudb; pudb.set_trace() - - # capture img - output, _, _, camera = capture_screen(MAX_LEVEL, 0, MIN_LEVEL, _file, brightness_vals, camera, config, down, - exposure_vals, g, i, init_brightness, shutter_speed, None, - n_tries_vals, - output_fp, start_idx) - - if recon is not None: - # normalize and remove background - output = output.astype(np.float32) - output /= output.max() - output -= bg # TODO implement fancy bg subtraction - output = np.clip(output, a_min=0, a_max=output.max()) - - # set data - output = output[np.newaxis, :, :, :] - recon.set_data(output) - - # reconstruct and save - res = recon.apply() - recon_fp = recon_dir / output_fp.name - save_image(res, recon_fp) - - # check if runtime is exceeded - if config.runtime: - proc_time = time.time() - start_time - if proc_time > runtime_sec: - print(f"-- measured {i + 1} / {n_files} files") - break + + if recon is not None: + # normalize and remove background + output = output.astype(np.float32) + output /= output.max() + output -= bg # TODO implement fancy bg subtraction + output = np.clip(output, a_min=0, a_max=output.max()) + + # set data + output = output[np.newaxis, :, :, :] + recon.set_data(output) + + # reconstruct and save + res = recon.apply() + recon_fp = recon_dir / output_fp.name + save_image(res, recon_fp) + + # check if runtime is exceeded + if config.runtime: + proc_time = time.time() - start_time + if proc_time > runtime_sec: + print(f"-- measured {i + 1} / {n_files} files") + break proc_time = time.time() - start_time print(f"\nFinished, {proc_time / 60.:.3f} minutes.") @@ -316,38 +314,6 @@ def capture_screen(MAX_LEVEL, MAX_TRIES, MIN_LEVEL, _file, brightness_vals, came fact_decrease = config.capture.fact_decrease n_tries = 0 - # -- create Camera object - # # -- now set up camera with desired settings - # camera = PiCamera( - # framerate=1 / config.capture.exposure, sensor_mode=0, resolution=tuple(res) - # ) - - # # Set ISO to the desired value - # camera.resolution = tuple(res) - # camera.iso = config.capture.iso - # # Wait for the automatic gain control to settle - # time.sleep(config.capture.config_pause) - # # Now fix the values - - # if config.capture.exposure: - # # in microseconds - # init_shutter_speed = int(config.capture.exposure * 1e6) - # else: - # init_shutter_speed = camera.exposure_speed - # camera.shutter_speed = init_shutter_speed - # camera.exposure_mode = "off" - - # # AWB - # if config.capture.awb_gains: - # assert len(config.capture.awb_gains) == 2 - # g = (Fraction(config.capture.awb_gains[0]), Fraction(config.capture.awb_gains[1])) - # g = tuple(g) - # else: - # g = camera.awb_gains - - # camera.awb_mode = "off" - # camera.awb_gains = g - camera.shutter_speed = int(init_shutter_speed) time.sleep(config.capture.config_pause) current_shutter_speed = camera.shutter_speed @@ -395,19 +361,21 @@ def capture_screen(MAX_LEVEL, MAX_TRIES, MIN_LEVEL, _file, brightness_vals, came max_pixel_val = output.max() if max_pixel_val < MIN_LEVEL: + # increase exposure current_shutter_speed = int(current_shutter_speed * fact_increase) + camera.shutter_speed = current_shutter_speed time.sleep(config.capture.config_pause) - print(f"increasing shutter speed to {current_shutter_speed}") + + print(f"increasing shutter speed to [desired] {current_shutter_speed} [actual] {camera.shutter_speed}") elif max_pixel_val > MAX_LEVEL: - if current_shutter_speed > 13098: # TODO: minimum for RPi HQ # decrease exposure current_shutter_speed = int(current_shutter_speed / fact_decrease) camera.shutter_speed = current_shutter_speed time.sleep(config.capture.config_pause) - print(f"decreasing shutter speed to {current_shutter_speed}") + print(f"decreasing shutter speed to [desired] {current_shutter_speed} [actual] {camera.shutter_speed}") else: diff --git a/setup.py b/setup.py index d1ab6d68..23bb2269 100644 --- a/setup.py +++ b/setup.py @@ -27,6 +27,7 @@ python_requires=">=3.8.1, <=3.11.9", install_requires=[ "opencv-python>=4.5.1.48", + "numpy==1.26.4; python_version=='3.11'", "numpy>=1.22", "scipy>=1.7.0", "image>=1.5.33",