Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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)
Esempio n. 5
0
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))
Esempio n. 6
0
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
Esempio n. 7
0
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)
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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)
Esempio n. 12
0
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
Esempio n. 13
0
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)
Esempio n. 14
0
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
Esempio n. 15
0
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