def object_location(object_list, frame_shape, verbose=True): """ Calculate the location of the largest object in `object_list`. Returns one of: 'frame_left', 'frame_right', 'frame_center', None """ if not object_list: if verbose: _ctx_print_all("Object location is None.") return None import numpy as np areas = [w * h for x, y, w, h in object_list] i = np.argmax(areas) nearest = object_list[i] x, y, w, h = nearest x_center = x + w / 2. if x_center < frame_shape[1] / 3.: location = 'frame_left' elif x_center < 2 * frame_shape[1] / 3.: location = 'frame_center' else: location = 'frame_right' if verbose: _ctx_print_all("Object location is '{}'.".format(location)) return location
def detect_stop_signs(frame, annotate=True, verbose=True): """ Detect stop signs inside of `frame`, and annotate each stop sign. The `frame` parameter must be an image as a numpy array either containing 3-channel RGB values _or_ 1-channel gray values. Returns a list of rectangles, where each rectangle is a 4-tuple of: (x, y, width, height) """ global STOPSIGNDETECTOR try: STOPSIGNDETECTOR except NameError: from auto.models import StopSignDetector STOPSIGNDETECTOR = StopSignDetector() if verbose: _ctx_print_all("Instantiated a StopSignDetector object!") rects = STOPSIGNDETECTOR.detect(frame, annotate=annotate) n = len(rects) if verbose: _ctx_print_all("Found {} stop sign{}.".format(n, 's' if n != 1 else '')) return rects
def detect_pedestrians(frame, annotate=True, verbose=True): """ Detect pedestrians inside of `frame`, and annotate each pedestrian. The `frame` parameter must be an image as a numpy array either containing 3-channel RGB values _or_ 1-channel gray values. Returns a list of rectangles, where each rectangle is a 4-tuple of: (x, y, width, height) """ global PEDESTRIANDETECTOR try: PEDESTRIANDETECTOR except NameError: from auto.models import PedestrianDetector if IS_VIRTUAL: PEDESTRIANDETECTOR = PedestrianDetector(hitThreshold=-1.5) else: PEDESTRIANDETECTOR = PedestrianDetector() if verbose: _ctx_print_all("Instantiated a PedestrianDetector object!") rects = PEDESTRIANDETECTOR.detect(frame, annotate=annotate) n = len(rects) if verbose: _ctx_print_all("Found {} pedestrian{}.".format(n, 's' if n != 1 else '')) return rects
def pause(sec=1.0, verbose=True): """ Pause the car's code for `sec` seconds. """ if verbose: _ctx_print_all("Pausing for {} seconds.".format(sec)) time.sleep(sec)
def stream(frame, to_console=True, to_labs=False, verbose=False): """ Stream the given `frame` (a numpy ndarray) to your device's console _and_ (optionally) to your `labs` account to be shown in your browser. The `frame` parameter must be a numpy ndarray with one of the following shapes: - (h, w, 3) meaning a single 3-channel RGB image of size `w`x`h` - (h, w, 1) meaning a single 1-channel gray image of size `w`x`h` - (h, w) meaning a single 1-channel gray image of size `w`x`h` """ if frame is None: if to_console: console.clear_image() if to_labs: send_message_to_labs({'base64_img': ''}) return # Publish the uncompressed frame to the console UI. if to_console: if frame.ndim == 3: if frame.shape[2] == 3: pass # all good elif frame.shape[2] == 1: pass # all good else: raise Exception("invalid number of channels") elif frame.ndim == 2: frame = np.expand_dims(frame, axis=2) assert frame.ndim == 3 and frame.shape[2] == 1 else: raise Exception(f"invalid frame ndarray ndim: {frame.ndim}") height, width, channels = frame.shape aspect_ratio = width / height if aspect_ratio != OPTIMAL_ASPECT_RATIO: final_frame = _add_white_bars(frame) height, width, channels = final_frame.shape else: final_frame = frame shape = [width, height, channels] rect = [0, 0, 0, 0] console.stream_image(rect, shape, final_frame.tobytes()) # Encode the frame and publish to the network connection. if to_labs: base64_img = base64_encode_image(frame) send_message_to_labs({'base64_img': base64_img}) if verbose: h, w = frame.shape[:2] _ctx_print_all("Streamed frame of size {}x{}.".format(w, h))
def object_size(object_list, frame_shape, verbose=True): """ Calculate the ratio of the nearest object's area to the frame's area. """ if not object_list: if verbose: _ctx_print_all("Object area is 0.") return 0.0 areas = [w * h for x, y, w, h in object_list] ratio = max(areas) / (frame_shape[0] * frame_shape[1]) if verbose: _ctx_print_all("Object area is {}.".format(ratio)) return ratio
def capture(num_frames=1, verbose=True): """ Capture `num_frames` frames from the car's camera and return them as a numpy ndarray. """ MAX_FRAMES = 4 if num_frames > MAX_FRAMES: _ctx_print_all( f"Warning: You may capture at most {MAX_FRAMES} frames with this function." ) num_frames = MAX_FRAMES from auto import camera return camera.capture(num_frames, verbose)
def close_global_camera(verbose=False): """ Close and delete the global camera object. """ global GLOBAL_CAMERA try: GLOBAL_CAMERA # <-- just to see if it exists if verbose: auto._ctx_print_all("Closing the global camera object...") release(GLOBAL_CAMERA._camera) del GLOBAL_CAMERA except NameError: # There is no global camera, so nothing needs to be done. pass
def global_camera(verbose=False): """ Creates (for the first call) or retrieves (for later calls) the global camera object. This is a convenience function to facilitate quickly and easily creating and retrieving a camera singleton. """ global GLOBAL_CAMERA try: GLOBAL_CAMERA except NameError: caps = list_caps() if 'Camera' not in caps: raise AttributeError("This device does not have a Camera.") camera = acquire('Camera') GLOBAL_CAMERA = _CameraRGB(camera) if verbose: auto._ctx_print_all("Instantiated a global camera object!") return GLOBAL_CAMERA
def capture(num_frames=1, verbose=False): """ Capture `num_frames` frames from the (global) camera and return them as a numpy ndarray. This is a convenience function to make the most common use-case simpler. """ camera = global_camera(verbose) if num_frames > 1: frames = np.array([frame for _, frame in zip(range(num_frames), camera.stream())]) if verbose: auto._ctx_print_all("Captured {} frames.".format(num_frames)) return frames else: frame = camera.capture() if verbose: auto._ctx_print_all("Captured 1 frame.") return frame
def reverse(sec=None, cm=None, verbose=True): """ Drive the car in reverse for `sec` seconds or `cm` centimeters (passing in both will raise an error). If neither is passed in, the car will drive for 1 second. """ from car import motors if sec is not None and cm is not None: _ctx_print_all( "Error: Please specify duration (sec) OR distance (cm) - not both." ) return if sec is None and cm is None: sec = 1.0 if sec is not None: if sec > 5.0: _ctx_print_all( "Error: The duration (sec) exceeds 5 seconds; will reset to 5 seconds." ) sec = 5.0 if sec <= 0.0: return if verbose: _ctx_print_all("Driving in reverse for {} seconds.".format(sec)) if cm is not None: if cm > 300.0: _ctx_print_all( "Error: The distance (cm) exceeds 300 cm (~10 feet); will reset to 300 cm." ) cm = 300.0 if cm <= 0.0: return if verbose: _ctx_print_all("Driving in reverse for {} centimeters.".format(cm)) motors.straight(motors.safe_reverse_throttle(), sec, cm, invert_output=True)
def plot(frames, also_stream=True, verbose=False): """ Stitch together the given `frames` (a numpy nd-array) into a single nd-array. If running in a notebook then the PIL image will be returned (and displayed). This function by default also streams the image to your `labs` account. The `frames` parameter must be a numpy ndarray with one of the following shapes: - (n, h, w, 3) meaning `n` 3-channel RGB images of size `w`x`h` - (n, h, w, 1) meaning `n` 1-channel gray images of size `w`x`h` - (h, w, 3) meaning a single 3-channel RGB image of size `w`x`h` - (h, w, 1) meaning a single 1-channel gray image of size `w`x`h` - (h, w) meaning a single 1-channel gray image of size `w`x`h` """ # Ensure the proper shape of `frames`. if frames.ndim == 4: pass elif frames.ndim == 3: frames = np.expand_dims(frames, axis=0) elif frames.ndim == 2: frames = np.expand_dims(frames, axis=2) frames = np.expand_dims(frames, axis=0) else: raise Exception("invalid frames ndarray ndim") if frames.shape[3] != 3 and frames.shape[3] != 1: raise Exception("invalid number of channels") if verbose: n = frames.shape[0] _ctx_print_all("Plotting {} frame{}...".format(n, 's' if n != 1 else '')) montage = _create_montage(frames) if also_stream: stream(montage, to_labs=True, verbose=False) return PIL.Image.fromarray(np.squeeze(montage)) if _in_notebook() else None
def right(sec=None, deg=None, verbose=True): """ Drive the car forwad and right for `sec` seconds or `deg` degrees (passing in both will raise an error). If neither is passed in, the car will drive for 1 second. """ from car import motors if sec is not None and deg is not None: _ctx_print_all( "Error: Please specify duration (sec) OR degrees (deg) - not both." ) return if sec is None and deg is None: sec = 1.0 if sec is not None: if sec > 5.0: _ctx_print_all( "Error: The duration (sec) exceeds 5 seconds; will reset to 5 seconds." ) sec = 5.0 if sec <= 0.0: return if verbose: _ctx_print_all("Driving right for {} seconds.".format(sec)) if deg is not None: if deg > 360.0: _ctx_print_all( "Error: The degrees (deg) exceeds 360; will reset to 360.") deg = 360.0 if deg <= 0.0: return if verbose: _ctx_print_all("Driving right for {} degrees.".format(deg)) motors.drive(-45.0, motors.safe_forward_throttle(), sec, deg)
def classify_color(frame, annotate=True, verbose=True): """ Classify the center region of `frame` as having either primarily "red", "yellow", or "green, or none of those ("background"). The `frame` parameter must be a numpy array containing an RGB image. Returns a string representing the color found in the center of the image, one of "red", "yellow", "green", or "background". """ global COLORCLASSIFIER try: COLORCLASSIFIER except NameError: from auto.models import ColorClassifier COLORCLASSIFIER = ColorClassifier() if verbose: _ctx_print_all("Instantiated a ColorClassifier object!") p1, p2, classific = COLORCLASSIFIER.classify(frame, annotate=annotate) if verbose: _ctx_print_all("Classified color as '{}'.".format(classific)) return classific
def detect_faces(frame, annotate=True, verbose=True): """ Detect faces inside of `frame`, and annotate each face. The `frame` parameter must be an image as a numpy array either containing 3-channel RGB values _or_ 1-channel gray values. Returns a list of rectangles, where each rectangle is a 4-tuple of: (x, y, width, height) """ global FACEDETECTOR try: FACEDETECTOR except NameError: from auto.models import FaceDetector FACEDETECTOR = FaceDetector() if verbose: _ctx_print_all("Instantiated a FaceDetector object!") faces = FACEDETECTOR.detect(frame, annotate=annotate) n = len(faces) if verbose: _ctx_print_all("Found {} face{}.".format(n, 's' if n != 1 else '')) return faces