Tìm kiếm

Hướng dẫn

Tesseract OCR cho bot game Android: đọc bộ đếm

Cho bot game Android dùng Tesseract OCR với read_text trong MAS: chọn vùng trong Asset Lab, chỉnh psm và chuyển đổi màu, rồi phân tích bộ đếm và đồng hồ.

  • Windows
  • Mac
  • Giả lập
  • Thiết bị đám mây
  • Điện thoại
  • Studio
  • Python SDK
Trung bình Cập nhật 7 phút đọc
Trong trang này
  1. Trước khi bắt đầu
  2. Cách Tesseract OCR hoạt động trong bot game Android
  3. Chọn vùng OCR trong Asset Lab
  4. Chọn mô hình
  5. Chọn chế độ phân đoạn trang
  6. Sửa chữ sáng trên nền tối
  7. Đặt thời gian chờ
  8. Phân tích số từ chữ
  9. Dùng độ tin cậy
  10. Dùng lại một ảnh chụp màn hình
  11. Đọc chữ trên giả lập Android bằng Python: ví dụ hoàn chỉnh
  12. Khắc phục sự cố
  13. OCR trả về chuỗi rỗng
  14. Đọc sai chữ số
  15. OCR chậm

So khớp mẫu cho bot game Android biết một nút có trên màn hình hay không. Tesseract OCR cho nó biết bộ đếm ghi gì: năng lượng 8 trên 50, đồng hồ ở 00:42, một con số cấp độ. Hướng dẫn này đưa mas.read_text với Tesseract OCR từ một vùng vẽ trong Asset Lab đến một macro dừng khi năng lượng xuống dưới giới hạn. Trang dành cho bất kỳ ai viết macro Macro Automation Studio (MAS) bằng Python trên giả lập, thiết bị cloud hoặc điện thoại.

Trước khi bắt đầu

  • Một dự án Code-Based đang mở trong Code Editor và đã chọn thiết bị. Xem Bắt đầu.
  • Ứng dụng hoặc game đang hiển thị chữ bạn muốn đọc, ở độ phân giải bạn sẽ giữ.
  • Bạn đã đọc hướng dẫn nhận diện hình ảnh hoặc biết Region là gì.

Cách Tesseract OCR hoạt động trong bot game Android

read_text gửi một ảnh chụp màn hình, hoặc phần nằm trong một vùng, tới Tesseract OCR bên trong ứng dụng. Nó trả về những gì bộ máy đọc được.

python
def read_text(
    region: Region | None = None,
    screenshot: Screenshot | None = None,
    model: str = "eng_best",
    psm: int = 7,
    color_conversion: ColorConversion = ColorConversion.NONE,
    timeout_ms: int = 30000,
) -> TextRecognitionResult

Kết quả là một TextRecognitionResult với ba trường: text (chuỗi), confidence (0.0 đến 1.0) và region (nơi nó đã nhìn). Đọc cả màn hình vẫn được, nhưng một vùng sát nhanh hơn và chính xác hơn nhiều, nên bước đầu tiên luôn là vùng.

Chọn vùng OCR trong Asset Lab

  1. Đưa thiết bị tới màn hình có bộ đếm.
  2. Trong Code Editor, mở bảng Tài nguyên và nhấn Mở Asset Helper. Asset Lab mở với màn hình đang chạy.
  3. Vẽ một khung quanh chữ. Chừa một chút lề, nhưng không có biểu tượng, viền hay con số bên cạnh.
  4. Chạy kiểm thử OCR trực tiếp. Chỉnh khung cho đến khi chữ trả về sạch; kiểm thử dùng cùng bộ máy với mã của bạn.
  5. Chép bốn tọa độ vào một Region(x1, y1, x2, y2).
python
import mas
from mas import Region

ENERGY = Region(x1=380, y1=20, x2=520, y2=60)

result = mas.read_text(region=ENERGY)
print(repr(result.text), result.confidence)

In bằng repr trong lúc chỉnh: nó hiển thị dấu cách và xuống dòng thừa mà print giấu đi. Vùng là tọa độ pixel ở độ phân giải lúc chụp, nên hãy giữ mọi thiết bị ở độ phân giải đó. Xem Asset Lab.

Chọn mô hình

model chọn dữ liệu Tesseract. "eng_best" là mặc định và chính xác nhất; "eng_fast" đổi độ chính xác lấy tốc độ trên chữ sạch; "eng" là bộ tiếng Anh chuẩn. Bắt đầu với mặc định và chỉ đổi khi một vòng lặp đọc hàng chục lần mỗi phút.

