def test_match_region2(x, y, offset_x, offset_y, width, height, frame_width, frame_height): if x >= 0: x = x + offset_x else: x = frame_width - width - offset_x if y >= 0: y = y + offset_y else: y = frame_height - height - offset_y region = stbt.Region(x, y, width=width, height=height) image = numpy.ones((region.height, region.width, 3), numpy.uint8) * 255 image[5:-5, 5:-5] = (255, 0, 0) frame = black(frame_width, frame_height) frame[region.to_slice()] = image[ 0 if region.y >= 0 else -region.y:region. height if region.bottom <= frame_height else frame_height - region.y, 0 if region.x >= 0 else -region.x:region. width if region.right <= frame_width else frame_width - region.x] * .85 # N.B. .85 is the lowest at which all the tests still passed when I # disabled the pyramid optimisation. should_match = _image_region(frame).contains(region) m = stbt.match(image, frame) if should_match != m.match or os.environ.get("STBT_DEBUG"): with scoped_debug_level(2): stbt.match(image, frame) assert should_match == m.match if should_match: assert m.region == region
def test_pyramid_roi_too_small(frame, image, match_method, match_threshold): # This is a regression test for an error that was seen with a particular # frame from a single test-run, with SQDIFF_NORMED: # cv2.error: (-215) _img.size().height <= _templ.size().height && # _img.size().width <= _templ.size().width in function matchTemplate with scoped_debug_level(2): stbt.match(image, frame=stbt.load_image(frame), match_parameters=stbt.MatchParameters( match_method=match_method, match_threshold=match_threshold))
def test_that_cache_is_disabled_when_debug_match(): # debug logging is a side effect that the cache cannot reproduce import stbt_core as stbt import _stbt.logging with scoped_curdir() as srcdir, cache('cache.lmdb'): stbt.match(srcdir + '/tests/red-black.png', frame=numpy.zeros((720, 1280, 3), dtype=numpy.uint8)) assert not os.path.exists('stbt-debug') with _stbt.logging.scoped_debug_level(2): stbt.match(srcdir + '/tests/red-black.png', frame=numpy.zeros((720, 1280, 3), dtype=numpy.uint8)) assert os.path.exists('stbt-debug')
def test_matching_greyscale_array_with_greyscale_frame(match_method): assert stbt.match(cv2.cvtColor(stbt.load_image("videotestsrc-redblue.png"), cv2.COLOR_BGR2GRAY), frame=cv2.cvtColor( stbt.load_image("videotestsrc-full-frame.png"), cv2.COLOR_BGR2GRAY), match_parameters=mp(match_method=match_method))
def test_png_with_16_bits_per_channel(): assert cv2.imread(_find_file("uint16.png"), cv2.IMREAD_UNCHANGED).dtype == \ numpy.uint16 # Sanity check (that this test is valid) assert stbt.match( "tests/uint16.png", frame=cv2.imread(_find_file("uint8.png")))
def test_matching_greyscale_array_with_greyscale_frame(match_method): img = stbt.load_image("videotestsrc-redblue.png", color_channels=1) assert img.shape[2] == 1 frame = stbt.load_image("videotestsrc-full-frame.png", color_channels=1) assert frame.shape[2] == 1 assert stbt.match(img, frame, match_parameters=mp(match_method=match_method))
def test_that_get_frame_resizes_to_match_coordinate_system( orientation, coordinate_system): source = cv2.imread( _find_file("images/android/resize/source-1080p-%s.png" % orientation)) out = _resize(source, coordinate_system) expected_filename = \ "images/android/resize/expected-{system}-{orientation}.png".format( system=coordinate_system.name.lower().replace("_", "-"), orientation=orientation) expected = cv2.imread(_find_file(expected_filename)) assert match(expected, out)
def _info(self): """ This is a private property because its name starts with ``_``. It will not appear in ``__repr__`` nor count toward equality comparisons, but the result from it will still be cached. This is useful for sharing intermediate values between your public properties, particularly if they are expensive to calculate. In this example we use ``_info`` from ``is_visible`` and ``message``. You wouldn't want this to be a public property because it returns a `MatchResult` which includes the entire frame passed into `match`. """ return stbt.match('tests/info.png', frame=self._frame)
def test_that_match_fast_path_is_equivalent(): from _stbt.match import _load_image black_reference = black(10, 10) almost_black_reference = black(10, 10, value=1) black_frame = black(1280, 720) almost_black_frame = black(1280, 720, value=2) images = [ ("videotestsrc-redblue.png", "videotestsrc-full-frame.png"), ("action-panel.png", "action-panel.png"), ("videotestsrc-full-frame.png", "videotestsrc-full-frame.png"), ("videotestsrc-redblue-flipped.png", "videotestsrc-full-frame.png"), ("button.png", "black-full-frame.png"), ("completely-transparent.png", "buttons-on-blue-background.png"), ("action-panel-template.png", "action-panel.png"), ("button.png", "buttons.png"), (black_reference, black_frame), (almost_black_reference, black_frame), (almost_black_reference, almost_black_frame), ("repeating-pattern.png", "repeating-pattern-full-frame.png"), ("button-transparent.png", "buttons.png"), ] for reference, frame in images: if isinstance(frame, string_types): frame = stbt.load_image(frame, cv2.IMREAD_COLOR) reference = _load_image(reference) orig_m = stbt.match(reference, frame=frame) fast_m = stbt.match(reference, frame=frame, region=orig_m.region) assert orig_m.time == fast_m.time assert orig_m.match == fast_m.match assert orig_m.region == fast_m.region assert bool(orig_m) == bool(fast_m) assert orig_m.first_pass_result == pytest.approx( fast_m.first_pass_result, abs=0.0001 if orig_m else 0.05) assert (orig_m.frame == fast_m.frame).all() if isinstance(orig_m.image, numpy.ndarray): assert (orig_m.image == fast_m.image).all() else: assert orig_m.image == fast_m.image
def test_transparent_reference_image_false_negative_caused_by_pyramid( frame, image, expected_region): # This is a regression test for a bug in the pyramid optimisation when # the reference image has a very small number of pixels, or the only non- # transparent pixels are near the edges of reference image: # At the smaller pyramid levels, the pixels near the edge of the reference # image won't match exactly because the corresponding pixels in the # down-scaled frame have been blurred. We also blur the reference image # before down-scaling, but since it doesn't know what's outside its edges, # it won't have the blurring near the edge. frame = stbt.load_image(frame) m = stbt.match(image, frame=frame) assert m assert expected_region.contains(m.region)
def test_to_native_coordinates(orientation, device_resolution, expected_coordinates, coordinate_system): description = "{source}-{orientation}".format( source=coordinate_system.name.lower().replace("_", "-"), orientation=orientation) screenshot = cv2.imread( _find_file("images/android/coordinates/%s-screenshot.png" % description)) icon = "images/android/coordinates/%s-reference.png" % description m = match(icon, screenshot) screenshot_x, screenshot_y = _centre_point(m.region) native_x, native_y = _to_native_coordinates( screenshot_x, screenshot_y, coordinate_system, _Dimensions(*device_resolution)) print((native_x, native_y)) assert isclose(native_x, expected_coordinates[0], atol=1) assert isclose(native_y, expected_coordinates[1], atol=1)
def test_that_sqdiff_matches_black_images(): black_reference = black(10, 10) almost_black_reference = black(10, 10, value=1) black_frame = black(1280, 720) almost_black_frame = black(1280, 720, value=2) sqdiff = mp(match_method=stbt.MatchMethod.SQDIFF) sqdiff_normed = mp(match_method=stbt.MatchMethod.SQDIFF_NORMED) assert not stbt.match(black_reference, black_frame, sqdiff_normed) assert not stbt.match(almost_black_reference, black_frame, sqdiff_normed) assert not stbt.match(almost_black_reference, almost_black_frame, sqdiff_normed) assert stbt.match(black_reference, black_frame, sqdiff) assert stbt.match(almost_black_reference, black_frame, sqdiff) assert stbt.match(almost_black_reference, almost_black_frame, sqdiff)
def test_match_error_message_for_too_small_frame_and_region(): stbt.match("videotestsrc-redblue.png", frame=black(width=92, height=160)) stbt.match("videotestsrc-redblue.png", frame=black(), region=stbt.Region(x=1188, y=560, width=92, height=160)) with pytest.raises(ValueError) as excinfo: stbt.match("videotestsrc-redblue.png", frame=black(width=91, height=160)) assert ( "Frame (160, 91, 3) must be larger than reference image (160, 92, 3)" in str(excinfo.value)) with pytest.raises(ValueError) as excinfo: stbt.match("videotestsrc-redblue.png", frame=black(width=92, height=159)) assert ( "Frame (159, 92, 3) must be larger than reference image (160, 92, 3)" in str(excinfo.value)) with pytest.raises(ValueError) as excinfo: # Region seems large enough but actually it extends beyond the frame stbt.match("videotestsrc-redblue.png", frame=black(), region=stbt.Region(x=1189, y=560, width=92, height=160)) assert ( "Region(x=1189, y=560, right=1280, bottom=720) must be larger than " "reference image (160, 92, 3)" in str(excinfo.value)) with pytest.raises(ValueError) as excinfo: # Region seems large enough but actually it extends beyond the frame stbt.match("videotestsrc-redblue.png", frame=black(), region=stbt.Region(x=1188, y=561, width=92, height=160)) assert ( "Region(x=1188, y=561, right=1280, bottom=720) must be larger than " "reference image (160, 92, 3)" in str(excinfo.value))
def test_that_match_rejects_greyscale_array(match_method): grey = cv2.cvtColor(stbt.load_image("black.png"), cv2.COLOR_BGR2GRAY) with pytest.raises(ValueError): stbt.match(grey, frame=black(), match_parameters=mp(match_method=match_method))
def test_match_fast_path(): # This is just an example of typical use assert stbt.match("action-panel-prototype.png", frame=stbt.load_image("action-panel.png"))
def test_matchresult_region_when_first_pyramid_level_fails_to_match(): f = stbt.load_image("videotestsrc-full-frame.png") r = stbt.match("videotestsrc-redblue-flipped.png", frame=f).region assert r.width == 92 assert r.height == 160
def test_transparent_reference_image_with_sqdiff_normed_raises_valueerror(): f = stbt.load_image("buttons-on-blue-background.png") with pytest.raises(ValueError): stbt.match("button-transparent.png", f, match_parameters=mp(stbt.MatchMethod.SQDIFF_NORMED))
def test_that_matchresult_str_image_matches_template_passed_to_match_custom(): assert "image=<Image(filename=None, dimensions=30x30x3)>" in str( stbt.match(black(30, 30), frame=black()))
def test_that_matchresult_str_image_matches_template_passed_to_match(): assert re.search(r"image=<Image\(filename=u?'black.png'", str(stbt.match("black.png", frame=black())))
def test_that_matchresult_image_matches_template_passed_to_match(): assert stbt.match("black.png", frame=black()).image.filename == "black.png"
def match(): return stbt.match('tests/red-black.png', frame=black)
def test_match_region(image, expected): frame = stbt.load_image("images/region/frame.png") m = stbt.match("images/region/%s.png" % image, frame=frame) assert m assert m.region == expected
def match_any(basename): f = adb.get_frame() return (match("images/android/galaxy-ace-2/" + basename, f) or match("images/android/moto-x2/" + basename, f))
def test_that_matchresult_str_image_matches_template_passed_to_match_custom(): assert "image=<Custom Image>" in str( stbt.match(black(30, 30), frame=black()))
def test_that_match_converts_greyscale_reference_image(filename): stbt.match(filename, frame=black()) # Doesn't raise stbt.match(stbt.load_image(filename), frame=black())
def test_ocr_on_text_next_to_image_match(): frame = load_image("action-panel.png") m = stbt.match("action-panel-blue-button.png", frame) assert "YOUVIEW MENU" == stbt.ocr(frame, region=m.region.right_of(width=150))