'commit'
This commit is contained in:
@@ -1,24 +1,126 @@
|
||||
# coding=utf-8
|
||||
import cv2
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
try:
|
||||
import uiautomator2 as u2
|
||||
except ImportError:
|
||||
u2 = None
|
||||
|
||||
def analyze_chat_image(image_path, output_path):
|
||||
print(f"正在读取图片: {image_path}")
|
||||
|
||||
# 读取图片
|
||||
# 注意:cv2.imread 不支持中文路径,需要用 np.fromfile 读取
|
||||
# 添加项目根目录到 sys.path 以便导入 Util
|
||||
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 Util.EasyOcrKit import get_easyocr_reader
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(level=logging.INFO, format='%(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def find_input_box_center(image_path):
|
||||
"""
|
||||
识别底部输入框的中心坐标
|
||||
"""
|
||||
try:
|
||||
img_data = np.fromfile(image_path, dtype=np.uint8)
|
||||
img = cv2.imdecode(img_data, cv2.IMREAD_COLOR)
|
||||
if img is None:
|
||||
return None
|
||||
|
||||
height, width = img.shape[:2]
|
||||
|
||||
# 截取底部 15% 区域
|
||||
bottom_h = int(height * 0.15)
|
||||
crop_y_start = height - bottom_h
|
||||
crop = img[crop_y_start:height, 0:width]
|
||||
|
||||
# 预处理
|
||||
gray = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY)
|
||||
# 简单二值化,输入框通常是浅色或深色背景上的反色
|
||||
# 这里假设深色模式下,输入框可能较亮,或者有边框
|
||||
# 尝试自适应阈值
|
||||
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
|
||||
cv2.THRESH_BINARY_INV, 11, 2)
|
||||
|
||||
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
best_cnt = None
|
||||
max_area = 0
|
||||
|
||||
for cnt in contours:
|
||||
x, y, w, h = cv2.boundingRect(cnt)
|
||||
# 筛选条件:宽度较大 (比如 > 50% 屏幕宽),高度适中
|
||||
if w > width * 0.5 and h > 20:
|
||||
if w * h > max_area:
|
||||
max_area = w * h
|
||||
best_cnt = (x, y, w, h)
|
||||
|
||||
if best_cnt:
|
||||
x, y, w, h = best_cnt
|
||||
center_x = x + w // 2
|
||||
center_y = crop_y_start + y + h // 2
|
||||
logger.info(f"找到输入框: ({center_x}, {center_y}), 尺寸: {w}x{h}")
|
||||
return center_x, center_y
|
||||
else:
|
||||
# 兜底:返回底部区域中心
|
||||
logger.warning("未找到明显输入框轮廓,使用默认坐标")
|
||||
return width // 2, int(height * 0.95)
|
||||
|
||||
except Exception as e:
|
||||
print(f"读取图片失败: {e}")
|
||||
logger.error(f"查找输入框失败: {e}")
|
||||
return None
|
||||
|
||||
def perform_input_action(coords, text):
|
||||
"""
|
||||
点击坐标并输入文本
|
||||
"""
|
||||
if u2 is None:
|
||||
logger.error("未安装 uiautomator2 库,无法执行自动化操作")
|
||||
return
|
||||
|
||||
if img is None:
|
||||
print("图片读取为空")
|
||||
if not coords:
|
||||
logger.error("坐标无效,无法执行点击输入")
|
||||
return
|
||||
|
||||
x, y = coords
|
||||
try:
|
||||
# 连接设备 (默认连接第一个 USB 设备)
|
||||
d = u2.connect()
|
||||
logger.info(f"设备连接成功: {d.info.get('serial')}")
|
||||
|
||||
# 点击输入框
|
||||
logger.info(f"点击坐标: ({x}, {y})")
|
||||
d.click(x, y)
|
||||
|
||||
# 等待键盘弹出或输入框激活
|
||||
time.sleep(1)
|
||||
|
||||
# 输入文本
|
||||
logger.info(f"输入文本: {text}")
|
||||
d.send_keys(text)
|
||||
|
||||
# 尝试发送回车键以确认输入 (视具体情况而定)
|
||||
# d.press("enter")
|
||||
|
||||
logger.info("输入完成")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"自动化操作失败: {e}")
|
||||
print(f"自动化操作失败: {e}")
|
||||
|
||||
def analyze_chat_image(image_path, output_path, target_name="对方"):
|
||||
# 读取图片(支持中文路径)
|
||||
img_data = np.fromfile(image_path, dtype=np.uint8)
|
||||
img = cv2.imdecode(img_data, cv2.IMREAD_COLOR)
|
||||
|
||||
# 备份一份干净的图片用于 OCR (避免识别到画上去的框)
|
||||
img_clean = img.copy()
|
||||
|
||||
height, width = img.shape[:2]
|
||||
print(f"图片尺寸: {width}x{height}")
|
||||
|
||||
@@ -79,6 +181,16 @@ def analyze_chat_image(image_path, output_path):
|
||||
|
||||
print(f"找到有效头像数量: {len(avatars)}")
|
||||
|
||||
# 初始化 OCR
|
||||
try:
|
||||
reader = get_easyocr_reader(gpu=True)
|
||||
print("OCR 初始化成功")
|
||||
except Exception as e:
|
||||
print(f"OCR 初始化失败: {e}")
|
||||
reader = None
|
||||
|
||||
dialogue_log = []
|
||||
|
||||
# 4. 绘制对话内容框 (Green/Red Boxes)
|
||||
# 策略:按顺序遍历头像,如果发现同侧连续,则视为一组。
|
||||
# 从当前组的第一个头像上方开始,直到下一个不同侧的头像上方(或底部)。
|
||||
@@ -122,6 +234,49 @@ def analyze_chat_image(image_path, output_path):
|
||||
|
||||
print(f"绘制内容框: 侧别={current_side}, 范围 Y={start_y} to {end_y}")
|
||||
|
||||
# OCR 识别区域文本
|
||||
if reader:
|
||||
try:
|
||||
# 从原图(img_clean)裁剪区域
|
||||
# 注意边界检查
|
||||
safe_start_y = max(0, start_y)
|
||||
safe_end_y = min(height, end_y)
|
||||
|
||||
if safe_end_y > safe_start_y:
|
||||
roi_img = img_clean[safe_start_y:safe_end_y, 0:width]
|
||||
|
||||
# 识别
|
||||
results = reader.read_text(roi_img)
|
||||
|
||||
# 过滤关键词
|
||||
ignore_keywords = ["点击查看对话内容", "以上是打招呼的消息", "和 Kimi 的对话", "Kim智能助手"]
|
||||
|
||||
# 过滤并拼接文本 (置信度 > 0.3)
|
||||
texts = []
|
||||
for res in results:
|
||||
text = res[1]
|
||||
prob = res[2]
|
||||
if prob > 0.3:
|
||||
# 1. 检查是否包含屏蔽词
|
||||
if any(kw in text for kw in ignore_keywords):
|
||||
continue
|
||||
|
||||
# 2. 检查是否为单行时间 (如 11:35, 09:00)
|
||||
# 正则匹配: 只有时间格式,没有其他文字
|
||||
if re.match(r'^\s*\d{1,2}:\d{2}\s*$', text):
|
||||
continue
|
||||
|
||||
texts.append(text)
|
||||
|
||||
combined_text = " ".join(texts)
|
||||
|
||||
if combined_text.strip():
|
||||
role = target_name if current_side == "Left" else "我"
|
||||
dialogue_log.append(f"{role}: {combined_text}")
|
||||
print(f" -> OCR结果: {combined_text}")
|
||||
except Exception as e:
|
||||
print(f" -> OCR出错: {e}")
|
||||
|
||||
# 移动到下一组
|
||||
i = j
|
||||
|
||||
@@ -144,10 +299,32 @@ def analyze_chat_image(image_path, output_path):
|
||||
except Exception as e:
|
||||
print(f"保存图片失败: {e}")
|
||||
|
||||
print("\n" + "="*30)
|
||||
print("对话内容汇总:")
|
||||
for line in dialogue_log:
|
||||
print(line)
|
||||
print("="*30 + "\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 输入文件路径
|
||||
input_file = r"d:\dsWork\aiData\Test\Screenshots\chat_result_20260121_113553.jpg"
|
||||
# 输出文件路径
|
||||
output_file = r"d:\dsWork\aiData\Test\Screenshots\chat_result_analyzed.jpg"
|
||||
|
||||
analyze_chat_image(input_file, output_file)
|
||||
# 目标联系人名称 (对应搜索关键字)
|
||||
target_name = "糖豆爸爸"
|
||||
|
||||
analyze_chat_image(input_file, output_file, target_name=target_name)
|
||||
|
||||
# 2. 查找输入框并执行自动化操作
|
||||
print("\n" + "="*30)
|
||||
print("开始执行自动化输入...")
|
||||
|
||||
# 注意: 这里使用 input_file (截图) 来定位坐标
|
||||
# 前提是截图时的界面布局与当前设备界面一致
|
||||
coords = find_input_box_center(input_file)
|
||||
if coords:
|
||||
print(f"输入框坐标: {coords}")
|
||||
perform_input_action(coords, "AI助手我现在可以开始和你聊天了!")
|
||||
else:
|
||||
print("未找到输入框坐标")
|
||||
|
||||
Reference in New Issue
Block a user