예제 #1
0
def test_fall_detection_case_2_2():
    """Expected to detect a fall because key-points are detected, the angle criteria is met and the time distance between frames is not too short."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    img_1 = _get_image(file_name='fall_img_1.png')
    img_2 = _get_image(file_name='fall_img_2.png')
    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1
    category, confidence, box, angle = result[0]
    assert box  # Add this line to avoid 'Unused local variable'
    assert category == 'FALL'
    assert confidence > 0.7
    assert angle > 60
예제 #2
0
def test_bad_sample_good_sample():
    """One bad sample should not prevent good samples from being processed."""
    config = _fall_detect_config()
    result = 'nothing passed to me'

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    object_detector = ObjectDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    object_detector.connect_to_next_element(output)
    # bad sample
    object_detector.receive_next_sample(image=None)
    assert result == 'nothing passed to me'

    # good sample
    fall_detector = FallDetector(**config)
    fall_detector.connect_to_next_element(output)

    img_1 = _get_image(file_name='fall_img_1.png')
    img_2 = _get_image(file_name='fall_img_2.png')
    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1
    category, confidence, box, angle = result[0]
    assert box  # Add this line to avoid 'Unused local variable'
    assert category == 'FALL'
    assert confidence > 0.7
    assert angle > 60
예제 #3
0
def test_one_person():
    """Expect to detect a fall."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result

        result = inference_result

    fall_detector = FallDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)

    img_1 = _get_image(file_name='basic_fall_1.jpg')
    img_2 = _get_image(file_name='basic_fall_2.jpg')
    fall_detector.receive_next_sample(image=img_1)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1
    category, confidence, (x0, y0, x1, y1) = result[0]
    assert category == 'FALL'
    assert confidence > 0.7
    assert x0 > 0 and x0 < x1
    assert y0 > 0 and y0 < y1
예제 #4
0
def test_fall_detection_case_2_1():
    """Expected to not detect a fall even though key-points are detected
    and the angle criteria is met. However the time distance between
    frames is too short."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    # The frame represents a person who is in a standing position.
    img_1 = _get_image(file_name="fall_img_1.png")

    # The frame represents a person falls.
    img_2 = _get_image(file_name="fall_img_2.png")

    start_time = time.monotonic()
    fall_detector.receive_next_sample(image=img_1)
    end_time = time.monotonic()
    safe_min = end_time - start_time + 1
    # set min time to a sufficiently big number to ensure test passes
    # on slow environments
    # the goal is to simulate two frames that are too close in time
    # to be considered for a fall detection sequence
    fall_detector.min_time_between_frames = safe_min
    fall_detector.receive_next_sample(image=img_2)

    assert not result
예제 #5
0
def test_fall_detection_case_5():
    """Expected to not detect a fall even the angle criteria is met
    because image 2 is standing up rather than fall"""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    # The frame represents a person falls.
    img_1 = _get_image(file_name="fall_img_2.png")

    # The frame represents a person who is in a standing position.
    img_2 = _get_image(file_name="fall_img_1.png")

    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert not result
예제 #6
0
def test_fall_detection_case_8():
    """Expect to not detect a fall"""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    # No person in a frame
    img_1 = _get_image(file_name="fall_img_6.png")

    # The frame represents a person who is in a standing position.
    img_2 = _get_image(file_name="fall_img_7.png")

    fall_detector.receive_next_sample(image=img_1)
    # set min time to a small number to speed up testing
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert not result
예제 #7
0
def test_fall_detection_case_3():
    """Expect to detect a fall as key-points are detected by rotating the image."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    img_1 = _get_image(file_name='fall_img_11.png')
    img_2 = _get_image(file_name='fall_img_12.png')
    fall_detector.receive_next_sample(image=img_1)
    # set min time to a small number to speed up testing
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1
    category, confidence, box, angle = result[0]
    assert box  # Add this line to avoid 'Unused local variable'
    assert category == 'FALL'
    assert confidence > 0.3
    assert angle > 60
