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

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

主要涉及技术:

JAVA,PYTHON,OPENCV,OCR

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

(场景)

梦幻西游脚本 lua与python 梦幻西游脚本原理_JAVA

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:得到店铺的宝图店铺大致所在的一个区域。对每个店铺中的文字进行识别

 

梦幻西游脚本 lua与python 梦幻西游脚本原理_机器学习_02

这里使用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"类似的店铺, 什么鬼都给我识别出来了。哈哈

梦幻西游脚本 lua与python 梦幻西游脚本原理_梦幻西游脚本 lua与python_03

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

最后借助一个OCR的工具:

梦幻西游脚本 lua与python 梦幻西游脚本原理_java_04

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

 

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

下面也就是重复的动作,

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

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

3:........