梦幻西游挖图脚本探讨(一)

时间:2024-02-21 07:48:04

序言:最近在学习图像视觉,基础不太好。也用在自己学程序语言时候的激情和方法尝试了一下。

最近 “梦幻西游” 挖图脚本的猖狂。可我关心的是他们挖图脚本的由来,以及验证自己最近的一些学习成果,尝试一下对挖图脚本制作。

主要涉及技术:

JAVA,PYTHON,OPENCV,OCR

(一)对场景图片中关于宝图店铺的识别,模拟鼠标点击

(场景)

1:分析步骤

1:JAVA调用JNI接口获取梦幻西游客户端窗口句柄(JNI 学习时间成本有点高,现阶段暂时指定位置)

         主要这一步是对我们实现截图进行定位。可以得到客户端的窗口在屏幕中的位置。可以实现对区域进行截图(后续针对每一个区,宝图店铺区域的不同,我们可以把对应坐标存在数据库中,达到通用性)。

  /**
     * 根据 游戏客户端 宝图店铺对应区域的一个截图
     * @param x 坐标
     * @param y
     * @param width 宽度
     * @param height 高度
     */
    public static BufferedImage getCreenshotsImage(int x, int y, int width, int height) {
        BufferedImage bfImage = null;
             try {
                 Robot robot = new Robot();
                bfImage = robot.createScreenCapture(new Rectangle(x, y, width, height));
             } catch (AWTException e) {
                e.printStackTrace();
            }
        return bfImage;
    }

 

 

2:得到店铺的宝图店铺大致所在的一个区域。对每个店铺中的文字进行识别

 

这里使用OPENCV 的的一些基础知识(也是我在这个阶段暂时遇到的最大一个坎,不过一切都好,总算努力不会白费)

PYTHON 代码(实现了图片中检索出所有店铺的区域位置)

#coding:utf-8

import sys

import os

sys.path.append([\'E:\\python3.6\\Lib\\site-packages\'])

#sys.path.append(\'E:\Opencv\pythonObject\')



 

import numpy as np

import cv2

import redis

import json

 

def baotuDianPu (uuid):

    #缓存读取JAVA  UUID值,对应UUID 从 REDIS中取得对应图片的数据

    db = redis.Redis(host=\'localhost\',port=6379,db=0,password=\'\',);

 

    imageUrl = db.get(uuid);

    imageUrl = str(imageUrl,encoding=\'utf-8\')

    if(imageUrl ==None):

        return;

    image = cv2.imread(imageUrl);

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY);

    # 双边滤波

    gray = cv2.bilateralFilter(src=gray, d=2, sigmaColor=100, sigmaSpace=13)

 

    gray = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)[1];

 

    # 开区间

    kernel = np.ones((3, 3), np.uint8)

    gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)

    # 自适应 阈值

    gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

 

    # 返回轮廓黑白

    gray = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_BINARY_INV)[1]

    # 开区间

    sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4));

    gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, sqKernel);

 

    # 计算轮廓  retr_external 只检测外轮廓,  CHAIN_APP...保存坐标点  返回参数refCnts 是轮廓

    refCnts, hierarchy = cv2.findContours(gray.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE);

 

    # 指定字典  一个坐标系, 一个 坐标远在返回轮廓坐标

    digitsTrain = []



 

    imas = image.copy();

    for (i, c) in enumerate(refCnts):

        # 计算 外接矩形resize合适的大小

        (x, y, w, h) = cv2.boundingRect(c);

        # 因为店铺的高度是固定的

        # if ((disX>2.5and  disX<4.5)):

        if ((h <= 19 and h >= 15 and w >= 20 and w <= 95)):

            #放进集合中 ,每四个一个

            digitsTrain.append((x, y - 1, w, h));

    strs = "";

    print(len(digitsTrain))

    if(len(digitsTrain)>0):

        strs = json.dumps(digitsTrain, indent=2, ensure_ascii=False)

        db.set(uuid,strs);

    db.close()

    #存进REDIS

 

if __name__ == \'__main__\':

    for i in range(1, len(sys.argv)):

        uuid = sys.argv[i];

        baotuDianPu(uuid)

 

上面已经得到该该图片 能找出所有的的店铺的位置

主要我对PYTHON 还不太熟悉,为了节约时间成本,我选着了用JAVA调用PYTHON 的方式拿值,中间用redis做数据交换存储.

JAVA 调用代码:(JAVA 调PYTHON 的时候,有坑。用不了第三方包,主要原因自己在pycharm里面是有编译环境的,而独立出来的python 里面没有编译环境,在PY文件头上记得要加上包的路径,我是这样理解的)
    public static void main(String[] args) throws InterruptedException {
        
        String uuid = UUID.randomUUID().toString();
        
        //CMD 执行PYTHON 所在路径(这一步有很多坑,主要设置自己的环境== 要不然你得不到运行时候,会调用不了第三方包)
        String[] param = new String[] {"E:\\python3.6\\python.exe","E:/Opencv/pythonObject/baotuDianPu.py",uuid};
        
        String imageUrl = "D:/Users/admin/Desktop/test/test1.png";
        
        Jedis jedis = RedisUtils.getJedis();
        jedis.set(uuid,imageUrl);
        //执行脚本
        try {
            Process proc = Runtime.getRuntime().exec(param);
        } catch (IOException e) {
            e.printStackTrace();
        }    
        //线程听两秒
        Thread.sleep(2000);
        String list = jedis.get(uuid);
        System.out.println(list);
        RedisUtils.returnResource(jedis);
    }

3:进行 宝图店铺的检测

这里我尝试了很多方法,由于自己的技术有限。知识面还不够广,对文字的识别还是有点困难。

这是我第一次尝试用在识别的时候直接逐字判断包含有宝图 TT 图 等字样的图片出来,效果不太理想,我只想要有 "ttt" ,"图","TT"类似的店铺, 什么鬼都给我识别出来了。哈哈

机器学习的 svm 识别的差别还是差不多。为了不停止下来,我尝试了一些OCR接口与工具,百度,阿里==接口(好贵)。自己做tess4jOCR的话(效果貌似也不太行).

最后借助一个OCR的工具:

能有比较高效率的识别对应中的文字。因为上面,我已经得到了 所有店铺的所有区域位置的LIST。那么如果想对该区域文字的识别,只要用JAVA控制鼠标操作 就可以实现文字的提取。后续进行对文字保存然后在txt的读取。就能判断该店铺是否是宝图店铺。进行截图。我在虚拟机里面做了简易的WEB后台,只提供接口 ,把OCR工具放进了虚拟机进行操作。这样我本地的鼠标操作就直接省去了。

 

4:根据这个得到该宝图店铺的位置,就可以干嘛了?大家都应该知道了。

下面也就是重复的动作,

1:控制点击店铺。判断是否有宝图。价格几何?

2:检测自己背包是否满了。

3:........

后续 .....敬请期待

 

一边学习,而且对自己喜欢的游戏进行学习,那种兴趣  哈哈 。。欢迎探讨一下。。。