예제 #8
0
def test_fall_detection_case_1():
    """Expected to not detect a fall as key-points are not detected."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)

    # The frame represents a person who is in a standing position.
    img_1 = _get_image(file_name="fall_img_1.png")

    # The frame represents a person completely falls.
    img_2 = _get_image(file_name="fall_img_3.png")

    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert not result
예제 #9
0
def test_config_confidence_threshold():
    """Verify against known confidence threshold. Make sure it propagates
    at all levels."""
    config = _fall_detect_config()
    fall_detector = FallDetector(**config)
    tfe = fall_detector._tfengine
    pe = fall_detector._pose_engine
    assert fall_detector.confidence_threshold == config["confidence_threshold"]
    assert pe.confidence_threshold == config["confidence_threshold"]
    assert tfe.confidence_threshold == config["confidence_threshold"]
    config["confidence_threshold"] = 0.457
    fall_detector = FallDetector(**config)
    tfe = fall_detector._tfengine
    pe = fall_detector._pose_engine
    assert fall_detector.confidence_threshold == config["confidence_threshold"]
    assert pe.confidence_threshold == config["confidence_threshold"]
    assert tfe.confidence_threshold == config["confidence_threshold"]
예제 #10
0
def test_draw_line_1_1():
    """One keypoing but no full body line. No image should be saved."""
    config = _fall_detect_config()

    fall_detector = FallDetector(**config)

    image = _get_image(file_name="fall_img_1.png")
    pose_dix = {fall_detector.LEFT_SHOULDER: [0, 0]}
    lines_drawn = fall_detector.draw_lines(image, pose_dix, 0.5)
    assert lines_drawn == 0
예제 #11
0
def test_fall_detection_2_frame_back_case_1():
    """
    Expected to detect a fall using frame[t] and frame[t-1].
    frame[t-2] : A person is in standing position.
    frame[t-1] : A person is almost in standing position as he is walking.
    frame[t]   : A person is fall down.
    """

    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)

    # A frame at t-2 timestamp when person is in standing position.
    img_1 = _get_image(file_name="fall_img_1.png")

    # A frame at t-1 timestamp when person is almost in standing position \
    # as he is walking.
    img_2 = _get_image(file_name="fall_img_1_1.png")

    # A frame at t timestamp when person falls down.
    img_3 = _get_image(file_name="fall_img_2.png")

    fall_detector.min_time_between_frames = 0.01

    fall_detector.receive_next_sample(image=img_1)
    time.sleep(fall_detector.min_time_between_frames)

    fall_detector.receive_next_sample(image=img_2)
    time.sleep(fall_detector.min_time_between_frames)

    assert not result

    fall_detector.receive_next_sample(image=img_3)

    assert result
    assert len(result) == 1

    category = result[0]["label"]
    confidence = result[0]["confidence"]
    angle = result[0]["leaning_angle"]
    keypoint_corr = result[0]["keypoint_corr"]

    assert keypoint_corr
    assert category == "FALL"
    assert confidence > 0.7
    assert angle > 60
def test_fall_detection_2_frame_back_case_2():
    """
        Expected to detect a fall using frame[t] and frame[t-2].
        frame[t-2] : A person is in standing position.
        frame[t-1] : A person is mid-way of fall.
        frame[t]   : A person is fall down.
    """
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)

    # A frame at t-2 timestamp when person is in standing position.
    img_1 = _get_image(file_name='fall_img_1.png')

    # A frame at t-1 timestamp when person is mid-way of fall.
    img_2 = _get_image(file_name='fall_img_2_2.png')

    # A frame at t timestamp when person falls down.
    img_3 = _get_image(file_name='fall_img_2.png')

    fall_detector.min_time_between_frames = 0.01
    fall_detector.max_time_between_frames = 15

    fall_detector.receive_next_sample(image=img_1)
    time.sleep(fall_detector.min_time_between_frames)

    fall_detector.receive_next_sample(image=img_2)
    time.sleep(fall_detector.min_time_between_frames)

    assert not result

    fall_detector.receive_next_sample(image=img_3)

    assert result
    assert len(result) == 1

    category = result[0]['label']
    confidence = result[0]['confidence']
    angle = result[0]['leaning_angle']
    keypoint_corr = result[0]['keypoint_corr']

    assert keypoint_corr
    assert category == 'FALL'
    assert confidence > 0.7
    assert angle > 60
예제 #13
0
def test_draw_line_1():
    """One body line passed to draw. Image with one line should be saved."""
    config = _fall_detect_config()

    fall_detector = FallDetector(**config)

    image = _get_image(file_name="fall_img_1.png")
    pose_dix = {
        fall_detector.LEFT_SHOULDER: [0, 0],
        fall_detector.LEFT_HIP: [0, 1]
    }
    lines_drawn = fall_detector.draw_lines(image, pose_dix, 0.5)
    assert lines_drawn == 1
예제 #14
0
def test_model_inputs():
    """Verify against known model inputs."""
    config = _fall_detect_config()
    fall_detector = FallDetector(**config)
    tfe = fall_detector._tfengine
    samples = tfe.input_details[0]['shape'][0]
    assert samples == 1
    height = tfe.input_details[0]['shape'][1]
    assert height == 300
    width = tfe.input_details[0]['shape'][2]
    assert width == 300
    colors = tfe.input_details[0]['shape'][3]
    assert colors == 3
예제 #15
0
def test_draw_line_0():
    """No body lines passed to draw. No image should be saved."""
    config = _fall_detect_config()

    fall_detector = FallDetector(**config)

    image = _get_image(file_name="fall_img_1.png")
    pose_dix = None
    lines_drawn = fall_detector.draw_lines(image, pose_dix, 0.5)
    assert lines_drawn == 0

    pose_dix = {}
    lines_drawn = fall_detector.draw_lines(image, pose_dix, 0.5)
    assert lines_drawn == 0
예제 #16
0
def test_no_sample():
    """Expect element to pass empty sample to next element."""
    config = _fall_detect_config()
    result = False

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = image is None and inference_result is None

    fall_detector = FallDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)
    fall_detector.receive_next_sample()
    assert result is True
예제 #17
0
def test_background_image():
    """Expect to not detect anything interesting in a background image."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)
    img = _get_image(file_name='background.jpg')
    fall_detector.receive_next_sample(image=img)
    assert not result
