微信跳一跳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中的正则表达式的用法
Apr 09 Python
Python设置Socket代理及实现远程摄像头控制的例子
Nov 13 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
May 18 Python
python3将视频流保存为本地视频文件
Jun 20 Python
PyCharm在新窗口打开项目的方法
Jan 17 Python
pow在python中的含义及用法
Jul 11 Python
python使用Pandas库提升项目的运行速度过程详解
Jul 12 Python
Python协程 yield与协程greenlet简单用法示例
Nov 22 Python
Tensorflow Summary用法学习笔记
Jan 10 Python
Python使用turtle库绘制小猪佩奇(实例代码)
Jan 16 Python
Django用户登录与注册系统的实现示例
Jun 03 Python
python 实现rolling和apply函数的向下取值操作
Jun 08 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常用数组函数介绍
2014/07/28 PHP
PHP实用函数分享之去除多余的0
2015/02/06 PHP
php中使用url传递数组的方法
2015/02/11 PHP
wamp服务器访问php非常缓慢的解决过程
2015/07/01 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
ExtJS 2.0实用简明教程 之Border区域布局
2009/04/29 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
jquery实现每个数字上都带进度条的幻灯片
2013/02/20 Javascript
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
JS+CSS实现淡入式焦点图片幻灯切换效果的方法
2015/02/26 Javascript
Node.js和MongoDB实现简单日志分析系统
2015/04/25 Javascript
JQuery中上下文选择器实现方法
2015/05/18 Javascript
jQuery悬停文字提示框插件jquery.tooltipster.js用法示例【附demo源码下载】
2016/07/19 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
node.js基于express使用websocket的方法
2017/11/09 Javascript
微信小程序中使用ECharts 异步加载数据实现图表功能
2018/07/13 Javascript
vue.js路由mode配置之去掉url上默认的#方法
2019/11/01 Javascript
VUE中V-IF条件判断改变元素的样式操作
2020/08/09 Javascript
JavaScript通如何过RGraph实现动态仪表盘
2020/10/15 Javascript
[37:37]DAC2018 4.4 淘汰赛 Optic vs Mineski 第二场
2018/04/05 DOTA
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
2018/03/22 Python
Python3 实现随机生成一组不重复数并按行写入文件
2018/04/09 Python
python计算n的阶乘的方法代码
2019/10/25 Python
Pytorch之卷积层的使用详解
2019/12/31 Python
Python 自由定制表格的实现示例
2020/03/20 Python
html5使用canvas实现跟随光标跳动的火焰效果
2014/01/07 HTML / CSS
办公室文秘岗位职责
2013/11/15 职场文书
博士学位自我鉴定范文
2013/12/26 职场文书
优秀党员自我评价范文
2014/09/15 职场文书
党员干部反四风民主生活会对照检查材料思想汇报
2014/10/12 职场文书
幼儿园五一劳动节活动总结
2015/02/09 职场文书
司机岗位职责范本
2015/04/10 职场文书
教师师德承诺书2016
2016/03/25 职场文书
win10+anaconda安装yolov5的方法及问题解决方案
2021/04/29 Python
Windows11性能真的上涨35%? 桌面酷睿i9实测结果公开
2021/11/21 数码科技
一文搞清楚MySQL count(*)、count(1)、count(col)区别
2022/03/03 MySQL