Chọn chế độ phân đoạn trang

psm cho Tesseract biết cần mong đợi hình dạng chữ nào. Sai chế độ là nguyên nhân phổ biến nhất của kết quả trống hoặc rác.

psmMong đợiDùng cho
7Một dòng chữ đơn (mặc định)Bộ đếm, đồng hồ, nhãn một dòng
8Một từ đơnMột con số lẻ hoặc huy hiệu ngắn
6Một khối chữ đồng nhấtMột đoạn văn trong hộp thoại
11Chữ rải rác bất kỳ đâu, không thứ tựCả màn hình, một danh sách kết quả
python
level = mas.read_text(region=Region(x1=20, y1=20, x2=90, y2=60), psm=8)
dialog = mas.read_text(region=Region(x1=60, y1=300, x2=480, y2=600), psm=6)

Giá trị chạy từ 0 đến 13, nhưng bốn chế độ này bao gần như mọi macro. Khi một vùng một dòng trả về trống, thử 8 trước, rồi 6.

Sửa chữ sáng trên nền tối

Tesseract mong đợi chữ tối trên nền sáng. Bộ đếm trong game thường ngược lại, chữ số trắng trên thanh tối, hay có viền màu. color_conversion tiền xử lý mẩu cắt trước khi OCR.

python
from mas import ColorConversion

energy = mas.read_text(
    region=ENERGY,
    psm=7,
    color_conversion=ColorConversion.BLACK_WHITE,
)
  • ColorConversion.NONE (mặc định) gửi pixel nguyên trạng.
  • ColorConversion.BLACK_WHITE chuyển sang thang xám và áp ngưỡng tự động, cho ra đen trắng thuần. Đây là lựa chọn thử đầu tiên tốt nhất cho chữ tương phản cao trên nền nhiễu hoặc có màu.
  • ColorConversion.BGR_TO_GRAY hoặc RGB_TO_GRAY cho thang xám thuần, hữu ích khi ngưỡng trong BLACK_WHITE ăn mất nét mảnh.

Thử từng tùy chọn trong Asset Lab trên màn hình thật. Không có thành viên GRAYSCALE; dùng một trong các tên ở trên.

Đặt thời gian chờ

timeout_ms mặc định là 30000. Một vùng sát với psm=7 trả về dưới một giây; một lần đọc toàn màn hình psm=11 trên màn hình bận mất lâu hơn. Hạ thời gian chờ trong vòng lặp cần phản hồi nhanh, và bọc lời gọi để một lần đọc chậm không kết thúc lần chạy.

python
try:
    result = mas.read_text(region=ENERGY, timeout_ms=5000)
except mas.RPCError as e:
    mas.log(f"OCR failed: {e}", level="warning")
    result = None

Phân tích số từ chữ

result.text là một chuỗi, đôi khi có dấu cách, dấu phẩy, dấu gạch chéo hoặc một chữ cái lạc. Phân tích bằng biểu thức chính quy và coi “không có số” là một kết quả thật.

python
import re

def first_int(text: str) -> int | None:
    cleaned = text.replace(",", "").replace("O", "0").replace("l", "1")
    m = re.search(r"\d+", cleaned)
    return int(m.group()) if m else None

def current_and_max(text: str) -> tuple[int | None, int | None]:
    m = re.search(r"(\d+)\s*/\s*(\d+)", text.replace(",", ""))
    return (int(m.group(1)), int(m.group(2))) if m else (None, None)

first_int("Energy 1,250") cho 1250; current_and_max("8/50") cho (8, 50). Việc đổi Ol sửa hai lỗi đọc chữ số phổ biến nhất; chỉ áp dụng cho các vùng chỉ chứa chữ số.

Dùng độ tin cậy

confidence chạy từ 0.0 đến 1.0 trên các từ Tesseract tìm thấy. Một bộ đếm sạch đọc ở 0.9 trở lên. Khi nó giảm, đọc lại trước khi hành động theo giá trị, và ghi cả hai để bạn thấy được quy luật về sau.

python
for attempt in range(3):
    result = mas.read_text(region=ENERGY, psm=7)
    value = first_int(result.text)
    if value is not None and result.confidence >= 0.8:
        break
    mas.log(f"Low confidence {result.confidence:.2f} for {result.text!r}", level="warning")

Dùng lại một ảnh chụp màn hình

Mỗi read_text chụp một khung hình mới trừ khi bạn truyền vào một cái. Khi một vòng lặp đọc nhiều vùng cùng lúc, chụp một ảnh và truyền cho từng lời gọi; các giá trị khi đó thuộc cùng một khoảnh khắc.

