Skip to content

Commit

Permalink
Improve remote capture API.
Browse files Browse the repository at this point in the history
  • Loading branch information
ebezzam committed Nov 30, 2023
1 parent c9e7ce4 commit dd0609a
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 236 deletions.
3 changes: 3 additions & 0 deletions configs/collect_dataset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ display:
rot90: 3

capture:
sensor: rpi_hq
nbits_capture: 12
nbits_out: 8
delay: 2 # to allow picture to display
config_pause: 2
iso: 100
Expand Down
2 changes: 1 addition & 1 deletion configs/demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ capture:
legacy: True # Legacy image capture software (raspistill) or new one (libcamera)
bayer: True # whether to capture Bayer data, otherwise directly capture RGB (demosaiced) data
nbits_capture: 12 # bit-depth to capture, check support bit depth of sensor: lensless/hardware/sensor.py
raw_data_fn: raw_data # output file name
fn: raw_data # output file name
exp: 0.02
config_pause: 2
sensor_mode: "0" # {'off': 0, 'auto': 1, 'sunlight': 2, 'cloudy': 3, 'shade': 4, 'tungsten': 5, 'fluorescent': 6, 'incandescent': 7, 'flash': 8, 'horizon': 9}
Expand Down
19 changes: 0 additions & 19 deletions lensless/hardware/constants.py

This file was deleted.

109 changes: 74 additions & 35 deletions lensless/hardware/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,39 @@
logging.getLogger("paramiko").setLevel(logging.WARNING)


def check_capture_config(config):

sensor = config.sensor
nbits_capture = config.nbits_capture
nbits_out = config.nbits_out
exp = config.exp
rgb = config.rgb
gray = config.gray
legacy = config.legacy
down = config.down
res = config.res if "res" in config.keys() else None
awb_gains = config.awb_gains
def check_capture_config(
sensor,
nbits_capture,
nbits_out,
exp,
rgb,
gray,
legacy,
down,
awb_gains,
res=None,
**kwargs,
):

# sensor = config.sensor
# nbits_capture = config.nbits_capture
# nbits_out = config.nbits_out
# exp = config.exp
# rgb = config.rgb
# gray = config.gray
# legacy = config.legacy
# down = config.down
# res = config.res if "res" in config.keys() else None
# awb_gains = config.awb_gains

assert sensor in SensorOptions.values(), f"Sensor must be one of {SensorOptions.values()}"

assert res is None or down is None, "Cannot specify both res and down"
if res is not None:
assert len(res) == 2, "res must be a tuple of length 2"
# if down is not None or res is not None:
# if rgb is False and gray is False:
# warnings.warn("Bayer data will be returned in original dimension, i.e. 'down' and 'res' will be ignored.")

assert rgb is False or gray is False, "Cannot set both rgb and gray"

Expand Down Expand Up @@ -80,16 +95,16 @@ def capture(
config_pause=2,
sensor_mode="0",
nbits_out=12,
nbits_capture=12,
legacy=True,
rgb=False,
gray=False,
nbits=12,
down=None,
awb_gains=None,
rpi_python="~/LenslessPiCam/lensless_env/bin/python",
capture_script="~/LenslessPiCam/scripts/measure/on_device_capture.py",
verbose=False,
output_path=None,
output_dir=None,
**kwargs,
):
"""
Expand Down Expand Up @@ -123,10 +138,10 @@ def capture(
Whether to capture RGB image.
gray : bool
Whether to capture grayscale image.
nbits : int
Number of bits of image.
nbits_capture : int
Number of bits of image captured by sensor.
down : int
Downsample factor.
Downsample factor. Only used if non-Bayer data is returned.
awb_gains : list
AWB gains (red, blue).
rpi_python : str
Expand All @@ -140,6 +155,19 @@ def capture(
"""

black_level, ccm, supported_bit_depth = check_capture_config(
sensor=sensor,
nbits_capture=nbits_capture,
nbits_out=nbits_out,
exp=exp,
rgb=rgb,
gray=gray,
legacy=legacy,
down=down,
awb_gains=awb_gains,
**kwargs,
)

# check_username_hostname(rpi_username, rpi_hostname)
assert sensor in SensorOptions.values(), f"Sensor must be one of {SensorOptions.values()}"

