This commit is contained in:
HuangHai
2026-01-12 22:59:53 +08:00
parent fa1beb3b3f
commit b07dca28b5
9 changed files with 226 additions and 12 deletions

147
Tools/TestAdClick.py Normal file
View File

@@ -0,0 +1,147 @@
import uiautomator2 as u2
import time
import os
import cv2
import numpy as np
def test_click():
d = u2.connect()
w, h = d.window_size()
print(f"Device size: {w}x{h}")
# 1. Take screenshot
print("Taking screenshot...")
screenshot_path = r"d:\dsWork\aiData\Output\debug_ad_before.jpg"
d.screenshot(screenshot_path)
# 2. Check hierarchy
print("Dumping hierarchy...")
try:
xml = d.dump_hierarchy()
with open(r"d:\dsWork\aiData\Output\hierarchy.xml", "w", encoding="utf-8") as f:
f.write(xml)
print(r"Hierarchy saved to d:\dsWork\aiData\Output\hierarchy.xml")
except Exception as e:
print(f"Failed to dump hierarchy: {e}")
# 3. Visualize the current fixed point (80/1000, 835/1000)
# Norm: 0.08, 0.835
# Previous attempt was: (86, 2004) for 1080x2400
# Let's try to detect the black circle using HSV or thresholding
img = cv2.imread(screenshot_path)
if img is None:
print("Failed to load screenshot")
return
# ROI: Left side, bottom half
# x: 0 - 200, y: 1500 - 2200 (approx for 1080x2400)
roi_x1, roi_x2 = 0, int(w * 0.25)
roi_y1, roi_y2 = int(h * 0.6), int(h * 0.9)
roi = img[roi_y1:roi_y2, roi_x1:roi_x2]
# Convert to grayscale
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
# The close button is a black circle. So it should be very dark.
# Try multiple thresholds to find the best candidates
candidates = []
for threshold_val in [50, 70, 90, 110]:
_, thresh = cv2.threshold(gray, threshold_val, 255, cv2.THRESH_BINARY_INV)
# Find contours
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
area = cv2.contourArea(cnt)
# Approximate circle check
perimeter = cv2.arcLength(cnt, True)
if perimeter == 0: continue
circularity = 4 * np.pi * (area / (perimeter * perimeter))
# Filter by size and circularity
# Size: it's a small button
if 50 < area < 6000 and circularity > 0.35:
M = cv2.moments(cnt)
if M["m00"] != 0:
cX = int(M["m10"] / M["m00"]) + roi_x1
cY = int(M["m01"] / M["m00"]) + roi_y1
# Calculate normalized coordinates
norm_x = int(cX / w * 1000)
norm_y = int(cY / h * 1000)
# Avoid duplicates
if not any(abs(cX - c[0]) < 10 and abs(cY - c[1]) < 10 for c in candidates):
candidates.append((cX, cY, area, norm_x, norm_y))
# Save thresh image for debugging
_, debug_thresh = cv2.threshold(gray, 70, 255, cv2.THRESH_BINARY_INV)
cv2.imwrite(r"d:\dsWork\aiData\Output\debug_thresh.jpg", debug_thresh)
# Sort by proximity to expected location (Left side, Middle-Bottom)
# Expected norm: (93, 830)
def score_candidate(c):
# Weighting: X proximity is important, Y proximity is also important, Area around 400-500 is ideal
dist_x = abs(c[3] - 93)
dist_y = abs(c[4] - 830)
area_diff = abs(c[2] - 450) / 450.0
return dist_x * 2 + dist_y + area_diff * 100
candidates.sort(key=score_candidate)
target_x, target_y = int(w * 0.08), int(h * 0.835) # Default fallback
norm_target_x, norm_target_y = 80, 835
if candidates:
print(f"Found {len(candidates)} candidate close buttons via CV:")
for i, (cx, cy, area, nx, ny) in enumerate(candidates):
score = score_candidate((cx, cy, area, nx, ny))
print(f" Candidate {i}: ({cx}, {cy}), Area: {area}, Norm: ({nx}, {ny}), Score: {score:.2f}")
# Pick the best one
best_c = candidates[0]
target_x, target_y = best_c[0], best_c[1]
norm_target_x, norm_target_y = best_c[3], best_c[4]
print(f"Selected CV target: ({target_x}, {target_y}), Norm: ({norm_target_x}, {norm_target_y})")
else:
print("No CV candidates found. Using fixed coordinates.")
# Visualize
cv2.circle(img, (target_x, target_y), 20, (0, 255, 0), -1)
cv2.putText(img, f"Click ({target_x}, {target_y})", (target_x + 30, target_y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# Also draw the fixed point for comparison (Blue)
fixed_x = int(w * 0.08)
fixed_y = int(h * 0.835)
cv2.circle(img, (fixed_x, fixed_y), 15, (255, 0, 0), -1)
debug_path = r"d:\dsWork\aiData\Output\debug_ad_point.jpg"
cv2.imwrite(debug_path, img)
print(f"Debug image saved to {debug_path}")
# 4. Perform click
print(f"Clicking ({target_x}, {target_y}) using double_click...")
# Use d.double_click for a faster interaction
d.double_click(target_x, target_y, duration=0.05)
# NEW: Handle potential background click as per user's latest request
print("Waiting 2s for potential background card to load...")
time.sleep(2)
print("Pressing BACK to return to main page...")
d.press("back")
time.sleep(2)
# 5. Take after screenshot
after_path = r"d:\dsWork\aiData\Output\debug_ad_after.jpg"
d.screenshot(after_path)
print(f"After screenshot saved to {after_path}")
# Check if successful (compare image hash or just file size, though file size varies with compression)
# Simple check: If the black button is gone, the area should be brighter?
# Or just let user check.
if __name__ == "__main__":
test_click()