메뉴 닫기

PyAutoGUI locateAllOnScreen 다수 매칭 반복 처리와 성능 주의 완벽 가이드

PyAutoGUI locateAllOnScreen 다수 매칭 반복 처리와 성능 주의 완벽 가이드

🐍 다중 좌표를 안전하게 순회하고 탐지 속도를 높이는 실전 코드와 최적화 포인트

화면 자동화를 해보면 같은 버튼이나 아이콘이 여러 곳에 등장하는 상황을 자주 마주합니다.
특히 이미지 템플릿으로 위치를 찾는 방식은 한 번에 하나만 누르면 끝나는 문제가 아니라, 찾힌 모든 좌표를 정확하고 안전하게 처리해야 성과가 나옵니다.
PyAutoGUI의 locateAllOnScreen은 바로 이런 장면에서 강력한 도구가 되지만, 무심코 사용하면 느린 탐지, 중복 클릭, 스크린 변화에 따른 오작동 같은 함정이 생기기 쉽죠.
이 글은 다수 매칭을 반복 처리하는 올바른 패턴과 성능을 끌어올리는 핵심 주의사항을 한곳에 모아, 실제 업무 자동화와 테스트 시나리오에서 바로 적용할 수 있도록 정리합니다.
불필요한 대기 시간과 시스템 자원 낭비를 줄이고, 이미지 매칭의 신뢰도를 높이는 방법까지 알기 쉽게 안내합니다.

핵심은 두 가지입니다.
첫째, locateAllOnScreen이 반환하는 다중 결과를 어떻게 순회하고 클릭·드래그·입력 같은 후속 동작과 연결하느냐입니다.
둘째, 해상도·스케일링·지역 검색(Region)·confidence 설정·그레이스케일 변환 등 성능과 정확도에 영향을 주는 요소를 체계적으로 다루는 것입니다.
여기에 중복 좌표 제거, 화면 갱신 대기, 실패 재시도 정책을 더하면 자동화 스크립트가 훨씬 견고해집니다.
실무 팁과 코드 예시를 기반으로 안전한 반복 처리 패턴을 제시하고, 이미지 인식 속도를 높이는 최적화 전략, 그리고 OpenCV와의 병행 활용 아이디어까지 준비했습니다.
내용을 차근차근 따라가며 자신만의 자동화 루틴을 안정적으로 완성해보세요.



🔗 PyAutoGUI locateAllOnScreen 개념과 반환값 구조

화면에서 동일한 이미지가 여러 번 등장할 때 locateAllOnScreen은 모든 매칭 후보를 찾아냅니다.
반환 타입은 반복 가능한 제너레이터이며, 각 항목은 (left, top, width, height) 값을 가진 Box 형태로 제공됩니다.
즉시 리스트가 아니라 한 개씩 계산해 내보내므로, 결과를 여러 번 순회해야 한다면 list()로 한 번에 물리 리스트로 변환해야 합니다.
각 박스의 중심 좌표는 pyautogui.center(box)로 구할 수 있고, 클릭·드래그 등 후속 액션과 자연스럽게 연결됩니다.

성능과 정확도는 해상도, 디스플레이 스케일링(특히 Windows 125%/150%), 검색 영역(Region), 매칭 임계값(confidence), 그레이스케일 여부 등 다양한 요소에 의해 크게 달라집니다.
또한 confidence 인자를 사용하려면 OpenCV가 설치되어 있어야 하며, 이미지 리소스는 가능한 한 UI 원본과 색상·크기가 동일해야 합니다.
제너레이터 특성상 결과를 소비하는 순간 스크린샷 비교가 끝나므로, 화면이 계속 변하는 환경에서는 첫 수집 타이밍과 후속 액션 사이에 상태 변화가 없는지 고려해야 합니다.

🧩 반환값 이해와 안전한 순회

다수 매칭을 안정적으로 처리하려면 두 가지를 기억하세요.
첫째, 제너레이터는 1회성입니다.
둘째, 처리 중 화면이 변하면 이후 매칭이 무효가 될 수 있습니다.
따라서 결과를 즉시 list()로 담아 두고, 중복·중첩 박스 제거정렬(예: 좌→우, 상→하)을 적용해 순회 순서를 예측 가능하게 만드는 것이 좋습니다.

