Skip to content

Locate API performance issues #456

Description

@splondike

There are a couple of conditions under which the locate API can perform slowly (multiple seconds):

  • Searching over large screen resolutions (e.g. retina).
  • When the locate API finds a large number of matches.

The following Python code and attached image demonstrate the second case. The code attempts to find the Slack 'hash' icon and also a small white patch. The hash icon search gets 15 hits and takes ~0.5s. The white patch search gets 2 million hits and takes around 15-20s. I ran into this issue while building the talon UI helper package that allows users to lasso select regions and displays matches live on the screen. The user might inadvertently select something like the white patch and lock up the system.

Some mechanisms we discussed for improving performance were: exact matching, image pyramids, and multithreading. Having a maximum number of returned results is another option, but that may not be available from the OpenCV API.

import os
import time
import numpy as np
from talon.skia.image import Image
from talon.experimental import locate

def crop_image(image_np, x1, y1, x2, y2):
    return Image.from_array(
        image_np[y1:y2,x1:x2]
    )

image_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "one-monitor-screenshot.png")
screenshot_image = Image.from_file(image_path)
screenshot_image_np = np.array(screenshot_image)

hash_icon_image = crop_image(screenshot_image_np, 30, 325, 43, 341)
# hash_icon_image.write_file("/tmp/hash-icon.png")
white_patch_image = crop_image(screenshot_image_np, 241, 334, 250, 344)
# white_patch_image.write_file("/tmp/white_patch.png")

for label, image in [("hash icons", hash_icon_image), ("white patches", white_patch_image)]:
    start = time.time()
    results = locate.locate_in_image(
        screenshot_image,
        image,
        threshold=0.99
    )
    end = time.time()
    # I get 15 in 0.42s and 2047752 in ~16s respectively for this on my i7-2620M @ 2.7GHz CPU running Linux
    print(f"Found {len(results)} {label} in {end-start:.2f}s")

one-monitor-screenshot

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions