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

之前有看到微信小程序《跳一跳》别人用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 imgs

def 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 = -1
    res = []
    names = []
    index = 0
    for sum in sum_list:
        if sum > 255 * 4:
            if start_index == -1:
                start_index = index
        else:
            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 = -1
        index += 1

    imgs = []
    count = 0
    for 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 = -1
    end = -1
    index = 0
    for sum in sum_list:
        if sum > 255 * 2:
            start_index = index
            break
        index += 1
    for i in range(1, len(sum_list) + 1):
        if sum_list[-i] > 255 * 2:
            end = len(sum_list) + 1 - i
            break
    img = img[start_index:end, :]
    img = cv2.resize(img, (30, 60), interpolation=cv2.INTER_CUBIC)
    #cv2.imwrite('SingleChar/%d.png' %c, img)
    c += 1
    return 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):
    # 可以控制到这一关gg
    if (count == 455):
        time.sleep(3)

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

四、源代码地址

记得给哥们的github打?啊

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

有问题私聊我[email protected]

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

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

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

原文地址:https://www.cnblogs.com/Yiutto/p/9440397.html

时间: 2024-08-04 12:39:30

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

微信小程序 加载图片时,先拉长,再恢复正常

今天在写小程序,发现小程序的图片image如过mode设置为widthFix的话, 加载图片会被先拉伸,后恢复正常 我的处理方法是,给他一个初始的height值,或者就直接 height:auto 原文地址:https://www.cnblogs.com/bing0709/p/10729449.html

微信小程序发布新版本时自动提示用户更新

如图,当小程序发布新的版本后,用户如果之前访问过该小程序,通过已打开的小程序进入(未手动删除),则会弹出这个提示,提醒用户更新新的版本.用户点击确定就可以自动重启更新,点击取消则关闭弹窗,不再更新. 官方给的示例代码: const updateManager = wx.getUpdateManager() updateManager.onCheckForUpdate(function (res) { // 请求完新版本信息的回调 console.log(res.hasUpdate) }) upd

微信小程序------加导航

效果图如下 这个其实很简单 在app.json上面加点代码 "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#OOOOOO", "navigationBarTitleText": "WeChat", "navigationBarTextStyle"

微信小程序学习指南

作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 微信小程序正式公测, 张小龙全面阐述小程序,定档1月9日上线(附90分钟演讲全文) ... 前言:新人第一坑,跳坑指南:修改后,必须保存:ctrl+S: 1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教

官方问答--微信小程序常见FAQ (17.8.21-17.8.27)

给提问的开发者的建议:提问之前先查询 文档.通过社区右上角搜索搜索已经存在的问题. 写一个简明扼要的标题,并且正文描述清楚你的问题. 提交 BUG:需要带上基础库版本号,设备信息(iOS, Android,开发工具等等),操作系统信息(系统版本),以及可以让他人重现的信息,最好能够提供重现 demo. 对于提供信息过少的问题,会直接关闭,请提供完整信息以后重新打开问题.另外,对于如何做某某功能,可否做某某功能的问题,会直接关闭. 微信小程序常见FAQ(17.8.21-17.8.27) Q:1.5

WordPress版微信小程序2.1.5版发布

WordPress版微信小程序功能已经基本完善,利用这套程序,搭配WordPress提供的rest api,WordPress网站的站长可以快速搭建属于自己的网站微信小程序 . WordPress版微信小程序开放源码地址:https://github.com/iamxjb/winxin-app-watch-life.net 如果你对小程序还不了解,可以先去看看我以前写的wordpress版微信小程序的系列文章: 1.用微信小程序连接WordPress网站2.WordPress版微信小程序1.5版

微信小程序-整理各种小程序源码和资料免费下载

微信小程序整理下载 [小程序源码]微信小程序-车源宝微信版 [小程序源码]小程序-微赞社区(论坛demo) [小程序源码]微信小程序-收支账单 [小程序工具]微信小程序-日历 [小程序源码]小程序-在线聊天功能 [小程序源码]微信小程序-大好商城(新增功能天气查询和2048游戏) [小程序源码]微信小程序-查询号码归属地 [小程序源码]微信小程序-备忘录2 [小程序源码]微信小程序-QQ音乐 [小程序源码]小程序-货币汇率 [小程序源码]微信小程序-大学图书馆 [小程序源码]小程序-积分商城 [

微信小程序image组件开发程序以及相关图片问题参考资料汇总

微信小程序image组件开发程序以及相关图片问题参考资料汇总,希望对大家小程序开发能有一定的参考和借鉴价值.以下汇总主要涉及到微信小程序image组件有关资源路径.缩放和剪裁模式等进行的探讨,无论是对微信小程序新手还是正在开发中的朋友都是很好的小程序学习资料. 微信小程序image组件必备基础知识: image组件默认宽度300px.高度225px image的属性mode有13种模式,其中4种是缩放模式,9种是裁剪模式 image组件开发教程汇总: 微信小程序自定义组件实现图片单指拖动.双指缩

原生微信小程序脚手架(支持npm)

微信小程序支持npm 为了支持生态扩展,社区贡献者可以提供更加丰富的功能,已经支持了第三方小程序开发功能,见如下地址. 微信小程序支持npm https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html 从小程序基础库版本 2.2.1 或以上.及开发者工具 1.02.1808300 或以上开始,小程序支持使用 npm 安装第三方包. 此文档要求开发者们对 npm 有一定的了解,因此不会再去介绍 npm 的基本功能.如若之前未