之前有看到微信小程序《跳一跳》别人用python实现自动运行,后来看到别人用hash码实现《加减大师》的自动答题领取娃娃,最近一直在研究深度学习,为啥不用机器学习实现呢?不就是一个分类问题吗

如何实现自动答题微信小游戏《加减大师》?

思考:

  • 图像识别吗?
  • 如何建立特征工程?
  • 选用什么算法?

一、图像特征工程

如何获取手机游戏上的图片?

  • 使用adb命令截取手机屏幕;
  • 在PC端和手机端同时运行APowerMirror软件,将手机投屏到电脑上,然后使用Pillow包中的截图方法截取电脑上对应手机屏幕的
    区域。
  • 在PC端和手机端同时运行APowerMirror软件,将手机投屏到电脑上,然后使用Python调用windows的原生API截取电脑上对应手机屏幕的区域。

实验结果: 三种截屏方式花费的时间差异很大,第一种每次截屏需要0.7s左右,第二种0.3s左右,第三种0.04s左右。

当然选择第3种咯,下载地址[https://www.apowersoft.cn/phone-mirror],一个好的软件是成功的关键(够清晰)。

获取训练样本

相关步骤:

1.util.py中的shotByWinAPI函数:首先利用window自带api获取全屏图片,然后自定义config.py的相关参数。

# 从PC端截屏时,截取区域左上角相对桌面的x坐标
'projection_x': 32,
# 从PC端截屏时,截取区域左上角相对桌面的y坐标
'projection_y': 278,
# 从PC端截屏时,截取区域的宽度
'projection_width': 482,
# 从PC端截屏时,截取区域的高度
'projection_height': 854,

可以用window命令键PrtScSysRq(F12的右边),然后复制到画图中(1920x1080)。


用画图的放大镜放大,图中红色框的小方块位置(32x278)projection_x即32,projection_y即278。


在画图中计算出截图的宽度和高度,即projection_widthprojection_height(482x854)

2.img_tool.py函数介绍:主要是通过all(img, filename)函数进行图片分割

srcImg = cv2.imread(os.path.join("ScreenShotForTrain", f), 0)

上述代码是为了将彩色图片灰度模式加载

-----------------------------------------------------------------------------------------------

def all(img, filename):"""封装对图片的所有操作"""img = cropImg(img)img = binaryImg(img)img1, img2 = cropAgain(img)imgs = cutImg(img1, filename + '_1') + cutImg(img2, filename + '_2')return imgsdef cropImg(img):"""裁剪原始截图"""height = img.shape[0]img2 = img[int(config.config['exp_area_top_rate'] * height):int(config.config['exp_area_bottom_rate'] * height),:]#print('裁剪完毕')return  img2

cropImg(img)函数主要是为了裁剪含有数字的区域,通过设置参数

#表达式区域的顶部处于整张图片的位置(307/854=0.359)
'exp_area_top_rate': 0.36,
#表达式区域的底部处于整张图片的位置(478/854=0.559)
'exp_area_bottom_rate': 0.56,

如果觉得设置比例太麻烦,可以直接写死位置(img2 = img[int(307):int(478),:])。得到如下图:

----------------

def binaryImg(img):"""二值化图片"""ret, thresh1 = cv2.threshold(img, config.config['binary_threshold'], 255, cv2.THRESH_BINARY)# ret, thresh1 = cv2.threshold(img, config.config['binary_threshold'], 255, cv2.THRESH_BINARY_INV)#print('二值化完毕')return thresh1

binaryImg(img)函数主要是为了将图片二值化,可以参考
Python+OpenCV教程6:阈值分割。得到的图片如下图:


def cropAgain(img):"""再次裁剪"""height = img.shape[0]img1 = img[0:int(0.5 * height), :]img2 = img[int(0.5 * height):height, :]#print('再次裁剪完毕')return img1, img2

cropAgain(img)函数主要是为了将图片分成上下两部分



def cutImg(img, filename):"""水平分割图片"""sb = np.array(img)print(sb.shape)sum_list = np.array(img).sum(axis=0)start_index = -1res = []names = []index = 0for sum in sum_list:if sum > 255 * 4:if start_index == -1:start_index = indexelse:if start_index != -1:if config.config['type'] == 0:sigleCharWidth = config.config['abd_single_char_width']else:sigleCharWidth = config.config['pc_single_char_width']#为了防止字符粘连,需要在此处宽度进行判断if index - start_index > sigleCharWidth * 2:res.append((start_index,start_index + (index - start_index) // 2))res.append((start_index + (index - start_index) // 2, index))else:res.append((start_index, index))start_index = -1index += 1imgs = []count = 0for single_char in res:start = single_char[0]end = single_char[1]sub_img = img[:, start:end]sub_img = cv2.resize(sub_img, (120, 240), interpolation=cv2.INTER_CUBIC)#cv2.imwrite('SingleChar/%s_%d.png' % (filename, count), sub_img)#names.append('%s_%d.png' % (filename, count))# cv2.imshow(str(count), sub_img)imgs.append(sub_img)count += 1# cv2.waitKey()#print('分割,重新设置大小 %s 完毕' %filename)return  imgs

设置pc_single_char_width参数值,得到如下图:


c = 0
def v_cut(img):global c"""竖直方向切割图片"""sb1 = np.array(img)print(sb1.shape)sum_list = np.array(img).sum(axis=1)start_index = -1end = -1index = 0for sum in sum_list:if sum > 255 * 2:start_index = indexbreakindex += 1for i in range(1, len(sum_list) + 1):if sum_list[-i] > 255 * 2:end = len(sum_list) + 1 - ibreakimg = img[start_index:end, :]img = cv2.resize(img, (30, 60), interpolation=cv2.INTER_CUBIC)#cv2.imwrite('SingleChar/%d.png' %c, img)c += 1return img

重新固定图片的大小(30x60),得到如下图:


二、训练模型,建立LR分类器

相关代码请看ml.py,这里不过多介绍,直接利用python包from sklearn.linear_model import LogisticRegression

LogisticRegression(class_weight='balanced')

sklearn逻辑回归(Logistic Regression,LR)类库使用小结

三、自动答题模式开启

实现原理

  • 1.截取游戏界面,本项目中提供了三种方案。
    在PC端和手机端同时运行APowerMirror软件,将手机投屏到电脑上,然后使用Python调用windows的原生API截取电脑上对应手机屏幕的区域。

  • 2.提取截屏图片中的表达式区域并进行文字识别,得到表达式字符串。
    由于图片中的表达式区域固定,而且字符规整,因此这一步不是很困难,我仅仅训练了一个简单的逻辑回归模型就得到了非常高的识别正确率。

  • 3.根据第二步得到的表达式,调用Python的eval()函数,得到表达式结果的正误,然后点击手机屏幕的相应区域。当截图使用投屏的方案时,点击手机屏幕通过代码点击
    电脑上手机的对应区域。

首次操作,生成分类器模型

1.借用投屏软件,利用画图工具配置相关参数config.py,可以参考上面的“图像特征工程”

2.对于新的手机(我用的是honor8),必须重新训练模型,设置config.py中的debug参数为True,打开“加减大师”,然后运行main.py,这里必须手动答题,尽可能多答对一些题,目的为了扩充训练样本。

3.步骤2会产生一个SingleCharForTrain文件夹,剔除重复样本和无关样本。

4.运行img_tool.py文件,会生成一个SingleCharForTrain文件夹。

5.将步骤4得到的文件夹中的字符进行人工分类,保存至TrainChar文件夹。

6.运行ml.py文件,生成分类器模型lr.pickle

注意桌面上不要有东西遮挡到手机的投影区域

根据分类器模型自动答题

1.修改config.py中的debug参数为False及其他相关参数。

#使用PC进行截图时点击手机屏幕正确区域的x坐标
'pc_tap_true_x':117,
#使用PC进行截图时点击手机屏幕错误区域的x坐标
'pc_tap_false_x':365,
#使用PC进行截图时点击手机屏幕正确和区域的y坐标
'pc_tap_y':760,

配置正确和错误选择的横纵坐标,横坐标不一样,纵坐标相同(在同一高度)

2.打开加减大师,直接运行main.py即可。

遇到的问题

Q1: 跑到200步左右就停了?

A1: 如果是误判的话,把出错的那张图重新截图,将得到的字符添加到TrainChar文件夹中,重新训练模型

A1: 如果是上一张图和这张图相同,再跑一次呗,不相信你运气会那么差


Q2: 刷到1000分,结果小程序上不了分

A2: 刚开始以为是答题时间没有设置随机的问题,设置main.py

one_tap(res)
# 设置随机睡眠时间,随机性防止微信后台检测
if (count < 100):time.sleep(0.1 * (random.randint(0, 9)))
elif (count <200):time.sleep(0.05 * (random.randint(0, 9)))
elif (count <300):time.sleep(0.01 * (random.randint(0, 9)))
elif (count < 400):time.sleep(0.01 * (random.randint(0, 9)))
elif (count < 500):# 可以控制到这一关ggif (count == 455):time.sleep(3)

然而并没有软用,估计是后台设置(个人认为,当天的分数不能超过第一名太多),反正是前500都能获得小卡片,你可以尝试设置比第一名多个几分或少几分。

四、源代码地址

记得给哥们的github打♥啊

上代码:https://github.com/Yiutto/WechatGame_jjds

有问题私聊我yiutto@qq.com

最后放出我的娃娃来,手机上显示的是这样的

到手的时候却是这样的(本来以为没戏了,等了将近一个星期)

最后,祝大家都能拿到娃娃!!!

转载于:https://www.cnblogs.com/Yiutto/p/9440397.html

利用机器学习实现微信小程序-加减大师自动答题相关推荐

  1. Python 打造微信小程序-加减大师辅助程序

    写在前面: 主要运用python进行简单的图像处理,不得不说python用起来是真的爽,各种库的学习使得开发变得越来越简单... 其实玩过这个小程序的应该知道实现起来也不是很难,很适合新手练手.第一次 ...

  2. 微信小程序 加减控件

    微信小程序 加减控件 <!--index.wxml--> <view class='stepper'><text class='{{minusStatus}}' type ...

  3. php点击查看更多,微信小程序加载更多和点击查看更多功能介绍

    这篇文章主要为大家详细介绍了微信小程序加载更多,点击查看更多功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了微信小程序加载更多功能实现的具体代码,供大家参考,具体内容如下 ...

  4. 微信小程序加签验签(wxapp_rsa,jsencrypt)和egg搭建的后端交互(jsrsasign,node_rsa)最全!!!

    微信小程序加签验签(wxapp_rsa,jsencrypt)和egg搭建的后端交互(jsrsasign,node_rsa)最全!!! RAS加密 ​ RSA加密算法是一种非对称加密算法. ​ 假设 A ...

  5. HTML 点击查看更多,微信小程序加载更多和点击查看更多的实现方法

    微信小程序加载更多和点击查看更多的实现方法 发布时间:2020-12-31 11:01:19 来源:亿速云 阅读:126 作者:小新 这篇文章给大家分享的是有关微信小程序加载更多和点击查看更多的实现方 ...

  6. 微信小程序加载 FengMap地图

    实现微信小程序加载FengMap地图,主要通过小程序<web-view>组件的src属性的外链方式加载,如<web-view src="https://fengmap.co ...

  7. 微信小程序在线成语接龙答题有奖1.5.1版源码

    简介: 微信小程序在线成语接龙答题有奖源码是一款搭建在微擎上使用的 成语接龙答题有奖红包,可配合流量主推广,广告变现,后台含有区间余额区间奖励配置,自定义金额提现配置: 题库后台自己输入就可以. 开通 ...

  8. 微信小程序:开心锤锤超火动态表情包微信小程序源码下载自动采集

    这是一款表情包小程序源码 大家刷抖音的时候应该都刷过开心锤锤这个网红卡通短视频吧 现在这一款小程序就是和它有关的 里面的表情包呢大部分都是动态表情包(斗图的时候是不是更炫) 至于里面的表情包人物的就都 ...

  9. 微信小程序开发之编译自动生成新文件的解决办法

    文章目录 前言 微信小程序开发中一自动编译就自动生成一些wxss,wxml,文件的解决办法 一. 问题详情 二.为什么会出现这个情况 三.解决办法 1.找到app.json文件夹下的具体页面详情 2. ...

  10. 微信小程序公众号开发者自动编译,热启动,自动保存

    微信小程序公众号开发者自动编译,热启动,自动保存 1.自动保存 选择左上角设置➡编辑器设置➡勾选需要的设置即可 2.热启动 选择右上角详情➡本地设置➡勾选启动代码自动热重载(建议搭配自动保存使用)

最新文章

  1. javascript小实例,PC网页里的拖拽(转)
  2. 多多点金——青龙羊毛
  3. [Java 安全]加密算法
  4. HTMl语言编写的文件扩展名,用HTML编写的文件的扩展名是()。
  5. 将四个整数进行从小到大的顺序排列 java_07_Java基础语法_第7天(练习)_讲义(练习加强+在eclipse中实现)...
  6. Hadoop 集群的三种方式
  7. 星辰网址缩短源码支持二维码
  8. 秒级快速批量创建kvm虚拟机并指定IP地址和主机名
  9. 区块链技术指南学习笔记1
  10. 模拟钟表的手机软件_手机时钟软件推荐
  11. imewlconverter 制作Rime词库
  12. 液晶显示器的基本知识
  13. 我的wow血精灵圣骑士,晒晒
  14. iOS_21团购_拼音搜索
  15. 如何用计算机直接做工资表,超简单一招!用Excel十秒快速制作工资条
  16. 用SQL分析北京周边城市:天津以及保定房价
  17. HAPI使用方法总结(HITRAN数据库,HITEMP数据库)
  18. 《调和级数》python
  19. 【上海赛区】2022数学建模国赛获奖名单公布
  20. 简述关系数据库的数据完整性规则_认识关系数据库的完整性规则

热门文章

  1. firewalld-富规则使用内容事项:
  2. 抛开百度、知乎等都找不到连接不上服务器远程桌面的原因
  3. iframe中嵌入报表
  4. 帆软决策报表全页面刷新或局部组件定时刷新
  5. c语言经典程序100例50行以上,C语言非常简单的字符统计程序50行
  6. bcoma 应用程序发生错误_Golang 错误和异常处理(含生产环境下的解决方案)
  7. 设置表格表头字体_Excel双栏和三栏斜线表头制作技巧
  8. 集成融云没有ipc进程的天坑
  9. Mongoose使用——nodejs结合mongodb
  10. 用aspectJ 做了一次日志