CODE BLOCK
import pyautogui as pag

# 1) 결과를 물리 리스트로 수집 (제너레이터 1회성 주의)
matches = list(pag.locateAllOnScreen(
    'button.png',
    region=None,          # (x, y, w, h)로 제한 가능
    confidence=0.85,      # OpenCV 필요
    grayscale=True        # 색상 변화에 강함
))

# 2) 좌->우, 상->하 순으로 정렬
matches.sort(key=lambda r: (r.top, r.left))

# 3) 중심 좌표로 안전하게 클릭
for r in matches:
    x, y = pag.center(r)
    pag.moveTo(x, y, duration=0.15)
    pag.click()

🧭 부분 영역 검색과 해상도 이슈

전체 화면을 스캔하면 정확도는 유지되지만 시간이 오래 걸립니다.
대신 후보 영역을 알 수 있다면 region=(x, y, w, h)를 지정해 탐지 범위를 축소하세요.
또한 OS 스케일링으로 이미지가 확대·축소되면 매칭 실패가 잦아집니다.
템플릿의 크기를 실제 UI와 맞추거나, 고정 크기 UI가 아니라면 다양한 배율의 템플릿을 준비해 멀티 시도로 보완합니다.

함수 특징
locateOnScreen 첫 번째 매칭만 반환.
단일 대상 클릭에 적합.
locateAllOnScreen 모든 후보를 제너레이터로 반환.
다수 처리에 필수.

💡 TIP: 다수 매칭을 순회할 때는 화면 갱신 대기를 추가하세요.
예: 각 클릭 후 pag.sleep(0.1~0.3) 또는 상태 변화가 끝날 때까지 루프 조건으로 재확인.

⚠️ 주의: 제너레이터를 직접 두 번 순회하면 두 번째 순회에선 결과가 비어 보일 수 있습니다.
반드시 한 번 수집해 가공 후 사용하세요.
또한 confidence 사용 시 OpenCV 미설치 환경에서는 오류가 발생합니다.

💬 핵심은 ‘결과 수집 → 정렬/중복 제거 → 안정된 순회’의 3단계입니다.
특히 UI가 바뀌는 환경에서는 클릭 직후 재탐색으로 남은 항목을 갱신하는 전략이 신뢰도를 높입니다.

  • 🛠️list()로 결과를 한 번에 수집
  • ⚙️정렬 기준 통일: (row, col)
  • 🔌중복/중첩 박스 제거로 이중 클릭 방지
  • 🚀region, grayscale, confidence로 속도/정확도 조절

🛠️ 다수 매칭 반복 처리 패턴과 코드 예시

locateAllOnScreen을 활용할 때 가장 흔한 패턴은 화면에 같은 버튼이나 아이콘이 여러 개 있을 때, 이를 하나씩 순차적으로 클릭하거나 상태를 확인하는 방식입니다.
하지만 단순히 for 루프로 순회하는 것만으로는 문제가 생길 수 있습니다.
예를 들어, 클릭과 동시에 UI 레이아웃이 바뀌면서 이후 좌표가 무효화되는 경우, 또는 중첩된 요소가 두 번씩 잡혀 중복 클릭되는 경우가 대표적입니다.

안정적인 반복 처리를 위해서는 다음과 같은 절차가 필요합니다.
1) 제너레이터 결과를 리스트로 변환.
2) 좌표를 정렬해 예측 가능한 순서로 순회.
3) 클릭 후 화면 상태를 재탐색하거나 조건 확인.
4) 중복 좌표는 간격이나 중심점 비교로 제거.
이 과정을 체계적으로 구현하면 자동화 흐름이 훨씬 안정됩니다.

📌 안전한 반복 처리 코드 예시

CODE BLOCK
import pyautogui as pag
import time

def click_all_buttons(img, min_gap=10):
    # 1) 결과 수집
    results = list(pag.locateAllOnScreen(img, confidence=0.9, grayscale=True))
    results.sort(key=lambda r: (r.top, r.left))

    clicked = []
    for box in results:
        x, y = pag.center(box)
        # 2) 중복 좌표 방지
        if any(abs(px - x) < min_gap and abs(py - y) < min_gap for px, py in clicked):
            continue

        pag.moveTo(x, y, duration=0.2)
        pag.click()
        clicked.append((x, y))

        # 3) 상태 반영 대기
        time.sleep(0.2)

