OpenCV玩微信小游戏星途WeGoing

游戏模式

这是一个2D插画风格的益智游戏,玩家可以点击屏幕控制控制飞船在星球间飞跃,刚开始控制不好可能会撞上星球。

OpenCV玩微信小游戏星途WeGoing_第1张图片

工具介绍

  • Python 3.5
  • Android 手机
  • Adb 驱动

原理说明

通过OpenCV里的cv2.HoughCircles()函数识别星球,通过像素颜色识别飞船,在飞船运行到两个星球间时点击屏幕。

程序源码

import cv2
import numpy as np
import os


def findplanetcircle(planet):
    gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
    img = cv2.medianBlur(gray_img, 5)
    # cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 120,
                               param1=100, param2=50, minRadius=60)

    for i in circles[0, :]:
        # draw the outer circle
        cv2.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2)
        # draw the center of the circle
        cv2.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3)
    return circles


def findship(planets):
    (height, width, _) = planets.shape
    for h in range(0, height, 5):
        for w in range(1, width, 5):
            (B, G, R) = planets[h][w]
            if 110 < B < 125 and 80 < G < 90 and 15 < R < 25:
                # cv2.circle(图片, (w, h), 半径, (255, 255, 255), thickness)
                cv2.circle(planets, (w, h), 2, (255, 255, 255), 3)
                return w, h


def computedist(point1, point2):
    return np.sqrt(np.square(point1[0] - point2[0]) + np.square(point1[1] - point2[1]))


i = 1
while True:
    i = i + 1
    os.system('adb shell screencap -p /sdcard/autojump.png')
    os.system('adb pull /sdcard/autojump.png test/' + str(i) + '.png')
    planets = cv2.imread('test/' + str(i) + '.png')

    circles = findplanetcircle(planets)
    w, h = findship(planets)
    cv2.imwrite("test/" + str(i) + "circles.jpg", planets)

    ind = np.argsort(-circles[0][:, 1])
    circles = circles[0][ind]
    indexlist = []
    for index, item in enumerate(circles):
        widthcircle, heightcircle, radius = item
        # 判断目前在哪儿个星球,去掉当前星球
        if np.abs(computedist(item, (w, h)) - radius) < 35:
            indexlist.append(index)
        # 判断哪儿个星球已经走过,并且去掉
        elif heightcircle > h:
            indexlist.append(index)
    planetsNum = [i for i in range(circles.shape[0])]
    futurePlanet = list(set(planetsNum).difference(set(indexlist)))
    circles = circles[futurePlanet]
    for index, item in enumerate(circles):
        widthcircle, heightcircle, radius = item
        print(np.abs(computedist(item, (w, h)) - radius))
        if 60 < np.abs(computedist(item, (w, h)) - radius) < 150:
            print("正在点击")
            os.system('adb shell input swipe 525 1650 527 1654 2')
            cv2.imwrite("test/jump" + str(i) + ".jpg", planets)

实验结果

下图是飞船和星球识别标注后的图片。

OpenCV玩微信小游戏星途WeGoing_第2张图片

OpenCV玩微信小游戏星途WeGoing_第3张图片

TODO

图像识别功能已经完成,可是ADB截图再传送到电脑有一定时间,所以点击的时候,飞船已经飞了大半圈了,所以还需要完善,做到实时画面传送。

你可能感兴趣的:(OpenCV)