예제 #18
0
def test_model_outputs():
    """Verify against known model outputs."""
    config = _fall_detect_config()
    object_detector = FallDetector(**config)
    tfe = fall_detector._tfengine
    assert tfe.output_details[0]['shape'][0] == 1
    scores = tfe.output_details[0]['shape'][1]
    assert scores == 20
    assert tfe.output_details[1]['shape'][0] == 1
    boxes = tfe.output_details[1]['shape'][1]
    assert boxes == 20
    assert tfe.output_details[2]['shape'][0] == 1
    labels = tfe.output_details[2]['shape'][1]
    assert labels == 20
    num = tfe.output_details[3]['shape'][0]
    assert num == 1
예제 #19
0
def test_draw_line_2():
    """Two body lines passed to draw. Image with two lines should be saved."""
    config = _fall_detect_config()

    fall_detector = FallDetector(**config)

    # The frame represents a person who is in a standing position.
    image = _get_image(file_name="fall_img_1.png")
    pose_dix = {
        fall_detector.LEFT_SHOULDER: [0, 0],
        fall_detector.LEFT_HIP: [0, 1],
        fall_detector.RIGHT_SHOULDER: [1, 0],
        fall_detector.RIGHT_HIP: [1, 1],
    }
    lines_drawn = fall_detector.draw_lines(image, pose_dix, 0.5)
    assert lines_drawn == 2
예제 #20
0
def test_bad_sample_good_sample():
    """One bad sample should not prevent good samples from being processed."""
    config = _fall_detect_config()
    result = "nothing passed to me"

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    object_detector = ObjectDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    object_detector.connect_to_next_element(output)
    # bad sample
    object_detector.receive_next_sample(image=None)
    assert result == "nothing passed to me"

    # good sample
    fall_detector = FallDetector(**config)
    fall_detector.connect_to_next_element(output)

    # The frame represents a person who is in a standing position.
    img_1 = _get_image(file_name="fall_img_1.png")

    # The frame represents a person falls.
    img_2 = _get_image(file_name="fall_img_2.png")

    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1

    category = result[0]["label"]
    confidence = result[0]["confidence"]
    angle = result[0]["leaning_angle"]
    keypoint_corr = result[0]["keypoint_corr"]

    assert keypoint_corr
    assert category == "FALL"
    assert confidence > 0.7
    assert angle > 60
예제 #21
0
def test_fall_detection_2_frame_back_case_3():
    """
    Expected to not detect a fall using frame[t],frame[t-1] and frame[t-2].
    frame[t-2] : A person is in walking postion.
    frame[t-1] : A person is in walking postion.
    frame[t]   : A person is slight in lean postion but no fall.
    """

    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)

    # A frame at t-2 timestamp when person is in walking postion.
    img_1 = _get_image(file_name="fall_img_15.png")

    # A frame at t-1 timestamp when person is in walking postion.
    img_2 = _get_image(file_name="fall_img_16.png")

    # A frame at t timestamp when person is slight in lean postion but no fall.
    img_3 = _get_image(file_name="fall_img_17.png")

    fall_detector.min_time_between_frames = 0.01

    fall_detector.receive_next_sample(image=img_1)
    time.sleep(fall_detector.min_time_between_frames)

    fall_detector.receive_next_sample(image=img_2)
    time.sleep(fall_detector.min_time_between_frames)

    assert not result

    fall_detector.receive_next_sample(image=img_3)

    assert not result
