'commit'
This commit is contained in:
BIN
WeiXin/Screenshots/T6_debug_view.jpg
Normal file
BIN
WeiXin/Screenshots/T6_debug_view.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
BIN
WeiXin/Screenshots/t6_live_shot.jpg
Normal file
BIN
WeiXin/Screenshots/t6_live_shot.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
@@ -1,160 +0,0 @@
|
||||
# coding=utf-8
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import cv2
|
||||
|
||||
# 添加项目根目录到 sys.path
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if project_root not in sys.path:
|
||||
sys.path.append(project_root)
|
||||
|
||||
from WeiXin import WxUtil
|
||||
from WeiXin.WxUtil import get_vlm_analysis
|
||||
from Util.EasyOcrKit import EasyOcrKit
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger("T5_VLM_Voice_Debug")
|
||||
|
||||
async def main():
|
||||
logger.info("🚀 T6 VLM 语音坐标调试工具启动...")
|
||||
|
||||
# 连接设备
|
||||
d = WxUtil.connect_device()
|
||||
if not d:
|
||||
return
|
||||
|
||||
# 截图目录
|
||||
screenshots_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Screenshots")
|
||||
if not os.path.exists(screenshots_dir):
|
||||
os.makedirs(screenshots_dir)
|
||||
|
||||
# 截图
|
||||
screenshot_path = os.path.join(screenshots_dir, "t6_debug_temp.jpg")
|
||||
logger.info("📸 正在截图...")
|
||||
d.screenshot(screenshot_path)
|
||||
|
||||
# 调用 VLM 分析
|
||||
logger.info("🧠 正在调用 VLM 分析图片...")
|
||||
result_data = await get_vlm_analysis(screenshot_path)
|
||||
|
||||
if not result_data:
|
||||
logger.error("❌ VLM 分析返回为空")
|
||||
return
|
||||
|
||||
logger.info(f"VLM 返回结果: {result_data}")
|
||||
|
||||
# 读取图片用于绘制
|
||||
img = cv2.imread(screenshot_path)
|
||||
if img is None:
|
||||
logger.error("❌ 无法读取截图文件")
|
||||
return
|
||||
|
||||
messages = result_data.get("messages", [])
|
||||
voice_count = 0
|
||||
|
||||
for msg in messages:
|
||||
msg_type = msg.get("type")
|
||||
content = msg.get("content")
|
||||
coords = msg.get("coordinates") or msg.get("center")
|
||||
|
||||
if not coords:
|
||||
continue
|
||||
|
||||
x, y = coords
|
||||
|
||||
if msg_type == "voice":
|
||||
voice_count += 1
|
||||
logger.info(f"🎤 发现语音消息: {content}, 坐标: ({x}, {y})")
|
||||
|
||||
# 绘制绿框 (语音)
|
||||
w, h = 300, 80
|
||||
top_left = (int(x - w/2), int(y - h/2))
|
||||
bottom_right = (int(x + w/2), int(y + h/2))
|
||||
|
||||
cv2.rectangle(img, top_left, bottom_right, (0, 255, 0), 3)
|
||||
cv2.circle(img, (int(x), int(y)), 5, (0, 0, 255), -1)
|
||||
label = f"Voice ({x},{y})"
|
||||
cv2.putText(img, label, (top_left[0], top_left[1] - 10),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
|
||||
|
||||
# 保存结果图片
|
||||
output_path = os.path.join(screenshots_dir, "t6_debug_result.jpg")
|
||||
cv2.imwrite(output_path, img)
|
||||
logger.info(f"✅ 结果已保存至: {output_path}")
|
||||
logger.info(f"共标记了 {voice_count} 条语音消息。请检查图片是否准确。")
|
||||
|
||||
# --- 验证转文字功能 (处理最后一条未转换语音) ---
|
||||
logger.info("="*30)
|
||||
logger.info("🔍 开始验证“转文字”功能 (仅针对最后一条未转换语音)...")
|
||||
|
||||
# 筛选未转换的语音
|
||||
unconverted_voices = []
|
||||
for msg in messages:
|
||||
if msg.get("type") == "voice" and msg.get("status") == "unconverted":
|
||||
coords = msg.get("coordinates") or msg.get("center")
|
||||
if coords:
|
||||
msg["coordinates"] = coords
|
||||
unconverted_voices.append(msg)
|
||||
|
||||
if not unconverted_voices:
|
||||
logger.info("⚠️ 没有发现未转换的语音消息,跳过验证。")
|
||||
else:
|
||||
last_voice = unconverted_voices[-1]
|
||||
vx, vy = last_voice['coordinates']
|
||||
content = last_voice.get('content', '0"')
|
||||
logger.info(f"🎯 目标语音: {content}, 坐标: ({vx}, {vy})")
|
||||
|
||||
# 1. 长按
|
||||
logger.info(f"👆 长按语音消息...")
|
||||
d.long_click(vx, vy, 1.5)
|
||||
time.sleep(1.0)
|
||||
|
||||
# 2. 截图菜单
|
||||
menu_shot_path = os.path.join(screenshots_dir, "t6_menu_shot.jpg")
|
||||
logger.info(f"📸 截取菜单: {menu_shot_path}")
|
||||
d.screenshot(menu_shot_path)
|
||||
|
||||
# 3. OCR 识别
|
||||
logger.info("🧠 正在进行 OCR 识别菜单...")
|
||||
ocr_kit = EasyOcrKit()
|
||||
ocr_results = ocr_kit.read_text(menu_shot_path)
|
||||
|
||||
convert_btn_center = None
|
||||
for bbox, text, conf in ocr_results:
|
||||
if "转文字" in text or "转换为文字" in text:
|
||||
c_x = int((bbox[0][0] + bbox[2][0]) / 2)
|
||||
c_y = int((bbox[0][1] + bbox[2][1]) / 2)
|
||||
convert_btn_center = (c_x, c_y)
|
||||
logger.info(f"✅ OCR 找到 '{text}' 按钮: {convert_btn_center}")
|
||||
break
|
||||
|
||||
if convert_btn_center:
|
||||
# 4. 点击转文字
|
||||
logger.info(f"👆 点击转文字按钮: {convert_btn_center}")
|
||||
d.click(convert_btn_center[0], convert_btn_center[1])
|
||||
|
||||
# 5. 动态等待
|
||||
duration_str = content.replace('"', '').strip()
|
||||
try:
|
||||
duration = int(duration_str)
|
||||
except:
|
||||
duration = 10
|
||||
|
||||
wait_seconds = max(2, duration / 5.0)
|
||||
logger.info(f"⏳ 语音时长 {duration}s,模拟等待 {wait_seconds:.1f}s...")
|
||||
time.sleep(wait_seconds)
|
||||
logger.info("✅ 流程执行完毕!请检查手机屏幕是否已开始转换。")
|
||||
else:
|
||||
logger.error("❌ OCR 未找到 '转文字' 按钮!")
|
||||
# 点击空白处关闭
|
||||
d.click(vx + 200, vy)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if sys.platform.startswith('win'):
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
asyncio.run(main())
|
||||
@@ -64,23 +64,33 @@ def run_cv_debug():
|
||||
continue
|
||||
|
||||
sender = "对方" if ax < 500 else "我"
|
||||
|
||||
# --- 1. 先判断是否未读 (寻找附近的红点) ---
|
||||
is_unread = False
|
||||
|
||||
# 1. 绘制语音图标绿框 (根据模板大小,假设 60x60)
|
||||
cv2.rectangle(img, (int(ax-30), int(ay-30)), (int(ax+30), int(ay+30)), (0, 255, 0), 3)
|
||||
|
||||
# 2. 绘制模拟点击红点 (用户要求用红点标出模拟点击位置)
|
||||
cv2.circle(img, (int(ax), int(ay)), 15, (0, 0, 255), -1)
|
||||
|
||||
# 3. 检查并标记未读红点 (如果存在)
|
||||
for rx, ry in red_points:
|
||||
if abs(ry - ay) < 50 and rx > ax:
|
||||
is_unread = True
|
||||
# 绘制未读红点
|
||||
cv2.circle(img, (int(rx), int(ry)), 12, (0, 0, 255), -1)
|
||||
break
|
||||
|
||||
print(f"标注语音消息: ({ax}, {ay}), 发送者: {sender}, 未读: {is_unread}")
|
||||
# --- 2. 根据状态选择颜色 ---
|
||||
# BGR 格式: 红色 (0, 0, 255), 绿色 (0, 255, 0)
|
||||
color = (0, 0, 255) if is_unread else (0, 255, 0)
|
||||
status_text = "未读" if is_unread else "已读"
|
||||
|
||||
# --- 3. 绘制标注 ---
|
||||
# 语音图标框 (加粗)
|
||||
cv2.rectangle(img, (int(ax-35), int(ay-35)), (int(ax+35), int(ay+35)), color, 3)
|
||||
|
||||
# 中心点击位置 (实心圆)
|
||||
cv2.circle(img, (int(ax), int(ay)), 15, color, -1)
|
||||
|
||||
# 如果是未读,把原本识别到的红点也再次标出
|
||||
if is_unread:
|
||||
for rx, ry in red_points:
|
||||
if abs(ry - ay) < 50 and rx > ax:
|
||||
cv2.circle(img, (int(rx), int(ry)), 12, (0, 0, 255), -1)
|
||||
|
||||
print(f"标注语音消息: ({ax}, {ay}), 发送者: {sender}, 状态: {status_text}")
|
||||
|
||||
# 保存结果
|
||||
cv2.imwrite(output_path, img)
|
||||
|
||||
Reference in New Issue
Block a user