之前我在处理数据监测任务时,每天要盯着 3 个软件界面 —— 每隔 10 分钟就得检查是否弹出 “数据更新完成” 的提示框,看到后还要点击 “确认导出”,再手动打开文件夹核对文件。一天下来光做这些重复操作就占了 2 个多小时,有时候分心没及时看,还会错过数据导出时间。后来偶然发现了一款屏幕图像识别自动化工具,用熟之后这些操作全交给工具,每天直接省下不少时间,今天就把具体的使用方法分享给大家。

        这款工具的核心逻辑很简单:先让它 “记住” 屏幕上某个特定的图像(比如软件的提示框、按钮),之后工具会实时监测屏幕,一旦发现这个图像出现,就会自动执行我们提前设置好的操作 —— 比如点击按钮、打开文件,甚至是输入文字。不用写复杂的代码,纯图形化配置,对非技术出身的人也很友好。

        首先要做的是基础配置,这是工具能准确识别图像的关键。打开工具后,第一个要设置的是 “参照物图像”,也就是工具需要 “找” 的目标。这里有两个选择:要么从电脑里导入已经保存好的图像,要么直接截取当前屏幕上的元素。我更推荐直接截图,因为导入的图像可能因为分辨率、颜色偏差导致识别不准。截图时只要点击 “截取屏幕” 按钮,鼠标会变成十字光标,框选要识别的区域就行,要是不小心框错了,按 ESC 键就能取消。

        不过选参照物有几个坑我之前踩过,大家可以注意下。比如刚开始我选了软件界面上的时间显示区域当参照物,结果每过一分钟时间变了,工具就识别不到了;后来换成了软件固定的 “确认” 按钮 —— 按钮的颜色、形状不会变,而且有明显的边缘特征,识别成功率一下子就上去了。另外框选区域别太小,我试过只框按钮上的文字,大概 20x20 像素,结果有时候文字显示略有模糊就识别失败,后来把范围扩大到整个按钮,至少 50x50 像素,稳定性就好多了。还有纯颜色区域也别选,比如白色的背景,屏幕上到处都是类似的区域,工具很容易误判。选好的参照物会自动保存在工具目录下的 “screenshots” 文件夹里,下次打开不用重新设置。

        接下来是识别参数的调整,默认的 “归一化相关系数匹配” 算法其实不用改,我试过其他算法,反而没这个稳定。关键是 “识别精度阈值”,取值在 0-1 之间,默认是 0.8。之前我觉得精度越高越好,调到 0.95,结果有时候按钮上沾了个小光斑,工具就认不出来了;后来降到 0.7,又会把类似的按钮当成目标误操作。反复试了几次,发现 0.8 是个比较均衡的数值,既能保证准确,又不会太 “挑剔”。

        如果屏幕经常有轻微的噪点或者光线变化,还可以开 “图像预处理” 功能。我办公环境的灯光下午会变亮,屏幕有点反光,之前工具识别总是断断续续,后来勾了 “模糊处理”,它会自动减少细节干扰,勾了 “阈值处理” 后,按钮和背景的对比度更明显,识别就稳定多了。

        高级识别设置里,“过滤相似匹配” 一定要开,不然工具会把屏幕上多个类似的区域都当成目标,比如软件界面上有两个长得像的按钮,就会同时执行操作。这里还能设置 “最大匹配数量”,我目前设的是 5,之前设 10 的时候,工具监测时会有点卡顿,设 5 既能覆盖可能出现的多个目标,又不影响运行速度。另外 “边缘检测” 和 “显示匹配位置” 这两个功能,建议刚开始用的时候打开 —— 边缘检测会突出参照物的轮廓,方便确认是否选对了区域;显示匹配位置则会在屏幕上用红色方框标出识别到的目标,能直观看到工具有没有找对地方,调试的时候特别有用。

        配置好识别相关的设置后,就要设 “动作序列” 了,也就是工具识别到参照物后要做的事。我常用的是 “自动点击” 和 “延迟执行”。比如识别到 “数据更新完成” 提示框后,工具需要点击 “确认导出” 按钮,这里要注意点击坐标的设置 —— 刚开始我直接用了参照物的中心坐标,结果发现点击位置偏了一点,按钮没反应。后来发现可以用工具自带的 “坐标拾取” 功能,把鼠标移到按钮准确位置,点击一下就能获取坐标,再设置点击次数,比如一次左击,就不会出错了。

        有时候软件反应比较慢,识别到提示框后马上点击会没效果,这时候加个 “延迟执行” 就好。我一般设 1 秒,也就是工具识别到图像后,等 1 秒再点击,刚好能跟上软件的反应速度。如果需要更复杂的操作,比如点击后还要输入文字,也可以在动作序列里加 “输入文本” 的步骤,把要输入的内容提前填好,工具会自动完成。

        最后是工具的日常使用:所有配置调好后,一定要点 “保存配置”,不然下次打开又要重新设。保存好后点击 “启动监测”,工具就会最小化到任务栏,后台实时监测屏幕。如果中途想暂停,右键任务栏的工具图标就能找到暂停选项。另外 “日志” 模块很实用,每次工具识别到图像、执行操作,都会在这里记录时间和内容。之前有一次工具没执行操作,我打开日志一看,发现是 “screenshots” 文件夹被误删了,参照物图像找不到,很快就解决了问题。

import cv2
import numpy as np
import pyautogui
import time
import os
from datetime import datetime

