1. 程式人生 > >利用人工智慧實現小程式自動答題

利用人工智慧實現小程式自動答題

 作者:Yiutto,程式設計浪子

 GitHub:github.com/Yiutto

之前有看到有人用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的相關引數。

  1. # 從PC端截圖時,擷取區域左上角相對桌面的x座標

  2. 'projection_x': 32,

  3. # 從PC端截圖時,擷取區域左上角相對桌面的y座標

  4. 'projection_y': 278,

  5. # 從PC端截圖時,擷取區域的寬度

  6. 'projection_width': 482,

  7. # 從PC端截圖時,擷取區域的高度

  8. 'projection_height': 854,

可以用window命令鍵 PrtScSysRq(F12的右邊),然後複製到畫圖中(1920x1080)。640?wx_fmt=png

用畫圖的放大鏡放大,圖中紅色框的小方塊位置(32x278) projection_x即32, projection_y即278。

640?wx_fmt=png

在畫圖中計算出截圖的寬度和高度,即 projection_width和 projection_height(482x854) 

640?wx_fmt=png

2. img_tool.py函式介紹:主要是通過 all(img,filename)函式進行圖片分割

  1. srcImg = cv2.imread(os.path.join(

    "ScreenShotForTrain", f), 0)

上述程式碼是為了將彩色圖片灰度模式載入

640?wx_fmt=png

  1. def all(img, filename):

  2. """封裝對圖片的所有操作"""

  3.    img = cropImg(img)

  4.    img = binaryImg(img)

  5.    img1, img2 = cropAgain(img)

  6.    imgs = cutImg(img1, filename + '_1') + cutImg(img2, filename + '_2')

  7. return imgs

  8. def cropImg(img):

  9. """裁剪原始截圖"""

  10.    height = img.shape[0]

  11.    img2 = img[int(config.config['exp_area_top_rate'] * height):int(config.config['exp_area_bottom_rate'] * height),:]

  12. #print('裁剪完畢')

  13. return  img2

cropImg(img)函式主要是為了裁剪含有數字的區域,通過設定引數

  1. #表示式區域的頂部處於整張圖片的位置(307/854=0.359)

  2. 'exp_area_top_rate': 0.36,

  3. #表示式區域的底部處於整張圖片的位置(478/854=0.559)

  4. 'exp_area_bottom_rate': 0.56,

如果覺得設定比例太麻煩,可以直接寫死位置( img2=img[int(307):int(478),:])。得到如下圖:

640?wx_fmt=png

  1. def binaryImg(img):

  2. """二值化圖片"""

  3.    ret, thresh1 = cv2.threshold(img, config.config['binary_threshold'], 255, cv2.THRESH_BINARY)

  4. # ret, thresh1 = cv2.threshold(img, config.config['binary_threshold'], 255, cv2.THRESH_BINARY_INV)

  5. #print('二值化完畢')

  6. return thresh1

binaryImg(img)函式主要是為了將圖片二值化,可以參考 Python+OpenCV教程6:閾值分割。得到的圖片如下圖:

640?wx_fmt=png

  1. def cropAgain(img):

  2. """再次裁剪"""

  3.    height = img.shape[0]

  4.    img1 = img[0:int(0.5 * height), :]

  5.    img2 = img[int(0.5 * height):height, :]

  6. #print('再次裁剪完畢')

  7. return img1, img2

cropAgain(img)函式主要是為了將圖片分成上下兩部分

