PTT推薦

[聊天] 接龍小遊戲 自動查表器

看板PCReDive標題[聊天] 接龍小遊戲 自動查表器作者
gR7P4zXH
(tpn7gpdx)
時間推噓64 推:66 噓:2 →:8

覺得小遊戲查表好麻煩,做了一個查表器

附上人權
http://i.imgur.com/vzuo7ru.jpg

圖 接龍小遊戲 自動查表器

# 實驗成果
v1
https://youtu.be/IcirpEYB2lY

v2,感謝小精靈改scrcpy
https://youtu.be/Nb9cCh4DmgY

# source code
aHR0cHM6Ly9wYXN0ZWJpbi5jb20vajhNY3F4RGE=

# 實驗環境
- Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
- 12G RAM
- MX500 SSD
- Ubuntu 19.10

# 辨識九宮格圖示
OpenCV提供大量函式,為此我們使用了 `matchTemplate` 辨識圖示,整體流程如下
1. 切割原始圖片成單張圖示(icon),大小為106x106px
2. 調整大小至78x78px
3. 用 `matchTemplate` 比對148張既有圖示,排序 `min_val`,找出最大值所對應的圖示和ID
![](https://i.imgur.com/tATMR9t.png)

得益於Profiling工具的日新月異,我用cProfile分析單執行緒的 python script,發現最耗時的地方位於`templateMatching`,足足佔了整體執行時間97%‧

```bash
~$ python3 -m cProfile -s tottime ./tmp.py
0.7606322765350342
325680 function calls (318751 primitive calls) in 1.289 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
1287 0.741 0.001 0.741 0.001 {matchTemplate}
28/17 0.162 0.006 0.240 0.014 {built-in method
_imp.create_dynamic}
280 0.045 0.000 0.045 0.000 {built-in method marshal.loads} 2 0.041 0.020 0.041 0.020 {imread}
```

### 全彩轉灰階
試著將全彩圖示轉換成灰階再進行比對
```bash
~$ python3 -m cProfile -s tottime ./tmp.py
0.2725179195404053
326034 function calls (319105 primitive calls) in 0.811 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
1287 0.256 0.000 0.256 0.000 {matchTemplate}
```
看的出 maximum overhead 還是在`templateMatch`,但總執行時間足足少了65%‧

### 縮小圖示再比對
將兩邊要比對的78x78px縮小至26x26px,於是`matchTemplate`讓出寶座,整體執行時間更是來到 0.05s(-80%),圖示辨識率也還是維持100%。
```
0.05796694755554199
326071 function calls (319142 primitive calls) in 0.613 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
28/17 0.153 0.005 0.234 0.014 {built-in method
_imp.create_dynamic}
280 0.046 0.000 0.046 0.000 {built-in method marshal.loads} 2 0.043 0.022 0.043 0.022 {imread}
1287 0.042 0.000 0.042 0.000 {matchTemplate}
1175/1120 0.021 0.000 0.073 0.000 {built-in method
builtins.__build_class__}
```
為了減少執行時間,我們也測試圖片大小和辨識準確率關係,程式有做一些改動(印出正確率、存測試資料),下方數據只是作為 Image size 的選取依據並非實際執行時間。測試腳本如下
```bash
for i in `seq 78 -2 1`;do icon_size=$i python3 tmp.py; done;
```
只用一張遊戲畫面圖片做測試
icon size | elapsed time (sec)| accurate rate %)
---|---|---
78x78|0.2452|100.0
26x26|0.0758|100.0
24x24|0.0447|100.0
22x22|0.0434|100.0
20x20|0.0390|100.0
18x18|0.0389|88.9
16x16|0.0339|77.8
14x14|0.0473|77.8
12x12|0.0277|66.7
10x10|0.0295|77.8
8x8|0.0248|55.6
6x6|0.0234|55.6
4x4|0.0221|11.1
2x2|0.0210|11.1

看來極限能到20x20px,取20x20的耗時較26x26減少30%


26x26
```
0.0584
326155 function calls (319226 primitive calls) in 0.573 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
28/17 0.144 0.005 0.221 0.013 {built-in method
_imp.create_dynamic}
280 0.045 0.000 0.045 0.000 {built-in method marshal.loads} 1287 0.043 0.000 0.043 0.000 {matchTemplate}
```