Expand All @@ -148,10 +176,8 @@ def capture(
pic_command = (
f"{rpi_python} {capture_script} sensor={sensor} bayer={bayer} fn={remote_fn} exp={exp} iso={iso} "
f"config_pause={config_pause} sensor_mode={sensor_mode} nbits_out={nbits_out} "
f"legacy={legacy} rgb={rgb} gray={gray} "
f"legacy={legacy} rgb={rgb} gray={gray} nbits_capture={nbits_capture} "
)
if nbits > 8:
pic_command += " sixteen=True"
if down:
pic_command += f" down={down}"
if awb_gains:
Expand Down Expand Up @@ -203,16 +229,24 @@ def capture(
# copy over DNG file
remotefile = f"~/{remote_fn}.dng"
localfile = f"{fn}.dng"
if output_path is not None:
localfile = os.path.join(output_path, localfile)
if output_dir is not None:
localfile = os.path.join(output_dir, localfile)
if verbose:
print(f"\nCopying over picture as {localfile}...")
os.system(
'scp "%s@%s:%s" %s >/dev/null 2>&1'
% (rpi_username, rpi_hostname, remotefile, localfile)
)

img = load_image(localfile, verbose=True, bayer=bayer, nbits_out=nbits_out)
img = load_image(
localfile,
verbose=True,
bayer=bayer,
nbits_out=nbits_out,
black_level=black_level,
ccm=ccm,
downsample=down,
)

# print image properties
print_image_info(img)
Expand All @@ -226,8 +260,8 @@ def capture(

remotefile = f"~/{remote_fn}.png"
localfile = f"{fn}.png"
if output_path is not None:
localfile = os.path.join(output_path, localfile)
if output_dir is not None:
localfile = os.path.join(output_dir, localfile)
if verbose:
print(f"\nCopying over picture as {localfile}...")
os.system(
Expand All @@ -243,8 +277,8 @@ def capture(
# more pythonic? https://stackoverflow.com/questions/250283/how-to-scp-in-python
remotefile = f"~/{remote_fn}.png"
localfile = f"{fn}.png"
if output_path is not None:
localfile = os.path.join(output_path, localfile)
if output_dir is not None:
localfile = os.path.join(output_dir, localfile)
if verbose:
print(f"\nCopying over picture as {localfile}...")
os.system(
Expand All @@ -257,14 +291,16 @@ def capture(

else:

if not bayer:
# red_gain = config.camera.red_gain
# blue_gain = config.camera.blue_gain
red_gain = awb_gains[0]
blue_gain = awb_gains[1]
else:
red_gain = None
blue_gain = None
red_gain = awb_gains[0]
blue_gain = awb_gains[1]
# if not bayer:
# # red_gain = config.camera.red_gain
# # blue_gain = config.camera.blue_gain
# red_gain = awb_gains[0]
# blue_gain = awb_gains[1]
# else:
# red_gain = None
# blue_gain = None

# load image
if verbose:
Expand All @@ -277,6 +313,9 @@ def capture(
blue_gain=blue_gain,
red_gain=red_gain,
nbits_out=nbits_out,
black_level=black_level,
ccm=ccm,
downsample=down,
)

# write RGB data
Expand Down
2 changes: 2 additions & 0 deletions lensless/utils/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ def bayer2rgb_cc(

if ccm is None:
ccm = np.eye(3)
else:
assert ccm.shape == (3, 3)
ccm = ccm.copy().astype(np.float32)

# demosaic Bayer data
Expand Down
12 changes: 4 additions & 8 deletions lensless/utils/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import os.path

from lensless.utils.plot import plot_image
from lensless.hardware.constants import RPI_HQ_CAMERA_BLACK_LEVEL, RPI_HQ_CAMERA_CCM_MATRIX
from lensless.utils.image import bayer2rgb_cc, print_image_info, resize, rgb2gray, get_max_val


Expand All @@ -22,10 +21,10 @@ def load_image(
verbose=False,
flip=False,
bayer=False,
black_level=RPI_HQ_CAMERA_BLACK_LEVEL,
black_level=0,
blue_gain=None,
red_gain=None,
ccm=RPI_HQ_CAMERA_CCM_MATRIX,
ccm=None,
back=None,
nbits_out=None,
as_4d=False,
Expand Down Expand Up @@ -58,9 +57,9 @@ def load_image(
red_gain : float
Red gain for color correction.
black_level : float
Black level. Default is to use that of Raspberry Pi HQ camera.
Black level to remove.
ccm : :py:class:`~numpy.ndarray`
Color correction matrix. Default is to use that of Raspberry Pi HQ camera.
Color correction matrix.
back : array_like
Background level to subtract.
nbits_out : int
Expand Down Expand Up @@ -133,9 +132,6 @@ def load_image(
nbits = 12
else:
nbits = 8
# convert black level from 12 bit to 8 bit
if black_level > 255:
black_level = black_level / (2**12 - 1) * 255

if back:
back_img = cv2.imread(back, cv2.IMREAD_UNCHANGED)
Expand Down
Loading

0 comments on commit dd0609a

Please sign in to comment.