이 코드는 같은 버튼이 여러 개 있는 경우, 최소 간격(min_gap) 기준으로 중복 클릭을 피하고, 클릭 후 잠시 대기해 UI 반영이 끝난 뒤 다음 좌표를 진행하도록 설계되었습니다.

🧭 순회 순서와 중복 제거

좌표를 순회할 때는 보통 왼쪽에서 오른쪽, 위에서 아래 순으로 진행하면 사용자가 기대하는 방식과 유사합니다.
또한 실제 UI에는 동일 좌표가 겹쳐 잡히는 경우가 있어, 중심 좌표를 기준으로 10~15px 이내는 중복으로 처리해 제거하는 것이 좋습니다.

💡 TIP: 반복 처리 중 화면이 크게 바뀌는 경우라면, 처음부터 모든 좌표를 클릭하는 대신 한 번 클릭 → 재탐색 → 다음 클릭 방식으로 안정성을 확보하세요.

⚠️ 주의: locateAllOnScreen의 결과는 실행 시점의 화면 상태에 따라 달라집니다.
동작 중 UI가 바뀌면 이후 좌표가 모두 무효화될 수 있으니, 중요한 액션을 수행할 때는 꼭 재탐색을 권장합니다.

💬 다수 매칭은 단순 루프가 아니라 ‘수집 → 정렬 → 필터링 → 동작 → 재탐색’으로 이어지는 패턴을 습관화하면 자동화의 안정성이 크게 향상됩니다.

  • 🔄반드시 list() 변환 후 사용
  • 📐좌표 정렬과 순회 규칙 적용
  • 🚫중복 좌표 제거 로직 추가
  • 클릭 후 대기·재탐색 필수



⚙️ 성능 최적화 전략 이미지 검색 속도 높이기

PyAutoGUI의 locateAllOnScreen은 편리하지만, 기본 설정으로 사용하면 탐색 속도가 느려질 수 있습니다.
특히 해상도가 높은 모니터나 듀얼 모니터 환경에서는 전체 화면을 탐색하는 데 수 초 이상 걸릴 때도 있습니다.
실무에서 안정적이고 빠른 자동화를 원한다면, 성능 최적화 전략을 반드시 적용해야 합니다.

속도를 높이는 주요 방법은 크게 다섯 가지입니다.
첫째, region 매개변수로 탐색 범위를 제한합니다.
둘째, grayscale=True로 설정해 비교 연산량을 줄입니다.
셋째, OpenCV를 설치하고 confidence 옵션을 사용하면 작은 오차에도 빠른 매칭이 가능합니다.
넷째, 탐색 빈도를 낮추고 screenshot()을 재사용합니다.
마지막으로, 필요 없는 순간에는 불필요한 반복 탐색을 피하고 상태 변화를 조건문으로 제어하는 것이 좋습니다.

🚀 지역 검색과 그레이스케일 활용

전체 화면을 탐색하는 대신, 대상 요소가 있을 법한 영역을 region 인자로 지정하면 속도가 획기적으로 개선됩니다.
또한 색상 대신 흑백으로만 비교하는 grayscale은 색상 차이를 무시하고 매칭 속도를 20~40% 정도 향상시킵니다.

CODE BLOCK
import pyautogui as pag

# 특정 영역만 탐색 (x, y, width, height)
region_area = (100, 200, 800, 400)

matches = list(pag.locateAllOnScreen(
    'icon.png',
    region=region_area,
    confidence=0.9,
    grayscale=True
))
print(f"탐색된 개수: {len(matches)}")

⚡ 스크린샷 재사용과 반복 탐색 줄이기

여러 차례 탐색이 필요한 경우 매번 화면 전체를 캡처하는 대신, 한 번 스크린샷을 찍어 재사용하는 방식이 성능에 유리합니다.
예를 들어 버튼을 여러 개 찾을 때는 pag.screenshot()으로 한 번 캡처한 이미지를 재활용하면 탐색 시간이 절반 이하로 줄어듭니다.