class ScreenAutomation:
    def __init__(self):
        # 配置参数
        self.threshold = 0.8  # 识别精度阈值
        self.screenshot_dir = "screenshots"
        self.log_file = "automation_log.txt"
        
        # 确保截图目录存在
        if not os.path.exists(self.screenshot_dir):
            os.makedirs(self.screenshot_dir)

    def log(self, message):
        """记录操作日志"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"[{timestamp}] {message}\n"
        with open(self.log_file, "a", encoding="utf-8") as f:
            f.write(log_entry)
        print(log_entry.strip())

    def preprocess_image(self, image, blur=True, threshold=True):
        """预处理图像以提高识别率"""
        # 转为灰度图
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        
        # 模糊处理减少细节干扰
        if blur:
            gray = cv2.GaussianBlur(gray, (3, 3), 0)
        
        # 阈值处理增强对比度
        if threshold:
            _, gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
            
        return gray

    def find_image_on_screen(self, template_path, max_matches=5, show_matches=False):
        """在屏幕上查找匹配的图像"""
        # 加载模板图像
        if not os.path.exists(template_path):
            self.log(f"错误:模板图像 {template_path} 不存在")
            return []
        
        template = cv2.imread(template_path)
        if template is None:
            self.log(f"错误:无法加载模板图像 {template_path}")
            return []
            
        # 预处理模板
        template_gray = self.preprocess_image(template)
        template_height, template_width = template_gray.shape[:2]

        # 截取当前屏幕
        screen = pyautogui.screenshot()
        screen = cv2.cvtColor(np.array(screen), cv2.COLOR_RGB2BGR)
        screen_gray = self.preprocess_image(screen)

        # 模板匹配
        result = cv2.matchTemplate(screen_gray, template_gray, cv2.TM_CCOEFF_NORMED)
        locations = np.where(result >= self.threshold)

        # 收集匹配位置并去重(过滤相似匹配)
        matches = []
        for pt in zip(*locations[::-1]):
            # 计算中心点
            center_x = pt[0] + template_width // 2
            center_y = pt[1] + template_height // 2
            
            # 过滤过于接近的匹配点
            is_duplicate = False
            for existing in matches:
                if abs(center_x - existing[0]) < template_width // 2 and \
                   abs(center_y - existing[1]) < template_height // 2:
                    is_duplicate = True
                    break
                    
            if not is_duplicate:
                matches.append((center_x, center_y))
                if len(matches) >= max_matches:
                    break

        # 显示匹配位置(调试用)
        if show_matches and matches:
            for (x, y) in matches:
                cv2.rectangle(screen, 
                             (x - template_width//2, y - template_height//2),
                             (x + template_width//2, y + template_height//2),
                             (0, 255, 0), 2)
            
            cv2.imshow("Matches", screen)
            cv2.waitKey(2000)
            cv2.destroyAllWindows()

        return matches

    def capture_template(self, output_name):
        """截取屏幕区域作为模板图像"""
        self.log("请框选需要截取的区域(按ESC取消)")
        time.sleep(1)
        
        # 截取屏幕并让用户选择区域
        screenshot = pyautogui.screenshot()
        screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
        
        # 创建临时窗口用于选择区域
        roi = cv2.selectROI("选择模板区域", screenshot, False)
        cv2.destroyAllWindows()
        
        # 如果用户取消选择(区域为0)
        if roi[2] == 0 or roi[3] == 0:
            self.log("已取消截图")
            return None
            
        # 保存选择的区域
        x, y, w, h = roi
        template = screenshot[y:y+h, x:x+w]
        output_path = os.path.join(self.screenshot_dir, f"{output_name}.png")
        cv2.imwrite(output_path, template)
        
        self.log(f"模板已保存至 {output_path}")
        return output_path

    def perform_actions(self, positions):
        """在匹配位置执行预设操作"""
        for (x, y) in positions:
            self.log(f"在位置 ({x}, {y}) 执行操作")
            
            # 移动鼠标到目标位置
            pyautogui.moveTo(x, y, duration=0.5)
            
            # 点击操作(可根据需要修改为双击、右键等)
            pyautogui.click()
            
            # 可添加其他操作:输入文本、按键等
            # pyautogui.typewrite("需要输入的内容")
            # pyautogui.press("enter")
            
            time.sleep(1)  # 操作间隔

    def start_monitoring(self, template_path, interval=5):
        """开始监测屏幕并执行自动化操作"""
        self.log("开始监测屏幕...")
        try:
            while True:
                matches = self.find_image_on_screen(template_path)
                
                if matches:
                    self.log(f"发现 {len(matches)} 个匹配项")
                    self.perform_actions(matches)
                    # 执行操作后可添加延迟,避免重复操作
                    time.sleep(interval * 2)
                else:
                    self.log("未发现匹配项")
                    
                time.sleep(interval)
                
        except KeyboardInterrupt:
            self.log("监测已手动停止")
        except Exception as e:
            self.log(f"发生错误:{str(e)}")

if __name__ == "__main__":
    automation = ScreenAutomation()
    
    # 示例流程:
    # 1. 截取模板(首次使用时)
    # template_path = automation.capture_template("my_template")
    
    # 2. 使用已有的模板
    template_path = os.path.join("screenshots", "my_template.png")
    
    # 3. 开始监测(间隔5秒)
    if os.path.exists(template_path):
        automation.start_monitoring(template_path, interval=5)
    else:
        automation.log("未找到模板图像,请先截取模板")

        用了快一个月,现在我每天不用再盯着屏幕等提示,工具会自动处理数据导出、提示确认这些操作,算下来每天至少能多出来 2 小时,用来做更重要的事。如果你们也经常被屏幕重复操作拖累,不妨试试这款工具,按照上面的步骤配置,很快就能上手。

更多推荐