用OpenCV实现的跳一跳外挂

    讲道理来说,对于手残人士,跳一跳这个微信小程序是可以将其逼疯的。当你按了半天屏幕,棋子却有自己的意识,义无反顾地跳向方块与方块之间的深渊中,此时只剩下绝望。好了,不扯淡了,主要是最近从零入门OpenCV,刚学了其中的一些函数,之前也了解了一些机器学习的知识,就想练练手,就想到了能否写一个跳一跳的外挂。

    简要步骤如下:

  1. 将手机上的截屏图片下载到电脑的文件夹中
  2. 识别得到图片中棋子的初始位置
  3. 用边缘识别的函数对整张图片进行处理,得到其边界轮廓图
  4. 找到棋子下一步要跳到的品台的目标位置
  5. 计算初始位置与目标位置的距离
  6. 根据距离计算需要按压屏幕的时间
  7. 调用函数对手机屏幕模拟按压对应的时间,实现模拟人机交互

    一开始的手机屏幕截图一般是这样的:

    

 

    得到了这张图像之后,可以使用OpenCV自带的matchTemplate函数使用实现准备好的模板图片,与原图匹配,寻找棋子的初始位置,我用的模板图像是自己手动截的图:

    

    使用OpenCV自带的边缘检测函数canny将原图转化为

    

    根据这个边缘识别后的图像可以很明显发现下一个方块的位置,那么如何去找到目标方块的中心点的位置呢?由于对于整个图像中所有方块平台的倾斜角度是一定的,方块上方的正方形在倾斜角度之后呈现的是一个60°和120°的菱形,我们只需要知道相邻的2个顶点的坐标就可以得到目标方块中心点的坐标了。但是这里存在一个问题:找哪2个点呢?当然是最上边和最右边的2个顶点比较好找,于是截取有效区域(大概上canny图像的上部分1/5到1/2部分),不仅如此,有时棋子的头部会进入这个有效区域内部,会影响顶点的查找,所以也需要把棋子的整体移除(已经知道了棋子的坐标,所以移除之后也没什么影响),具体图像如下:

    

    此时只需要从上到下遍历,从左到右遍历整个图像,去寻找那个像素点值是255即可,由此就得到了目标点的像素坐标。

    好咯!我们手上已经有了棋子的初始位置和目标位置,也就是我们知道了棋子要跳动的像素距离,那像素距离和屏幕的按压时间之间存在的是怎样的关系呢,线性关系,二次关系,指数关系,或是其他?由此只能从实验中得到(当然你可以去看跳一跳源码或者科学上网):

    所以我们需要按压时间,实际跳转距离这2个未知数的大小,我的做法是首先假设这是一个线性模型,预估其中的正比例参数,使得棋子能跳上平台即可,不要求正好跳到中间。接着我发现在按压结束的0.2秒的那一瞬间,截取手机屏幕可以得到棋子落地瞬间的图像,这时屏幕并未移动,所以可以再次使用cv2.matchtemplate函数去寻找棋子落地点的位置,这样就可以得到实际跳转距离,比如如下图像:

    

    再这样运行了很多次之后,就可以得到一系列按压时间-实际跳转距离的数据,存在文件中画出来的图像大致上为:

    

    图中的直线是我自己手动调参模拟出来的,不过也可以使用Linear Regression使用最小二乘法自动模拟出比较好的参数,从图像中可以很明显看出,这是一个线性模型。由此,所要求得的全部距离和参数都可以得到了,只需最后计算恰当的按压时间就可以交互棋子跳动了。

    代码链接:https://github.com/ziniBRC/TiaoYiTiao

    

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值