20x20
```
0.0406
326057 function calls (319128 primitive calls) in 0.628 seconds

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
28/17 0.158 0.006 0.242 0.014 {built-in method
_imp.create_dynamic}
280 0.050 0.000 0.050 0.000 {built-in method marshal.loads} 2 0.043 0.021 0.043 0.021 {imread}
1287 0.025 0.000 0.025 0.000 {matchTemplate}
```
不知道為什麼行的通...但是算了
![](https://i.imgur.com/KCjfbQS.png)

### 使用python的sorted
Python的`sorted`使用名為Timsort的混合式排序演算法,使用`sorted`減少了0.0006秒的執行時間
```
0.0385->0.0379
```
```python=
# Before
def findIconId(img):
id = None
result = -1
for icon in icons.values():
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
if (result < min_val):
result = min_val
id = icon.id
return id

# After
def findIconId(img):
arr=[]
for icon in icons.values():
res = cv.matchTemplate(resized,icon.img,cv.TM_CCOEFF)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
arr.append((min_val, icon.id))
arr = sorted(arr, key= lambda x: x[0],reverse=True)
return arr[0][1]
```
### Multithreading
最後手段,但用了反而增加時間,不予採用。
`0.0373->0.0494 secs`

你知道 python 的 multithreading 跟你想像的不一樣嗎?
:::success
"_Each thread that wants to run must wait for the GIL to be released by the
other thread, which means your multi-threaded Python application is actually
single threaded._"

https://medium.com/practo-engineering/threading-vs-multiprocessing-in-python-7b57f224eadb
:::
![](https://i.imgur.com/ePnGiZC.png)

### 保險機制
遊戲中的過場畫面可不能拿來辨識,因此次要設計用一套方法來判斷何時該開始辨識
1. 用像素點顏色判斷白邊存在
2. 偵測白色反光,取圖示中心的點做判斷

兩項測試都通過後才會進行template matching
**valid**
> ![](https://i.imgur.com/xiSrrvv.jpg)
>
>**invalid**
> ![](https://i.imgur.com/73aqDUW.jpg)
> ![](https://i.imgur.com/u4Te7oH.jpg)
> ![](https://i.imgur.com/5e6IJ6V.jpg)
> ![](https://i.imgur.com/7PNnNHy.jpg)
> ![](https://i.imgur.com/Iwmn5de.jpg)
> ![](https://i.imgur.com/GgCjvoC.jpg)


### 辨識韻母
韻母只有一張圖要和38張圖比對,尺寸小,耗時短,不在此多著墨。

# 選取演算法
這部份沒什麼特別,目標就是最高分的圖示。以滿圖鑑為目標?不會多點幾次?


--

※ PTT留言評論
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.248.3.243 (臺灣)
PTT 網址
※ 編輯: gR7P4zXH (118.161.105.58 臺灣), 03/08/2020 08:52:43

KParmy03/08 08:52看不懂你在幹嘛 但好像很厲害 推一下

ikaros3503/08 08:53我做研究都沒那麼認真 跪了

adamacon03/08 08:56你的指導教授知道你在作這種東西嗎?

跑實驗閒暇時做的

qni110403/08 09:07這技術用在遊戲上,我只能跪了謝謝大大造福群眾

Jongkook03/08 09:09三小= =

r2274255703/08 09:10不好意思請教一下,你在辨識九宮格圖示部分,是使用螢

講完R

shaodw79101703/08 09:11?

CYL00903/08 09:11我今天流量夠了 該睡覺了

askye54638803/08 09:11看起來很厲害的樣子

KMSNY03/08 09:15很好 明天來上班

amsterdamDK03/08 09:21三小。。

aha887703/08 09:41先推,免得其他人以為我看不懂

honey461791203/08 09:48嗯嗯我也是這麼想的

x8s8x8s8x03/08 09:57偶先推

dajon03/08 10:02所以是螢幕辨識+按鍵精靈嗎

沒有按鍵精靈

sakuravivio03/08 10:03先推,裝懂

Incredible9903/08 10:03看不懂你在幹嘛 不過你之後要去so-net?

比較想去.net折衣服

crazycy03/08 10:09這不就外掛...

我自己手動點,不算外掛喔

Tiamat671603/08 10:09科技的力量

felixden03/08 10:12看不懂

Tamama5603/08 10:13先推

otakuxavier03/08 10:17請問可以把py檔放github嗎 想clone下來好好研究一下

糞扣公開傷眼

mifire03/08 10:17sonet:你要來我這裡報到了嗎

zodhk0105403/08 10:23不懂,先推再說

Terry198403/08 10:24太神啦

pionlang556603/08 10:29有沒有打算放在 github 開源

a89032403/08 10:31哇靠 文組看不懂啊

pionlang556603/08 10:33用 numba 會比較快嗎 <-出張嘴

loltrg4297203/08 10:33科技始終來自人性

rhythm732103/08 10:44推 如果能找想要的押韻就更猛了

請開spec

sweetmiki03/08 10:45我覺得你在做壞事 但我看不懂

smart0eddie03/08 10:53姆咪

shinobunodok03/08 11:01現在打電動都要這麼硬派寫實喔

wsttuub03/08 11:13.......看不懂但先跪再說

dend93003703/08 11:17你的指導教授知道這件事嗎

這是在家搞的

gsfate03/08 11:17這算外掛嗎XD

nutta03/08 11:20先推免得

qwert6573203/08 11:26上次是連點這次是小遊戲腳本 某人要高潮了嗎

泳犬小遊戲?

roc07403/08 11:28這跟去so-net沒一點關係,原po應該會去做影像辨識的公司吧

影像公司泊車小弟

bomda03/08 11:38這就是外掛啊

paul3178803/08 11:42

CVTaihouKai03/08 11:44第1行不就是寫查表器了

ptgeorge203/08 12:11我只是想打手槍,你給我看這個= =

frosagen201803/08 12:18我也是這麼想的

DanielHAO03/08 12:18跟我想得差不多

x8030703/08 12:23窩不知道 你再說蛇某

bightp3693603/08 12:44現在玩公連這麼硬的嗎

enders34603/08 12:47太強啦

kingoflag03/08 13:04我需要git網址 為了研究

怎麼這麼多人知道git

js85060403/08 13:10玩公連先學影像辨識

不用學,這沒用到理論

abjeffop03/08 13:17嗯嗯 跟我當初想的一樣 謝謝付諸行動

he0102381503/08 13:20嗯嗯跟我想的差不多

sismiku03/08 13:29IOTA凸了木有

sismiku03/08 13:29發錢辣

凸了墓

joe121103/08 14:02這山小...

littlestar6603/08 14:16嗯嗯 跟我當初想的一樣

powerkshs03/08 14:25你的got hub勒

mikeneko03/08 14:31講中文可以嗎

都蕊咪發搜

ruler7681803/08 15:09python。ai辨識

Raynor03/08 15:25source code 呢? (敲碗

站內信

NoLimination03/08 15:48說人話

duncan131503/08 16:13請問有哪些教授有在做upscale的嗎?滿有興趣的

大佬跑錯板了

zax5566x203/08 16:15請問paper哪裡可以找到

dkchronos03/08 17:03我需要網址,為了研究用途。

asteea03/08 17:14...我竟然看的懂 推有心去寫 又有心分享成果

lionel2000203/08 17:43scale前可以把邊界剪掉 外面那一圈白框對辨識沒幫助

感謝建議,但已達到可用標準,懶得再改

mose5678903/08 17:47瑟瑟發抖

taikobo03/08 18:17有看有推

b94031503/08 19:17感覺會被當外掛 還好我打玩了

to952703/09 00:03求github XD

KaiKaiGod03/09 00:35私!

※ 編輯: gR7P4zXH (111.248.3.243 臺灣), 03/09/2020 03:20:04 ※ 編輯: gR7P4zXH (111.248.3.243 臺灣), 03/09/2020 03:30:37 ※ 編輯: gR7P4zXH (111.248.3.243 臺灣), 03/09/2020 03:57:56 ※ 編輯: gR7P4zXH (1.171.87.231 臺灣), 03/09/2020 04:49:11

y12442147303/09 07:58你贏了...

MiRRorX03/09 08:41果然等著就有神人,太猛了,求站內codeXD

kevin80111703/10 08:54太神拉 要是我會還是懶得做

stocking003/10 11:07電腦白痴的我 連怎樣弄和用都不知道

eric91000503/10 21:23傻眼