"""仅检测缺口(修正版) + ASCII 验证, 不 swipe。""" from __future__ import annotations import subprocess from io import BytesIO import numpy as np from PIL import Image PHOTO_LEFT = 66 def cap(): d = subprocess.run(["adb", "exec-out", "screencap", "-p"], capture_output=True, timeout=30).stdout return np.asarray(Image.open(BytesIO(d)).convert("L")) def detect_notch(img, x_min_local=230, col_thr=25): reg = img[267:819, PHOTO_LEFT:1013] # 552 x 947 col = (reg < 90).sum(axis=0) col_r = col[x_min_local:] # 只看 home 右侧 hot = np.where(col_r > col_thr)[0] if len(hot) == 0: return None br = np.where(np.diff(hot) > 12)[0] segs = [s for s in np.split(hot, br + 1) if len(s) > 10] seg = max(segs, key=lambda s: col_r[s].sum()) # 缺口实心簇 segL = x_min_local + int(seg[0]) segR = x_min_local + int(seg[-1]) # 在 seg 列范围内取 <95 像素的面积加权质心 = 缺口中心 block = (reg[:, segL:segR + 1] < 95) ys, xs = np.where(block) if len(xs) == 0: return None cx_local = int(round(np.average(xs + segL))) cy_local = int(round(np.average(ys))) return dict(center=PHOTO_LEFT + cx_local, seg_local=(segL, segR), body_local=(segL, segR), cy=267 + cy_local) def main(): img = cap() n = detect_notch(img) print("notch:", n) if not n: return cl = n["center"] - PHOTO_LEFT L, R = max(0, cl - 170), min(947, cl + 170) reg = img[267:819, PHOTO_LEFT:1013] for y in range(0, 552, 8): line = "".join("#" if reg[y, x] < 90 else ("+" if reg[y, x] < 140 else ".") for x in range(int(L), int(R))) if any(c in line for c in "#+"): print(f"y{267+y:4d} {line}") print(f"(window local[{int(L)},{int(R)}] center_screen={n['center']})") if __name__ == "__main__": main()