【Python + 按键精灵】《找别扭》自动识别、聚类与过关

《找别扭》的窗口骇死我咧,Python鼠标不能直接够到它,又不能窗口化,只能使用《按键精灵》或在虚拟机里运行。Python部分:

import threading
import tkinter as tk
import random
import matplotlib
import win32gui
import win32con
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageTk, ImageChops
import pyautogui
from sklearn.cluster import KMeans
import time


x0, y0, x, W, H, border, image, imageTK = 16, 151, 386, 380, 292, 0, None, None
canvas, label = None, None
text = "按Space键计算"


def calculate():
    global image, imageTK
    diff = []  # 找出不同的点
    img = pyautogui.screenshot()
    background = img.crop((x0, y0, x0 + W, y0 + H))
    img1 = img.crop((x0 + border, y0 + border, x0 + W - border, y0 + H - border))  # 截图当前活动窗口
    img2 = img.crop((x0 + x + border, y0 + border, x0 + x + W - border, y0 + H - border))
    sub = ImageChops.subtract(img1, img2)
    imageTK = ImageTk.PhotoImage(sub)
    image = canvas.create_image(0, 0, anchor="nw", image=imageTK)

    for xi in range(W - 2 * border):
        for yi in range(5, H - 2 * border):
            pixel1, pixel2 = img1.getpixel((xi, yi)), img2.getpixel((xi, yi))
            if max(abs(pixel1[0] - pixel2[0]), abs(pixel1[1] - pixel2[1]), abs(pixel1[2] - pixel2[2])) > 16:
                row = [xi + border, H - 1 - yi + border]
                if random.random() < 0.1:
                    diff.append(row)
    diff = np.array(diff)

    Solver = KMeans(n_clusters=5, n_init=20)  # 把不同的点分成五类
    Solver.fit(diff)
    result = Solver.predict(diff)
    C = Solver.cluster_centers_  # 质心、点击处

    plt.cla()
    plt.imshow(background.transpose(Image.FLIP_TOP_BOTTOM))
    plt.scatter(diff[:, 0], diff[:, 1] - 2 * border, c="red", marker='s', s=20)
    plt.scatter(diff[:, 0], diff[:, 1] - 2 * border, c=result, marker='s', s=10)
    plt.scatter(C[:, 0], C[:, 1]-2*border, c="red", edgecolors='black', s=50)
    plt.xlim(0, W)
    plt.ylim(0, H)
    plt.savefig(r'D:\录像/封面.png')
    img = Image.open(r'D:\录像/封面.png')
    imageTK = ImageTk.PhotoImage(img)
    image = canvas.create_image(0, 0, anchor="nw", image=imageTK)

    title = ''
    print(C)
    for c in C:
        title += f'{int(x0 + border + c[0])}x{int(y0 + H - border - c[1])}y'
    print(title)
    window.title(title)


def onKeyDown(e):
    global label, text
    if e == "space":  # 空格
        text = "计算中"
        label.config(text=text)
        # test()
        calculate()
        text = "按Space键计算"
        label.config(text=text)
    # 你可以添加一些延迟来避免过高的CPU使用率
    # 例如,使用 time.sleep(0.1) 来每100毫秒检查一次按键状态
    return 0


def test():  # 校准
    img = pyautogui.screenshot()
    for dx in range(10, 30):
        img1 = img.crop((x0 + border, y0 + border, x0 + W - border, y0 + H - border))  # 截图当前活动窗口
        img2 = img.crop((x0 + x + dx + border, y0 + border, x0 + x + dx + W - border, y0 + H - border))
        sub = ImageChops.subtract(img1, img2)
        sub.save(fr"D:\录像\VipSongsDownload/x={x+dx}.jpg")


def thread():
    global text
    while True:
        if window.title() != tk and text == "按Space键计算":
            onKeyDown(window.title())
        time.sleep(0.5)


window = tk.Tk()
window.focus_set()  # 设置窗口焦点以接收按键事件
label = tk.Label(window, text=text)
label.pack()
canvas = tk.Canvas(window, bg='white', width=640, height=480)
canvas.pack()


# 创建一个Thread对象,target参数指定要在线程中运行的函数
second_thread = threading.Thread(target=thread)
second_thread.start()  # 启动线程
window.mainloop()  # 开始Tkinter的事件循环

将结果传递给按键精灵并执行的部分:

// 按键精灵端——收发消息和点击
tk = Plugin.Window.Find("TkTopLevel", "tk")  // 抓取TK窗口的句柄
title = Plugin.Window.GetText(tk)
x0 = 400
y0 = 300

If title <> "space" Then
	Call Plugin.Window.SetText(tk, "space")
	While Plugin.Window.GetText(tk) = "space"

	Wend
	//当循环条件成立的时候,反复执行循环体
	str = Plugin.Window.GetText(tk)
	i = 1
	x = 0
	y = 0
	res = ""
	For Len(str)
		c = Mid(str, i, 1)
		If c="x" Then
			x = CInt(res)
			res = ""
		ElseIf c="y" Then
			y = CInt(res)
			TracePrint (CStr(x) + " " + CStr(y))
			MoveTo -3*x0, -3*y0
			MoveTo x*2+x0, y*2+y0
			LeftClick 1
			Delay 200
			x = 0
			y = 0
			res = ""
		Else
			res = res + c
		End If
		i = i+1
	Next
	Call Plugin.Window.SetText(tk, "tk")
End If

// 按键精灵端——将TK窗口置顶并放在屏幕2居中放置
Hwnd = Plugin.Window.Find("TkTopLevel", "tk")
Call Plugin.Window.Move(Hwnd, 800, 250)
Call Plugin.Window.Top(Hwnd, 0)

// 按键精灵端——进入下一关
x0 = 400
y0 = 300

MoveTo -3*x0, -3*y0
MoveTo 400*2+x0, 520*2+y0
LeftClick 1

// 按键精灵端——使用Joker
x0 = 400
y0 = 300

MoveTo -3*x0, -3*y0
MoveTo 300*2+x0, 120*2+y0
LeftClick 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值