CODE BLOCK
screenshot = pag.screenshot()
matches = list(pag.locateAll('icon.png', screenshot, confidence=0.9))

💡 TIP: 불필요한 반복 탐색은 CPU를 과도하게 점유합니다.
특히 루프 내에서 locateAllOnScreen을 매번 호출하지 말고, 상황에 맞는 시점에만 재탐색하도록 코드를 구조화하세요.

⚠️ 주의: confidence 값을 과도하게 낮추면 비슷한 이미지가 잘못 탐지되는 오탐률이 올라갑니다.
성능 최적화를 하면서도 정확도를 유지하려면 0.8~0.9 정도의 confidence를 권장합니다.

💬 핵심은 탐색 범위를 줄이고, 연산량을 낮추고, 불필요한 반복을 피하는 것입니다.
이 세 가지를 지키면 locateAllOnScreen의 실행 속도가 체감될 만큼 빨라집니다.

  • 📍region으로 검색 영역 축소
  • 🌑grayscale=True로 연산 최적화
  • 🔎OpenCV + confidence 활용
  • 🖼️스크린샷 재사용으로 반복 연산 줄이기
  • ⚠️confidence 값은 너무 낮추지 않기

🔌 실무 팁 실패 대응 중복 클릭 방지 로직

locateAllOnScreen은 여러 개의 좌표를 반환하지만, 단순히 순회만 하면 안정성이 떨어질 수 있습니다.
클릭 후 UI가 즉시 사라지거나 바뀌는 경우, 이미 클릭한 요소가 재탐색에서 또 잡히는 문제가 생기죠.
또한, 같은 버튼이 겹쳐서 탐지되거나 그림자·반사 효과 때문에 좌표가 중복으로 인식될 수 있습니다.
이를 방지하기 위해서는 실패 대응과 중복 클릭 방지 로직이 필수적입니다.

중복 좌표를 방지하려면 중심 좌표 사이의 거리를 비교해 일정 값 이하인 경우 하나로 처리하는 것이 좋습니다.
또한 클릭 후 바로 다음 좌표로 넘어가기보다는, UI 상태가 바뀌었는지 확인하거나 재탐색을 통해 남은 요소를 다시 찾는 방식이 더 안전합니다.
이러한 방식은 자동화 안정성을 크게 높여주며, 특히 반복 동작이 많은 업무 자동화 환경에서 반드시 고려해야 합니다.

🛡️ 실패 대응과 예외 처리

탐색 결과가 없을 때 무작정 진행하면 오류가 발생할 수 있습니다.
따라서 조건문으로 탐색 결과 유무를 먼저 확인한 뒤, 없으면 로그를 남기고 다시 시도하거나, 최대 재시도 횟수를 정하는 것이 실무에서 권장되는 패턴입니다.

CODE BLOCK
import pyautogui as pag
import time

def safe_click(img, retries=3):
    for i in range(retries):
        box = pag.locateOnScreen(img, confidence=0.9)
        if box:
            x, y = pag.center(box)
            pag.click(x, y)
            return True
        time.sleep(0.3)
    return False

if not safe_click('submit.png'):
    print("버튼을 찾을 수 없습니다. 수동 확인 필요.")

🧭 중복 좌표 제거 로직

중복 좌표를 제거하려면 중심 좌표의 거리 기준으로 비교하는 것이 일반적입니다.
예를 들어, X·Y 좌표 차이가 모두 10px 이하라면 같은 좌표로 간주하고 중복 처리를 막을 수 있습니다.

CODE BLOCK
def filter_duplicates(coords, min_gap=10):
    filtered = []
    for (x, y) in coords:
        if not any(abs(x - fx) < min_gap and abs(y - fy) < min_gap for fx, fy in filtered):
            filtered.append((x, y))
    return filtered

💡 TIP: 자동화 중 예외 상황은 반드시 고려해야 합니다.
예상치 못한 팝업, 느린 반응 속도, 해상도 변화 등은 코드가 멈추는 원인이 되므로 예외 처리와 로그 기록을 습관화하세요.