python
shot = mas.take_screenshot()
energy = mas.read_text(region=ENERGY, screenshot=shot)
gold = mas.read_text(region=GOLD, screenshot=shot)

Đọc chữ trên giả lập Android bằng Python: ví dụ hoàn chỉnh

Mã này chạm vào một nút cho đến khi bộ đếm năng lượng xuống dưới giới hạn hoặc hết ngân sách thời gian. Thay vùng, ID ảnh và giới hạn bằng của bạn.

python
import random
import re
import sys
import time

import mas
from mas import ColorConversion, Region

images = mas.images({"attack_button": 101})

ENERGY = Region(x1=380, y1=20, x2=520, y2=60)
MIN_ENERGY = 10
TIME_BUDGET_S = 15 * 60


def read_energy() -> int | None:
    for _ in range(3):
        result = mas.read_text(
            region=ENERGY,
            psm=7,
            color_conversion=ColorConversion.BLACK_WHITE,
            timeout_ms=5000,
        )
        m = re.search(r"\d+", result.text.replace(",", "").replace("O", "0"))
        if m and result.confidence >= 0.7:
            return int(m.group())
        mas.log(f"Unclear energy {result.text!r} ({result.confidence:.2f})", level="warning")
        time.sleep(1)
    return None


def main():
    started = time.monotonic()
    unreadable = 0

    while time.monotonic() - started < TIME_BUDGET_S:
        energy = read_energy()
        if energy is None:
            unreadable += 1
            if unreadable >= 5:
                mas.log("Energy unreadable five times, stopping", level="error")
                sys.exit(2)
            continue
        unreadable = 0
        if energy < MIN_ENERGY:
            mas.log(f"Energy {energy} is below {MIN_ENERGY}, done")
            break

        button = mas.find_object_retry(images.attack_button, total_tries=3, time_sleep=2.0)
        if button is None:
            mas.log("Attack button not found", level="warning")
            continue
        mas.click(button.x, button.y, delay_ms=1000)
        time.sleep(random.uniform(0.8, 2.0))

    mas.log("Finished")


if __name__ == "__main__":
    main()

Đọc trước mỗi cú chạm giữ macro trung thực: nó không bao giờ tiêu năng lượng mà nó không thấy. Bộ đếm unreadable biến một vùng hỏng thành một lần chạy thất bại, mà webhook trên macro.failed có thể báo. Xem Vòng lặp và lập lịch. Nếu bạn muốn mô tả tác vụ thay vì viết, MAS Agent đo vùng và viết mã này cho bạn.

Khắc phục sự cố

OCR trả về chuỗi rỗng

Vùng không trúng chữ, chế độ sai, hoặc chữ sáng trên nền tối. Kiểm tra vùng trong Asset Lab, đổi psm sang 8 cho một con số hoặc 6 cho một khối, và thêm color_conversion=ColorConversion.BLACK_WHITE. Chữ rất nhỏ cũng đọc thành trống. Nếu chữ số chỉ cao vài pixel, tăng độ phân giải của giả lập trong cài đặt màn hình và chụp lại mọi vùng.

Đọc sai chữ số

Số 0 đọc thành chữ O, số 1 thành l, số 8 thành B, hoặc dấu phẩy biến mất. Trước hết thu hẹp vùng để không biểu tượng nào chạm vào chữ số. Rồi thử BLACK_WHITE, và nếu nét bị đứt, dùng BGR_TO_GRAY thay thế. Cuối cùng, chuẩn hóa trong mã: thay O bằng 0l bằng 1 trong các vùng chỉ có chữ số, bỏ dấu phẩy, và loại các giá trị nhảy vọt giữa các lần đọc.

OCR chậm

Đọc toàn màn hình với psm=11eng_best là trường hợp chậm. Đọc một vùng, không phải cả màn hình; dùng psm=7 hoặc 8; và truyền một screenshot cho nhiều lời gọi. model="eng_fast" giúp trên chữ sạch. Nếu một lần đọc vẫn mất vài giây, vùng có lẽ quá lớn; một bộ đếm chỉ cần khung rộng tối đa vài trăm pixel.

Không có công cụ tự động hóa nào an toàn 100%, vì vậy hãy tự động hóa một cách có trách nhiệm và theo quyết định của riêng bạn.

Bước tiếp theo

Trang liên quan

Trang này có hữu ích không?

Có câu hỏi? Hỏi trên Discord