640?wx_fmt=png 640?wx_fmt=png

  1. def cutImg(img, filename):

  2. """水平分割圖片"""

  3.    sb = np.array(img)

  4. print(sb.shape)

  5.    sum_list = np.array(img).sum(axis=0)

  6.    start_index = -1

  7.    res = []

  8.    names = []

  9.    index = 0

  10. for sum in sum_list:

  11. if sum > 255 * 4:

  12. if start_index == -1:

  13.                start_index = index

  14. else:

  15. if start_index != -1:

  16. if config.config['type'] == 0:

  17.                    sigleCharWidth = config.config['abd_single_char_width']

  18. else:

  19.                    sigleCharWidth = config.config['pc_single_char_width']

  20. #為了防止字元粘連,需要在此處寬度進行判斷

  21. if index - start_index > sigleCharWidth * 2:

  22.                    res.append((start_index,start_index + (index - start_index) // 2))

  23.                    res.append((start_index + (index - start_index) // 2, index))

  24. else:

  25.                    res.append((start_index, index))

  26.                start_index = -1

  27.        index += 1

  28.    imgs = []

  29.    count = 0

  30. for single_char in res:

  31.        start = single_char[0]

  32. end = single_char[1]

  33.        sub_img = img[:, start:end]

  34.        sub_img = cv2.resize(sub_img, (120, 240), interpolation=cv2.INTER_CUBIC)

  35. #cv2.imwrite('SingleChar/%s_%d.png' % (filename, count), sub_img)

  36. #names.append('%s_%d.png' % (filename, count))

  37. # cv2.imshow(str(count), sub_img)

  38.        imgs.append(sub_img)

  39.        count += 1

  40. # cv2.waitKey()

  41. #print('分割,重新設定大小 %s 完畢' %filename)

  42. return  imgs

設定 pc_single_char_width引數值,得到如下圖:

640?wx_fmt=png

  1. c = 0

  2. def v_cut(img):

  3. global c

  4. """豎直方向切割圖片"""

  5.    sb1 = np.array(img)

  6. print(sb1.shape)

  7.    sum_list = np.array(img).sum(axis=1)

  8.    start_index = -1

  9. end = -1

  10.    index = 0

  11. for sum in sum_list:

  12. if sum > 255 * 2:

  13.            start_index = index

  14. break

  15.        index += 1

  16. for i in range(1, len(sum_list) + 1):

  17. if sum_list[-i] > 255 * 2:

  18. end = len(sum_list) + 1 - i

  19. break

  20.    img = img[start_index:end, :]

  21.    img = cv2.resize(img, (30, 60), interpolation=cv2.INTER_CUBIC)

  22. #cv2.imwrite('SingleChar/%d.png' %c, img)

  23.    c += 1

  24. return img

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

640?wx_fmt=png 640?wx_fmt=png 640?wx_fmt=png 640?wx_fmt=png 640?wx_fmt=png

640?wx_fmt=png 640?wx_fmt=png 640?wx_fmt=png

二、訓練模型,建立LR分類器

相關程式碼請看 ml.py,這裡不過多介紹,直接利用python包 fromsklearn.linear_modelimportLogisticRegression

  1. LogisticRegression(class_weight='balanced')

sklearn邏輯迴歸(Logistic Regression,LR)類庫使用小結

三、自動答題模式開啟

實現原理

    相關推薦

    程式自動登入實現

    微信小程式之登入 第一步:獲取登入態code 微信登入部分,首先需要使用微信小程式的api—— wx.login(OBJECT)來獲取登入態 這個登入態的作用是為了獲取使用者的openid(使用者的唯一標識); 官方示例 js部分: //呼叫登入

    利用Python實現的一個自動群發或單發郵件的小腳本!(SMTP協議)

    成功 負責 mail 發現 腳本 服務器 編碼 SM 比較 python3、利用SMTP實現自動發送郵件!   首先聲明,這個是偶然從別人的博客裏發現的,覺得比較有趣,就自身親自嘗試了一番,在此做了點兒比較詳細的整理和一點點小小的優化!此處為原博客的鏈接地址!   http

    java實現程式獲取二維碼(介面B)

    應用場景: 實際應用場景:比如分享助力、名片分享之類的頁面需要生成二維碼 為滿足不同需求和場景,小程式提供了三個介面,開發者可挑選適合自己的介面 介面A:適用於需要的碼數量較少的業務場景 生成小程式碼,可接受 path 引數較長,生成個數受限,數量限制見 下面注意

    微信程式自動更新

    微信小程式專案釋出上線後,如何進行自動更新版本呢? 在主頁面載入的onload加入以下程式碼: //檢查是否存在新版本 wx.getUpdateManager().onCheckForUpdate(function (res) { // 請求完新版本資訊的回撥

    利用微信程式遊戲)API製作適配cocos creator遊戲排行榜的例項程式

    cocos creator 可以通過新建一個creator專案進行新增子域專案,但是有一個缺點就是佔用檔案大小是一個問題,所以我這裡採用微信的API進行繪製排行榜, 主域就是各種傳送給子域的訊息,這裡不再這裡贅述,就是各種呼叫微信的API 這裡給出微信的API 微信開放資料域 新建m

    3分鐘實現程式喚起微信支付 Laravel教程

    微信支付的接入,如果不使用成熟的開發包,將是巨大的工作量。 依賴 EasyWechat 先在 laravel 專案中依賴 easywechat 這個包 composer require "overtrue/laravel-wechat":"^4.0" 配置 在 .env 中新增微信支付的 key 配置

    樹莓派上實現python程式自動殺死程序

    首先,殺死程序的主要命令為ps,grep,kill這三個指令。 1、第一步是獲取要監控程序的pid號: def get_process_pid(name):     child = os.popen("ps -ef | grep "+name).readline() &n

    程式自動修復程式碼規範

    1。package.json:修改下面一行程式碼: { "name": "mpvue-demo", "version": "1.0.0", "description": "A Mpvue project", "author": "", "private": true,

    30分鐘實現程式語音識別

    前言 為了參加某個作秀活動,研究了一波如何結合小程式、科大訊飛實現語音錄入、識別的實現。科大訊飛開發文件中只給出 Python 的 demo,並沒有給出 node.js 的 sdk,但問題不大。本文將從小程式相關程式碼到最後對接科大訊飛 api 過程,一步步介紹,半個小時,搭建完成小程式語音識別功能!不能再

    樹莓派上利用Tensorflow實現小車的自動駕駛

    先丟擲大家最關心的——程式碼地址: github傳送門:https://github.com/Timthony/self_drive 碼雲傳送門:https://gitee.com/tiantianhang/self_drive 基於樹莓派的人工智慧自動駕駛小車 # 整體流程 電機控

    程式訊息推送(含原始碼)java實現程式推送,springboot實現微信訊息推送

    最近需要開發微信和小程式的推送功能,需要用java後臺實現推送,自己本身java和小程式都做,所以就自己動手實現下小程式的模版推送功能推送。 實現思路 1 小程式獲取使用者openid,收集formid傳給java後臺 2 java推送訊息給指定小程式使用

    實現程式中的自定義元件

    具體實現 要做自定義元件,我們先定一個小目標,比如說我們在小程式中實現一下 WEUI 中的彈窗元件,基本效果圖如下。 Step1 我們初始化一個小程式(本示例基礎版本庫為 1.7 ),刪掉裡面的示例程式碼,並新建一個 components 資料夾,用於存放我們以後開

    利用Redis實現應用程式主備

    需要實現主備的每個任務都先進行爭奪主機,通過爭奪redis中的key值。Rredis需要搭建主備高可用。 搶到key值的程式為主機,可以開始任務,備機執行緒開始等待,過段時間再進行爭奪主機。一般情況下首先搶到key值的主機會一直執行任務直到主機異常,程式崩潰等錯誤發生時,備

    微信程式自動定位,通過百度地圖根據經緯度獲取該地點所在城市資訊

    微信小程式獲得經緯度 var that = this wx.getLocation({ type: 'wgs84', success(res) { console.log(res) that.setData({

    mpvue實現程式購物車左滑刪除功能

    大家先看看效果 使用了iview的效果   上面的效果用到了 iView Weapp,點選進入官方文件 現在開始介紹如何在微信小程式中使用iView Weapp 到GitHub下載 iView Weapp

    程式自動生成圖片的標籤

    <view class="name" wx:for="{{array}}" wx:key="index"> <image style="transform:translate({{item.offsetX}}px, {{item.offsetY}}px) ;" class=

    Laravel實現程式使用openid登陸、手機號驗證碼登陸、賬戶密碼登陸三種登陸方式

    目前開發小程式,按需求要實現3種登陸方式: 1、微信授權登陸 2、賬戶密碼登陸 3、手機號、驗證碼登陸 我使用laravel自帶的Auth認證機制,通過attempt方法進行賬戶驗證,但是預設的認證機制必須包含password欄位,而我的第1、3種登陸方式都沒有

    如何實現程式使用者和公眾號使用者多點登入

    需求: 1.現在有一批公眾號使用者,後期又開發了小程式,那如何讓小程式識別到這是來自公眾號的使用者呢? 2.直接使用小程式的使用者實現快速登入? 這是一個很常見的需求場景,要實現小程式和公眾號使用者多點登入就需要任意一方儲存好使用者的unionId,在實現該需求的過

    如何實現程式的無限推送

    文章有點標題黨,單純的從技術上來實現無限推送暫時是不可能的。 為什麼不可能? "推送" 在小程式官方的叫法是模板訊息。先來看看官方對他的下發條件說明: 1. 支付 當用戶在小程式內完成過支付行為,可允許開發者向用戶在7天內推送有限條數的模板訊息(1次支付可下發3條,