⚠️ 주의: locateAllOnScreen은 UI가 빠르게 바뀌는 경우 잘못된 좌표를 반환할 수 있습니다.
반드시 클릭 직후 화면 상태를 검증하거나, 다음 단계로 넘어가기 전에 조건을 다시 확인해야 합니다.

💬 실패 대응과 중복 제거는 선택이 아니라 필수입니다.
안정적인 자동화 루틴은 ‘탐색 → 검증 → 실행 → 예외 처리’의 과정을 반드시 거칩니다.

  • 탐색 실패 시 재시도 및 로그 기록
  • 🚫중복 좌표 제거로 이중 클릭 방지
  • 🔄클릭 후 상태 검증 또는 재탐색
  • 📋예외 처리와 로그 습관화



💡 대안 도구와 함께 쓰는 방법 OpenCV 이미지 인식

PyAutoGUI의 locateAllOnScreen은 간단하고 직관적이지만, 대규모 화면 탐색이나 복잡한 패턴 인식에는 한계가 있습니다.
이럴 때 OpenCV를 함께 사용하면 이미지 인식 속도와 정확도를 크게 향상시킬 수 있습니다.
특히 템플릿 매칭, 다중 스케일 탐지, 엣지 기반 비교 같은 기능은 PyAutoGUI 단독으로는 지원하지 않는 강력한 보완책이 됩니다.

PyAutoGUI 내부에서도 confidence 매개변수를 사용할 때 OpenCV가 필요하기 때문에, OpenCV를 직접 활용하면 더 세밀한 제어가 가능합니다.
예를 들어 locateAllOnScreen이 여러 개의 결과를 제너레이터로만 반환하는 것과 달리, OpenCV는 매칭된 좌표와 유사도 점수를 함께 제공하므로 필터링과 정렬이 한층 수월합니다.

🖼️ OpenCV 템플릿 매칭 기본 예제

CODE BLOCK
import cv2
import pyautogui as pag
import numpy as np

# 화면 캡처
screenshot = pag.screenshot()
img = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)

# 템플릿 불러오기
template = cv2.imread('button.png', cv2.IMREAD_GRAYSCALE)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 템플릿 매칭
res = cv2.matchTemplate(gray_img, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(res >= 0.9)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img, pt, (pt[0] + template.shape[1], pt[1] + template.shape[0]), (0, 0, 255), 2)

cv2.imwrite("result.png", img)

위 코드에서는 PyAutoGUI로 스크린샷을 얻고, OpenCV로 템플릿 매칭을 수행합니다.
유사도가 0.9 이상인 좌표만 골라내 사각형으로 표시했으며, PyAutoGUI의 moveToclick 함수와 연결하면 자동화 루틴으로 쉽게 확장할 수 있습니다.

🔄 PyAutoGUI와 OpenCV 병행 활용

실무에서는 PyAutoGUI로 기본적인 자동화를 진행하되, locateAllOnScreen이 느리거나 오탐률이 높은 경우 OpenCV로 좌표를 먼저 찾아 필터링한 뒤 PyAutoGUI 동작을 연결하는 방식을 권장합니다.
이렇게 하면 두 라이브러리의 장점을 동시에 활용할 수 있습니다.

💡 TIP: OpenCV는 속도가 빠르고 매칭 조건이 세밀해 대규모 자동화에 적합합니다.
다만, PyAutoGUI처럼 단순 API로 마우스/키보드 이벤트를 제공하지 않으므로 두 라이브러리를 병행하는 방식이 가장 효율적입니다.

⚠️ 주의: OpenCV 템플릿 매칭은 이미지 크기가 조금만 달라도 탐지가 어려울 수 있습니다.
동적 UI에서는 멀티 스케일 매칭 또는 다양한 해상도의 템플릿 이미지를 준비해야 합니다.

💬 PyAutoGUI는 단순성과 접근성을, OpenCV는 정밀성과 속도를 제공합니다.
두 도구를 적절히 조합하면 대규모 UI 자동화 작업에서도 안정성과 효율성을 동시에 확보할 수 있습니다.

  • 🔍PyAutoGUI는 단순 동작에 적합
  • OpenCV는 고속 매칭과 정밀 탐지에 강점
  • 🔄병행 활용으로 성능·정확도 보완
  • ⚠️동적 UI에서는 멀티 스케일 매칭 필요

