OPENCV對遊戲腳本的技術探討(夢幻西遊) 一

序言:最近在學習圖像視覺,基礎不太好。也用在自己學程序語言時候的激情和方法嘗試了一下。

最近 “夢幻西遊” 挖圖腳本的猖狂。可我關心的是他們挖圖腳本的由來,以及驗證自己最近的一些學習成果,嘗試一下對挖圖腳本製作。

主要涉及技術:

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:........

後續 .....敬請期待

 

一邊學習,而且對自己喜歡的遊戲進行學習,那種興趣  哈哈 。。歡迎探討一下。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章