微信跳一跳实在是好玩。下面说下一个思路,如何通过目前的技术去自动点击。可能不是太具体,仅仅是思路,仅供参考。(实际操作的时候有点不是很准,可能是模型选错了)
具体实现见下文
使用了 openstf 开源的 minitouch 功能,安装 minitouch 的部分我先跳过,具体可以参考 minitouch 的首页https://github.com/openstf/minitouch
# Launch minitouch
$ adb forward tcp:1100 localabstract:minitouch
$ adb shell /data/local/tmp/minitouch
使用 python 连接 minitouch
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 1100))
print(s.recv(512))
# touch for 500ms
def touch(msecs):
s.send('\n'.join(['d 0 500 500 50', 'c', 'w %d' % msecs, 'u 0', 'c\n']))
猜测小人距离目标点的距离,与点击的时间成线性关系。
s = m*x + y
使用图像匹配获取小人的高度,如下代码使用了最简单的模版图像匹配。先用 uiautomator2 截一张图片 search.jpg
import uiautomator2 as u2
u = u2.connect()
u.screenshot('search.jpg')
用电脑中的图片编辑软件,进行裁剪,仅保留小人的下半部分。
获取小人的高度。
# reference: https://docs.opencv.org/trunk/d4/dc6/tutorial_py_template_matching.html
import cv2
import numpy as np
import uiautomator2 as u2
u = u2.connect() # connect to android device
# 获取当前屏幕图像(opencv格式)
pil_image = u.screenshot() # PIL.Image object
pil_image = pil_image.convert('RGB')
cv2_image = np.array(pil_image)
background = cv2.cvtColor(cv2_image, cv2.COLOR_RGB2GRAY)
# 读取search.jpg
search = cv2.imread('search.jpg', cv2.IMREAD_GRAYSCALE) # read grayscale
# 图片定位
res = cv2.matchTemplate(background, search, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# top_left = max_loc
# 起始点的坐标
h, w = search.shape[:2]
start = max_loc[0]+w/2, max_loc[1]+h
print("start:", start)
from sklearn.linear_model import LinearRegression
xtrain = np.array([1, 2, 3, 4, 5])
ytrain = np.array([2, 3, 4, 5, 7])
X = xtrain.reshape(len(xtrain), 1)
Y = ytrain.reshape(len(ytrain), 1)
linear_model = LinearRegression(normalize=True)
# Fit the OLS model to the data
linear_model.fit(X, Y)
print linear_model.intercept_
print linear_model.coef_
xtest = 5
yfit = linear_model.predict(np.array([[xtest]], dtype=np.float))
predict_ms = yfit[0][0] # 预测出的点击时间
先人工点击了很多很多次,预测预测出来的线性模型。
横轴是小人离目标点的像素距离,纵轴是点击时间(ms)
计算出的系数是 x = 5.4859, y = -31
s = m*x + y