Skip to content

Commit

Permalink
common/lib/camera: Test docs
Browse files Browse the repository at this point in the history
  • Loading branch information
e10harvey committed Nov 25, 2024
1 parent 07f71a6 commit 3a108cd
Show file tree
Hide file tree
Showing 5 changed files with 396 additions and 17 deletions.
48 changes: 48 additions & 0 deletions opencsp/common/lib/camera/ImageAcquisition_DCAM_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,24 @@ def __init__(self, instance: int = 0, pixel_format: str = 'BayerRG12'):
self._shutter_cal_values = np.linspace(shutter_min, shutter_max, 2**13).astype(int)

def instance_matches(self, possible_matches: list[ImageAcquisitionAbstract]) -> bool:
"""
Determine whether this camera instance matches any instance in the provided list.
This method checks if there is another camera instance in the `possible_matches`
list that has the same `basler_index` as the current instance.
Parameters
----------
possible_matches : list[ImageAcquisitionAbstract]
A list of camera instances to check against. Each instance should be of
type `ImageAcquisitionAbstract` and may have a `basler_index` attribute.
Returns
-------
bool
True when the first matching instance is found; False otherwise.
"""
# "ChatGPT 4o-mini" assisted with generating this docstring.
for camera in possible_matches:
if not hasattr(camera, 'basler_index'):
continue
Expand All @@ -84,6 +102,35 @@ def instance_matches(self, possible_matches: list[ImageAcquisitionAbstract]) ->
return False

def get_frame(self, encode: bool = True) -> np.ndarray:
"""
Captures a single frame from the camera.
This method initiates the frame capture process and retrieves the image data
from the camera. The captured image can be returned in its raw Bayer format
or converted to an RGB format based on the `encode` parameter.
Parameters
----------
encode : bool, optional
If True (default), the captured Bayer-encoded image will be converted to
a 3D RGB image using the `encode_RG_to_RGB` function. If False, the raw
Bayer-encoded image will be returned.
Returns
-------
np.ndarray
The captured image as a NumPy array. The shape of the array will depend
on the encoding:
- If `encode` is True, the shape will be (height, width, 3) for RGB images.
- If `encode` is False, the shape will be (height, width) for Bayer images.
Raises
------
pylon.RuntimeException
If the frame grab is unsuccessful, an exception is raised indicating the
failure to capture the frame.
"""
# "ChatGPT 4o-mini" assisted with generating this docstring.
# Start frame capture
self.cap.StartGrabbingMax(1)
grabResult = self.cap.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
Expand Down Expand Up @@ -147,6 +194,7 @@ def shutter_cal_values(self) -> np.ndarray:
return self._shutter_cal_values

def close(self):
"""Closes the camera connection"""
with et.ignored(Exception):
super().close()
with et.ignored(Exception):
Expand Down
46 changes: 46 additions & 0 deletions opencsp/common/lib/camera/ImageAcquisition_DCAM_mono.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ def _check_pypylon_version(cls):
cls._has_checked_pypylon_version = True

def instance_matches(self, possible_matches: list[ImageAcquisitionAbstract]) -> bool:
"""
Determine whether this camera instance matches any instance in the provided list.
This method checks if there is another camera instance in the `possible_matches`
list that has the same `basler_index` as the current instance.
Parameters
----------
possible_matches : list[ImageAcquisitionAbstract]
A list of camera instances to check against. Each instance should be of
type `ImageAcquisitionAbstract` and may have a `basler_index` attribute.
Returns
-------
bool
True when the first matching instance is found; False otherwise.
"""
# "ChatGPT 4o-mini" assisted with generating this docstring.
for camera in possible_matches:
if not hasattr(camera, 'basler_index'):
continue
Expand All @@ -108,6 +126,33 @@ def instance_matches(self, possible_matches: list[ImageAcquisitionAbstract]) ->
return False

def get_frame(self) -> np.ndarray:
"""
Captures a single frame from the Basler DCAM monochromatic camera.
This method initiates the frame capture process and retrieves the image data
from the camera. The method waits for the frame to be captured and returns
the image data as a NumPy array.
Returns
-------
np.ndarray
The captured image as a NumPy array. The shape of the array will depend
on the pixel format set during initialization (e.g., Mono8, Mono12).
Raises
------
pylon.RuntimeException
If the frame grab is unsuccessful, an exception is raised indicating the
failure to capture the frame.
Notes
-----
The method calculates the expected exposure time in milliseconds and uses
this value to set a timeout for the frame retrieval. The timeout is set to
1.5 times the expected image acquisition time to ensure that the frame is
captured successfully.
"""
# "ChatGPT 4o-mini" assisted with generating this docstring.
# Start frame capture
self.cap.StartGrabbingMax(1)
exposure_time_ms = self.cap.ExposureTimeRaw.Max / 1000 # exposure time, ms
Expand Down Expand Up @@ -170,6 +215,7 @@ def shutter_cal_values(self) -> np.ndarray:
return self._shutter_cal_values

def close(self):
"""Closes the camera connection"""
with et.ignored(Exception):
super().close()
with et.ignored(Exception):
Expand Down
48 changes: 48 additions & 0 deletions opencsp/common/lib/camera/ImageAcquisition_MSMF.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,60 @@ def __init__(self, instance: int = 0):
raise IOError("Error opening webcam")

def instance_matches(self, possible_matches: list[ImageAcquisitionAbstract]) -> bool:
"""
Determine whether this camera instance matches any instance in the provided list.
This method checks if there is another instance of the `ImageAcquisition` class
in the `possible_matches` list. Since only one MSMF camera is supported,
the method returns True if any instance of `ImageAcquisition` is found; otherwise,
it returns False.
Parameters
----------
possible_matches : list[ImageAcquisitionAbstract]
A list of camera instances to check against. Each instance should be of
type `ImageAcquisitionAbstract`.
Returns
-------
bool
True if a matching instance of `ImageAcquisition` is found; False otherwise.
"""
# "ChatGPT 4o-mini" assisted with generating this docstring.
for camera in possible_matches:
if isinstance(camera, ImageAcquisition):
# only one MSMF camera is supported
return True
return False

def get_frame(self) -> np.ndarray:
"""
Captures a single frame from the connected camera.
This method reads a frame from the camera and returns it as a NumPy array.
If the captured frame is in color (3-dimensional), it is converted to a
grayscale image by averaging the color channels. The method raises an
exception if the frame capture is unsuccessful.
Returns
-------
np.ndarray
The captured image as a NumPy array. The shape of the array will be:
- (height, width) for grayscale images.
- If the input frame is in color, it will be converted to grayscale
by averaging the channels.
Raises
------
Exception
If the frame was not captured successfully, an exception is raised
indicating the failure to capture the frame.
ValueError
If the output frame does not have 2 or 3 dimensions, a ValueError
is raised indicating the incorrect number of dimensions.
"""
# "ChatGPT 4o-mini" assisted with generating this docstring.
# Capture image
ret, frame = self.cap.read()

Expand Down Expand Up @@ -90,6 +137,7 @@ def shutter_cal_values(self) -> np.ndarray:
raise ValueError('exposure_time cannot be adjusted with MSMF camera; adjust screen brightness instead.')

def close(self):
"""Closes the camera connection"""
with et.ignored(Exception):
super().close()
with et.ignored(Exception):
Expand Down
Loading

0 comments on commit 3a108cd

Please sign in to comment.