微信跳一跳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中的reduce内建函数使用方法指南
Aug 31 Python
Python函数参数类型*、**的区别
Apr 11 Python
python使用socket向客户端发送数据的方法
Apr 29 Python
python实现一个简单的并查集的示例代码
Mar 19 Python
详解Python3.6的py文件打包生成exe
Jul 13 Python
python自定义函数实现一个数的三次方计算方法
Jan 20 Python
python实现微信自动回复机器人功能
Jul 11 Python
python读写Excel表格的实例代码(简单实用)
Dec 19 Python
Django后台管理系统的图文使用教学
Jan 20 Python
在python里创建一个任务(Task)实例
Apr 25 Python
python自动打开浏览器下载zip并提取内容写入excel
Jan 04 Python
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
Jun 03 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/10/09 PHP
php smarty的预保留变量总结
2008/12/04 PHP
php 图片上传类代码
2009/07/17 PHP
ThinkPHP实现多数据库连接的解决方法
2014/07/01 PHP
PHP使用PHPExcel实现批量上传到数据库的方法
2017/06/08 PHP
PHP常用字符串输出方法分析(echo,print,printf及sprintf)
2021/03/09 PHP
JS Timing
2007/04/21 Javascript
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
JavaScript中检测变量是否存在遇到的一些问题
2013/11/11 Javascript
使表格的标题列可左右拉伸jquery插件封装
2014/11/24 Javascript
Javascript模拟加速运动与减速运动代码分享
2014/12/11 Javascript
jQuery Validation Plugin验证插件手动验证
2016/01/26 Javascript
JavaScript无阻塞加载和defer、async详解
2017/02/26 Javascript
Angular中ng-options下拉数据默认值的设定方法
2017/06/21 Javascript
JS简单实现点击跳转登陆邮箱功能的方法
2017/10/31 Javascript
JavaScript代码实现txt文件的上传预览功能
2018/03/27 Javascript
详解vue中的父子传值双向绑定及数据更新问题
2019/06/13 Javascript
jquery 键盘事件 keypress() keydown() keyup()用法总结
2019/10/23 jQuery
JavaScript面向对象核心知识与概念归纳整理
2020/05/09 Javascript
Vue实现点击箭头上下移动效果
2020/06/11 Javascript
vue实现登录功能
2020/12/31 Vue.js
从零学python系列之从文件读取和保存数据
2014/05/23 Python
python实现udp数据报传输的方法
2014/09/26 Python
简单的Python2.7编程初学经验总结
2015/04/01 Python
Python实现简易端口扫描器代码实例
2017/03/15 Python
Python编程之Re模块下的函数介绍
2017/10/28 Python
用Pygal绘制直方图代码示例
2017/12/07 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
django在保存图像的同时压缩图像示例代码详解
2020/02/11 Python
python实现不同数据库间数据同步功能
2021/02/25 Python
介绍一下EJB的分类及其各自的功能及应用
2016/08/23 面试题
Unix/Linux开发面试题
2016/08/16 面试题
试用期转正鉴定评语
2014/01/27 职场文书
《中华少年》教学反思
2014/02/15 职场文书
撤诉申请书法院范本
2015/05/18 职场文书
2015小学新教师个人工作总结
2015/10/14 职场文书