微信跳一跳python辅助软件思路及图像识别源码解析


Posted in Python onJanuary 04, 2018

本文将梳理github上最火的wechat_jump_game的实现思路,并解析其图像处理部分源码

首先废话少说先看效果

微信跳一跳python辅助软件思路及图像识别源码解析

核心思想

获取棋子到下一个方块的中心点的距离
计算触摸屏幕的时间
点击屏幕

重要方法

计算棋子到下一个方块中心点的距离

  • 使用 adb shell screencap -p 命令获取手机当前屏幕画面
  • 再通过图像上的信息找出棋子的坐标和下一个方块中心点的坐标
  • 然后通过两点间距离公式计算出距离

计算触摸屏幕的时间

T=A * S

其中S为上步算出的像素距离,T为按压时间(ms),A为一个系数这个系数会随着屏幕分辨率的变化而变化,在1920*1080的屏幕下这个系数为1.35,在2560*1440的屏幕下这个系数为1.475

点击屏幕

adb shell input swipe x y x y time(ms)

这条命令能够点击手机屏幕x,y位置time(ms)

图像处理部分源码解析

图像处理部分代码都在 find_piece_and_board(im) 方法中

通过输入的图像im计算出棋子的坐标点以及下一个方块中心的坐标点

在find_piece_and_board的方法中一进来就是下面的两个嵌套在一起的for循环:

for i in range(int(h / 3), int(h * 2 / 3), 50):
    last_pixel = im_pixel[0, i]
    for j in range(1, w):
      pixel = im_pixel[j, i]
      # 不是纯色的线,则记录 scan_start_y 的值,准备跳出循环
      if pixel[0] != last_pixel[0] or pixel[1] != last_pixel[1] or pixel[2] != last_pixel[2]:
        scan_start_y = i - 50
        break
    if scan_start_y:
      break

这段代码的作用就是从屏幕2/3的位置向下寻找不是纯色的线。并将找到位置的纵坐标-50作为,寻找棋子和方块的起始坐标。这样可以简化以后搜索的工作量,因为在这个横坐标以上是没有东西的。

接下来是查找棋子坐标的代码

# 查找棋子坐标
  # piece_x_sum 横坐标总量 piece_x_c 点的个数 piece_y_max 纵坐标最大值
  # 从 scan_start_y 开始往下扫描,棋子应位于屏幕上半部分,这里暂定不超过 2/3
  for i in range(scan_start_y, int(h * 2 / 3)):
    for j in range(scan_x_border, w - scan_x_border): # 横坐标方面也减少了一部分扫描开销
      pixel = im_pixel[j, i]
      # 根据棋子的最低行的颜色判断,找最后一行那些点的平均值,这个颜色这样应该 OK,暂时不提出来
      if (50 < pixel[0] < 60) and (53 < pixel[1] < 63) and (95 < pixel[2] < 110):
        piece_x_sum += j
        piece_x_c += 1
        piece_y_max = max(i, piece_y_max)

  if not all((piece_x_sum, piece_x_c)):
    return 0, 0, 0, 0
  # 平均横坐标
  piece_x = int(piece_x_sum / piece_x_c)
  # 纵坐标最大值-底座一半的高度
  piece_y = piece_y_max - piece_base_height_1_2 # 上移棋子底盘高度的一半

查找棋子的重要依据就是棋子的颜色较为单一并且和方块的颜色有较大差距。如果一个像素点的RGB像素值在B(50, 60), G(53, 63), R(95, 110)范围内那么就认为这个像素点是属于棋子的。根据以上信息就能计算出棋子的平均横坐标,以及最大的纵坐标值。

所以不难计算出棋子坐标(棋子平均横坐标, 棋子最大纵坐标 - 底座一半的高度)其中底座一半的高度因手机分辨率而异。需要提前配置好。

最后是查找下一个方块中心点的坐标的代码

# 寻找最高的棋盘
  # 棋盘不会和棋子在同一侧
  # 限制棋盘扫描的横坐标,避免音符 bug
  if piece_x < w / 2:
    board_x_start = piece_x
    board_x_end = w
  else:
    board_x_start = 0
    board_x_end = piece_x
  for i in range(int(h / 3), int(h * 2 / 3)):
    last_pixel = im_pixel[0, i]
    if board_x or board_y:
      break
    board_x_sum = 0
    board_x_c = 0
    for j in range(int(board_x_start), int(board_x_end)):
      pixel = im_pixel[j, i]
      # 下一个棋盘紧贴着棋子
      # 修掉脑袋比下一个小格子还高的情况的 bug
      if abs(j - piece_x) < piece_body_width:
        continue
      # 修掉圆顶的时候一条线导致的小 bug,这个颜色判断应该 OK,暂时不提出来
      if abs(pixel[0] - last_pixel[0]) + abs(pixel[1] - last_pixel[1]) + abs(pixel[2] - last_pixel[2]) > 10:
        board_x_sum += j
        board_x_c += 1
    if board_x_sum:
      # 最高棋盘的平均横坐标
      board_x = board_x_sum / board_x_c
  last_pixel = im_pixel[board_x, i]

代码开头通过棋子所在的屏幕位置限制搜索的宽度,如果棋子在屏幕左边那么就在屏幕右边搜索方块,反之亦然。因为方块和棋子不会在屏幕同一侧。

然后就是自上而下得搜索方块的上顶点。

方块上顶点坐标( 平均横坐标,当前行的纵坐标)