자주 묻는 질문 (FAQ)

locateAllOnScreen과 locateOnScreen의 차이는 무엇인가요?
locateOnScreen은 첫 번째 매칭 결과만 반환하고, locateAllOnScreen은 화면에서 찾을 수 있는 모든 후보를 제너레이터로 반환합니다.
결과가 제너레이터로 반환된다고 하는데, 왜 list 변환이 필요한가요?
제너레이터는 1회성 반복 객체라 두 번 이상 순회하면 결과가 비어집니다. 따라서 list()로 변환해 안전하게 재사용하는 것이 좋습니다.
locateAllOnScreen이 너무 느린데 어떻게 개선할 수 있나요?
region으로 탐색 범위를 좁히거나 grayscale=True를 사용하면 속도가 개선됩니다. 또한 OpenCV를 설치해 confidence 옵션을 활용하면 효율이 높아집니다.
confidence 값을 사용할 때 오류가 나는 이유는 무엇인가요?
confidence 인자는 내부적으로 OpenCV를 사용하기 때문에, OpenCV가 설치되어 있지 않다면 오류가 발생합니다. pip install opencv-python으로 설치하면 해결됩니다.
중복 좌표가 발생하는 이유와 해결 방법은 무엇인가요?
그림자, 반사, UI 겹침 등으로 동일 좌표가 여러 번 탐지될 수 있습니다. 중심 좌표 간 거리를 비교해 일정 픽셀 이하는 중복으로 간주하고 제거하는 방법이 효과적입니다.
클릭 후 UI가 변하면 탐색 좌표가 무효화되는 경우 어떻게 하나요?
클릭 후 재탐색하는 방식으로 남은 요소를 다시 찾는 것이 안전합니다. 특히 UI가 자주 바뀌는 환경에서는 ‘클릭 → 재탐색 → 다음 클릭’ 패턴을 추천합니다.
PyAutoGUI 대신 OpenCV만 사용하는 것이 더 좋은가요?
OpenCV는 빠르고 정밀하지만 입력 이벤트를 지원하지 않습니다. 따라서 PyAutoGUI의 마우스/키보드 제어 기능과 병행해 사용하는 것이 가장 효율적입니다.
듀얼 모니터 환경에서도 locateAllOnScreen이 동작하나요?
기본적으로는 현재 메인 모니터 기준으로 탐지합니다. 듀얼 모니터 전체를 대상으로 하려면 화면 캡처 라이브러리를 활용해 확장된 이미지에서 OpenCV 매칭을 적용하는 방법을 권장합니다.

📌 PyAutoGUI 다중 매칭 처리와 성능 최적화 핵심 정리

locateAllOnScreen은 화면에서 동일한 패턴이 여러 번 등장할 때 유용하지만, 단순 순회만으로는 중복 클릭과 속도 저하 같은 문제가 발생할 수 있습니다.
따라서 결과를 list로 변환해 안정적으로 재사용하고, 좌표 정렬·중복 제거 로직을 반드시 포함하는 것이 좋습니다.
또한 region 제한, grayscale 변환, OpenCV와 confidence 활용 같은 성능 최적화 전략을 통해 탐색 속도를 크게 개선할 수 있습니다.

실패 대응과 예외 처리 역시 중요합니다.
UI가 바뀌면 탐색 좌표가 무효화되므로, 클릭 후 재탐색하는 안전한 루틴을 구성해야 합니다.
또한 OpenCV를 함께 사용하면 PyAutoGUI의 단순함과 OpenCV의 정밀함을 동시에 누릴 수 있어, 대규모 자동화에서도 높은 안정성을 확보할 수 있습니다.
결국, 정확도와 속도를 균형 있게 관리하는 것이 핵심이며, 본문에서 다룬 패턴과 최적화 기법을 습관화하면 실무 자동화의 완성도가 크게 향상됩니다.


🏷️ 관련 태그 : PyAutoGUI, locateAllOnScreen, 파이썬자동화, 화면인식, 이미지탐색, OpenCV, 성능최적화, 자동화스크립트, 중복클릭방지, UI테스트