예제 #22
0
def test_fall_detection_thumbnail_present():
    """Expected to receive thumnail in result if image is provided \
        and poses are detected."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None,
                        thumbnail=None,
                        inference_result=None,
                        **kwargs):
        nonlocal result
        result = (image is not None and thumbnail is not None
                  and inference_result is not None)

    fall_detector = FallDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)
    img_1 = _get_image(file_name="fall_img_1.png")
    fall_detector.receive_next_sample(image=img_1)
    assert result is True
예제 #23
0
def test_fall_detection_case_3_2():
    """Expect to detect a fall as key-points are detected
    by rotating the image counter clockwise."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    # The frame represents a person who is in a standing position.
    img_1 = _get_image(file_name="fall_img_11_flip.png")

    # The frame represents a person completely falls.
    img_2 = _get_image(file_name="fall_img_12_flip.png")

    fall_detector.receive_next_sample(image=img_1)
    # set min time to a small number to speed up testing
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1

    category = result[0]["label"]
    confidence = result[0]["confidence"]
    angle = result[0]["leaning_angle"]
    keypoint_corr = result[0]["keypoint_corr"]

    assert keypoint_corr
    assert category == "FALL"
    assert confidence > 0.3
    assert angle > 60
예제 #24
0
def test_fall_detection_case_2_2():
    """Expected to detect a fall because key-points are detected,
    the angle criteria is met and the time distance between
    frames is not too short."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    # The frame represents a person who is in a standing position.
    img_1 = _get_image(file_name="fall_img_1.png")

    # The frame represents a person falls.
    img_2 = _get_image(file_name="fall_img_2.png")

    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert result
    assert len(result) == 1
    category = result[0]["label"]
    confidence = result[0]["confidence"]
    angle = result[0]["leaning_angle"]
    keypoint_corr = result[0]["keypoint_corr"]

    assert keypoint_corr
    assert category == "FALL"
    assert confidence > 0.7
    assert angle > 60
예제 #25
0
def test_background_image():
    """Expect to not detect anything interesting in a background image."""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None,
                        thumbnail=None,
                        inference_result=None,
                        **kwargs):
        nonlocal result
        result = image is not None and thumbnail is not None and not inference_result

    fall_detector = FallDetector(**config)
    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)
    img = _get_image(file_name="background.jpg")
    fall_detector.receive_next_sample(image=img)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    img = _get_image(file_name="background.jpg")
    fall_detector.receive_next_sample(image=img)
    assert result is True
예제 #26
0
def test_fall_detection_case_4():
    """No Fall"""
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None, inference_result=None, **kwargs):
        nonlocal result
        result = inference_result

    fall_detector = FallDetector(**config)

    output = _OutPipeElement(sample_callback=sample_callback)

    fall_detector.connect_to_next_element(output)

    img_1 = _get_image(file_name='fall_img_1.png')
    img_2 = _get_image(file_name='fall_img_4.png')
    fall_detector.receive_next_sample(image=img_1)
    fall_detector.min_time_between_frames = 0.01
    time.sleep(fall_detector.min_time_between_frames)
    fall_detector.receive_next_sample(image=img_2)

    assert not result
예제 #27
0
def _helper_test_debug_image_save(context: PipelineContext = None):
    log_config = {"level": "DEBUG"}
    logger.configure(config=log_config)

    # Expect to receive thumnail in result if image is provided and
    #    poses are detected.
    config = _fall_detect_config()
    result = None

    def sample_callback(image=None,
                        thumbnail=None,
                        inference_result=None,
                        **kwargs):
        nonlocal result
        result = (image is not None and thumbnail is not None
                  and inference_result is not None)

    fall_detector = FallDetector(context=context, **config)
    output = _OutPipeElement(sample_callback=sample_callback)
    fall_detector.connect_to_next_element(output)
    img_1 = _get_image(file_name="fall_img_1.png")
    fall_detector.receive_next_sample(image=img_1)
    assert result is True
    # now that we know there was a positive detection
    # lets check if the the interim debug images were saved as expected
    pose_img_files = list(_data_dir.glob("tmp-pose-detect-image*.jpg"))
    assert len(pose_img_files) > 0
    fall_img_files = list(_data_dir.glob("tmp-fall-detect-thumbnail*.jpg"))
    assert len(fall_img_files) > 0
    # cleanup after test
    all_tmp_files = pose_img_files + fall_img_files
    for f in all_tmp_files:
        f.unlink()
    # return logger level to INFO to prevent side effects in other tests
    log_config = {"level": "INFO"}
    logger.configure(config=log_config)