然后再往下纵坐标+247的位置开始向上找颜色与上顶点一样的点,为下顶点。
当然此方法有一点局限性对于纯色的平面效果很好但是对于非纯色的平面。可能会判断出错。

如果上一跳命中中间,则下个目标中心会出现 r245 g245 b245 的点,利用这个属性弥补上一段代码可能存在的判断错误
若上一跳由于某种原因没有跳到正中间,而下一跳恰好有无法正确识别花纹,则有可能游戏失败,由于花纹面积通常比较大,失败概率较低

可改进方案

首先是目前方案对于多分辨率需要多个配置文件来记录不同分辨率下的系数以及棋子底盘一半的高度。随机测试了6台手机其中有两台手机因没有配饰而无法正常运作

首先是系数A,观察方程T=A * S,A就是一个可训练量,利用机器学习框架比如TensorFlow,对这个一元一次方程进行拟合。

观察棋子底盘一半的高度在代码中的作用。不难发现是为了求出棋子底盘中心的纵坐标。而棋子底盘中心的位置恰恰是棋子最宽的地方。所以可以通过找出棋子最宽处的纵坐标的方式找到棋子底盘中心的纵坐标。这样就摆脱了对配置文件的依赖,能让代码在任何手机上正常运行。

其次是对于方块中心坐标位置的判断方法出错率较高,虽然有中心白点可以弥补但是在大量跳跃的过程中还是会出现错误。3太手机不停运行了一下午,最高分只有2009分。

现方法出错率高的原因是使用纯颜色方法判断,但是在实际游戏中颜色丰富的方块也不少。如果想改变就不能依赖颜色方法判断,而应该通过几何图像的形状来计算方块的位置。不难发现游戏中方块只有棱形和圆形两种形状。

首先通过canny或其他轮廓查找算子提取出图像的轮廓,然后通过霍夫变换提取出圆形和棱形的中心坐标。

总结

以上所述是小编给大家介绍的微信跳一跳python辅助软件思路及图像识别源码解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
使用python调用浏览器并打开一个网址的例子
Jun 05 Python
Python 2.7.x 和 3.x 版本的重要区别小结
Nov 28 Python
python字符串的常用操作方法小结
May 21 Python
Python中super函数的用法
Nov 17 Python
利用Python正则表达式过滤敏感词的方法
Jan 21 Python
python 根据字典的键值进行排序的方法
Jul 24 Python
使用NumPy读取MNIST数据的实现代码示例
Nov 20 Python
Tensorflow tf.tile()的用法实例分析
May 22 Python
django 模型字段设置默认值代码
Jul 15 Python
Python中Yield的基本用法
Oct 18 Python
详解selenium + chromedriver 被反爬的解决方法
Oct 28 Python
Python os和os.path模块详情
Apr 02 Python
Python操作MongoDB数据库的方法示例
Jan 04 #Python
Python字典操作详细介绍及字典内建方法分享
Jan 04 #Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
Jan 04 #Python
Python给你的头像加上圣诞帽
Jan 04 #Python
Python编程实现线性回归和批量梯度下降法代码实例
Jan 04 #Python
Python语言描述随机梯度下降法
Jan 04 #Python
微信小程序跳一跳游戏 python脚本跳一跳刷高分技巧
Jan 04 #Python
You might like
PHP常用代码
2006/11/23 PHP
用PHP连接MySQL代码的参数说明
2008/06/07 PHP
DEDE采集大师官方留后门的删除办法
2011/01/08 PHP
php数字转汉字代码(算法)
2011/10/08 PHP
php加速缓存器opcache,apc,xcache,eAccelerator原理与配置方法实例分析
2020/03/02 PHP
js控制input框只读实现示例
2014/01/20 Javascript
利用Jquery实现可多选的下拉框
2014/02/21 Javascript
使用jquery prev()方法找到同级的前一个元素
2014/07/11 Javascript
JQuery ztree 异步加载实例讲解
2016/02/25 Javascript
Nodejs中 npm常用命令详解
2016/07/04 NodeJs
Vue.directive自定义指令的使用详解
2017/03/10 Javascript
详解如何使用Vue2做服务端渲染
2017/03/29 Javascript
详解vue-cli本地环境API代理设置和解决跨域
2017/09/05 Javascript
JavaScript控制浏览器全屏显示简单示例
2018/07/05 Javascript
Vue中的methods、watch、computed的区别
2018/11/26 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
浅谈使用nodejs搭建web服务器的过程
2020/07/20 NodeJs
从零学python系列之新版本导入httplib模块报ImportError解决方案
2014/05/23 Python
python中的二维列表实例详解
2018/06/19 Python
pyQt4实现俄罗斯方块游戏
2018/06/26 Python
Python列表生成式与生成器操作示例
2018/08/01 Python
python的xpath获取div标签内html内容,实现innerhtml功能的方法
2019/01/02 Python
Python 抓取微信公众号账号信息的方法
2019/06/14 Python
使用python+whoosh实现全文检索
2019/12/09 Python
详解Python IO口多路复用
2020/06/17 Python
Python三维绘图之Matplotlib库的使用方法
2020/09/20 Python
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
精美的手工家居和生活用品:Nkuku
2019/11/01 全球购物
开办饭店创业计划书
2013/12/28 职场文书
经典毕业生求职信
2014/07/12 职场文书
党性教育心得体会
2014/09/03 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
整改报告格式
2014/11/06 职场文书
高中生综合素质自我评价
2015/03/06 职场文书
法制教育观后感
2015/06/17 职场文书
将图片保存到mysql数据库并展示在前端页面的实现代码
2021/05/02 MySQL