Better fix for RGB capture memory issues

This commit is contained in:
Joel Collins 2018-11-30 10:33:39 +00:00
parent 3e4b1750ae
commit b21040f22e
3 changed files with 30 additions and 29 deletions

View file

@ -96,6 +96,9 @@ class BaseCamera(object):
self.last_access = 0 #: time: Time of last client access to the camera
self.event = CameraEvent()
self.stream_timeout = 20 #: int: Number of inactive seconds before timing out the stream
self.stream_timeout_enabled = True #: bool: Enable or disable timing out the stream
self.state = {} #: dict: Dictionary for capture state
self._config = {} #: dict: Dictionary of base camera settings
self.paths = {
@ -257,9 +260,12 @@ class BaseCamera(object):
self.event.set() # send signal to clients
time.sleep(0)
# if there hasn't been any clients asking for frames in
# the last 10 seconds then stop the thread
if time.time() - self.last_access > 20:
# Handle timeout
if (
self.stream_timeout_enabled and # If using timeout
(time.time() - self.last_access > self.stream_timeout) and # And timeout time
not self.state['preview_active'] # And GPU preview is not active
):
self.frames_iterator.close()
break

View file

@ -17,7 +17,7 @@ Camera capture resolution set to video_resolution in frames()
Video port uses that resolution for everything. If a different resolution
is specified for video capture, this is handled by the resizer.
Still capture (if use_video_port == False) uses pause_stream_for_capture
Still capture (if use_video_port == False) uses pause_stream
to temporarily increase the capture resolution.
"""
@ -208,7 +208,7 @@ class StreamingCamera(BaseCamera):
# Pause stream while changing settings
if self.state['stream_active']: # If stream is active
logging.info("Pausing stream to update config.")
self.pause_stream_for_capture() # Pause stream
self.pause_stream() # Pause stream
paused_stream = True # Remember to unpause stream when done
# PiCamera parameters (applied directly to PiCamera object)
@ -237,7 +237,7 @@ class StreamingCamera(BaseCamera):
# If stream was paused to update config, unpause
if paused_stream:
logging.info("Resuming stream.")
self.resume_stream_for_capture()
self.resume_stream()
else:
raise Exception(
@ -355,7 +355,7 @@ class StreamingCamera(BaseCamera):
# Update state dictionary
self.state['record_active'] = False
def pause_stream_for_capture(
def pause_stream(
self,
splitter_port: int=1,
resolution: Tuple[int, int]=None) -> None:
@ -377,7 +377,7 @@ class StreamingCamera(BaseCamera):
# Increase the resolution for taking an image
self.camera.resolution = resolution
def resume_stream_for_capture(
def resume_stream(
self,
splitter_port: int=1,
resolution: Tuple[int, int]=None) -> None:
@ -388,7 +388,7 @@ class StreamingCamera(BaseCamera):
splitter_port (int): Splitter port to start recording on
resolution ((int, int)): Resolution to set the camera to, before starting recording.
"""
logging.debug("Unpausing stream")
logging.debug("Resuming stream")
if not resolution:
resolution = self.config['video_resolution']
@ -453,7 +453,7 @@ class StreamingCamera(BaseCamera):
if not use_video_port:
# Pause video splitter port 1
self.pause_stream_for_capture()
self.pause_stream()
self.camera.capture(
target,
@ -463,7 +463,7 @@ class StreamingCamera(BaseCamera):
bayer=True)
# Resume video splitter port 1
self.resume_stream_for_capture()
self.resume_stream()
else:
self.camera.capture(
@ -498,7 +498,7 @@ class StreamingCamera(BaseCamera):
size = resolution
if not use_video_port:
self.pause_stream_for_capture(resolution=resolution)
self.pause_stream(resolution=resolution)
logging.debug("Creating PiYUVArray")
with picamera.array.PiYUVArray(self.camera, size=size) as output:
@ -512,7 +512,7 @@ class StreamingCamera(BaseCamera):
use_video_port=use_video_port)
if not use_video_port:
self.resume_stream_for_capture()
self.resume_stream()
if rgb:
logging.debug("Converting to RGB")
@ -523,19 +523,13 @@ class StreamingCamera(BaseCamera):
def array(
self,
use_video_port: bool=True,
resize: Tuple[int, int]=None,
stop_worker: bool=True) -> np.ndarray:
resize: Tuple[int, int]=None) -> np.ndarray:
"""Capture an uncompressed still RGB image to a Numpy array.
Args:
use_video_port (bool): Capture from the video port used for streaming. Lower resolution, faster.
resize ((int, int)): Resize the captured image.
stop_worker (bool): Auto-stop worker, to avoid GPU memory issues
"""
restart_worker = False
if stop_worker is True and self.stop is False:
self.stop_worker()
restart_worker = True
if use_video_port:
resolution = self.config['video_resolution']
@ -547,8 +541,8 @@ class StreamingCamera(BaseCamera):
else:
size = resolution
if not use_video_port:
self.pause_stream_for_capture(resolution=resolution)
# Always pause stream, to prevent resizer memory issues
self.pause_stream(resolution=resolution)
logging.debug("Creating PiRGBArray")
with picamera.array.PiRGBArray(self.camera, size=size) as output:
@ -561,11 +555,8 @@ class StreamingCamera(BaseCamera):
format='rgb',
use_video_port=use_video_port)
if not use_video_port:
self.resume_stream_for_capture()
if restart_worker:
self.start_worker()
# Resume stream
self.resume_stream()
return output.array

View file

@ -104,7 +104,6 @@ def generate_lens_shading_table_closed_loop(output_fname="shadingtable.npy",
# Open the microscope and start with flat (i.e. no) lens shading correction.
cam.start_preview()
logging.info("Stopping worker thread during calibration, to avoid GPU memory issues")
cam.stop_worker()
def get_rgb_image(): # shorthand for taking an RGB image
return cam.array(use_video_port=True, resize=(max_res[0]//2, max_res[1]//2))
@ -125,8 +124,11 @@ def generate_lens_shading_table_closed_loop(output_fname="shadingtable.npy",
rgb_image = np.mean(images, axis=0, dtype=np.float)
incremental_gains = lens_shading_correction_from_rgb(rgb_image, 64//2)
gains *= incremental_gains
# Apply this change (actually apply a bit less than the change)
cam.pause_stream()
cam.camera.lens_shading_table = gains_to_lst(gains*32)
cam.resume_stream()
time.sleep(2)
# Fix the AWB gains so the image is neutral
@ -158,6 +160,8 @@ def generate_lens_shading_table_closed_loop(output_fname="shadingtable.npy",
logging.debug("Merging config...")
config.merge_config(settings, safe=True, backup=True)
#cam.resume_stream_for_capture()
if __name__ == '__main__':
generate_lens_shading_table_closed_loop()