[聊天] 接龍小遊戲 python半自動
覺得小遊戲查表好麻煩,做了一個查表器
附上人權
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

得益於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}
```
不知道為什麼行的通...但是算了

### 使用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
:::

### 保險機制
遊戲中的過場畫面可不能拿來辨識,因此次要設計用一套方法來判斷何時該開始辨識
1. 用像素點顏色判斷白邊存在
2. 偵測白色反光,取圖示中心的點做判斷
兩項測試都通過後才會進行template matching
**valid**
> 
>
>**invalid**
> 
> 
> 
> 
> 
> 
### 辨識韻母
韻母只有一張圖要和38張圖比對,尺寸小,耗時短,不在此多著墨。
# 選取演算法
這部份沒什麼特別,目標就是最高分的圖示。以滿圖鑑為目標?不會多點幾次?
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.248.3.243 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/PCReDive/M.1583628323.A.04D.html
※ 編輯: gR7P4zXH (118.161.105.58 臺灣), 03/08/2020 08:52:43
推
03/08 08:52,
5年前
, 1F
03/08 08:52, 1F
推
03/08 08:53,
5年前
, 2F
03/08 08:53, 2F
推
03/08 08:56,
5年前
, 3F
03/08 08:56, 3F
跑實驗閒暇時做的
推
03/08 09:07,
5年前
, 4F
03/08 09:07, 4F
推
03/08 09:09,
5年前
, 5F
03/08 09:09, 5F
推
03/08 09:10,
5年前
, 6F
03/08 09:10, 6F
講完R
噓
03/08 09:11,
5年前
, 7F
03/08 09:11, 7F
推
03/08 09:11,
5年前
, 8F
03/08 09:11, 8F
推
03/08 09:11,
5年前
, 9F
03/08 09:11, 9F
推
03/08 09:15,
5年前
, 10F
03/08 09:15, 10F
推
03/08 09:21,
5年前
, 11F
03/08 09:21, 11F
推
03/08 09:41,
5年前
, 12F
03/08 09:41, 12F
推
03/08 09:48,
5年前
, 13F
03/08 09:48, 13F
推
03/08 09:57,
5年前
, 14F
03/08 09:57, 14F
推
03/08 10:02,
5年前
, 15F
03/08 10:02, 15F
沒有按鍵精靈
推
03/08 10:03,
5年前
, 16F
03/08 10:03, 16F
推
03/08 10:03,
5年前
, 17F
03/08 10:03, 17F
比較想去.net折衣服
→
03/08 10:09,
5年前
, 18F
03/08 10:09, 18F
我自己手動點,不算外掛喔
→
03/08 10:09,
5年前
, 19F
03/08 10:09, 19F
推
03/08 10:12,
5年前
, 20F
03/08 10:12, 20F
推
03/08 10:13,
5年前
, 21F
03/08 10:13, 21F
推
03/08 10:17,
5年前
, 22F
03/08 10:17, 22F
糞扣公開傷眼
推
03/08 10:17,
5年前
, 23F
03/08 10:17, 23F
推
03/08 10:23,
5年前
, 24F
03/08 10:23, 24F
推
03/08 10:24,
5年前
, 25F
03/08 10:24, 25F
推
03/08 10:29,
5年前
, 26F
03/08 10:29, 26F
好
推
03/08 10:31,
5年前
, 27F
03/08 10:31, 27F
推
03/08 10:33,
5年前
, 28F
03/08 10:33, 28F
推
03/08 10:33,
5年前
, 29F
03/08 10:33, 29F
推
03/08 10:44,
5年前
, 30F
03/08 10:44, 30F
請開spec
推
03/08 10:45,
5年前
, 31F
03/08 10:45, 31F
→
03/08 10:53,
5年前
, 32F
03/08 10:53, 32F
推
03/08 11:01,
5年前
, 33F
03/08 11:01, 33F
推
03/08 11:13,
5年前
, 34F
03/08 11:13, 34F
推
03/08 11:17,
5年前
, 35F
03/08 11:17, 35F
這是在家搞的
推
03/08 11:17,
5年前
, 36F
03/08 11:17, 36F
推
03/08 11:20,
5年前
, 37F
03/08 11:20, 37F
推
03/08 11:26,
5年前
, 38F
03/08 11:26, 38F
泳犬小遊戲?
推
03/08 11:28,
5年前
, 39F
03/08 11:28, 39F
影像公司泊車小弟
推
03/08 11:38,
5年前
, 40F
03/08 11:38, 40F
推
03/08 11:42,
5年前
, 41F
03/08 11:42, 41F
→
03/08 11:44,
5年前
, 42F
03/08 11:44, 42F
推
03/08 12:11,
5年前
, 43F
03/08 12:11, 43F
推
03/08 12:18,
5年前
, 44F
03/08 12:18, 44F
推
03/08 12:18,
5年前
, 45F
03/08 12:18, 45F
推
03/08 12:23,
5年前
, 46F
03/08 12:23, 46F
→
03/08 12:44,
5年前
, 47F
03/08 12:44, 47F
推
03/08 12:47,
5年前
, 48F
03/08 12:47, 48F
推
03/08 13:04,
5年前
, 49F
03/08 13:04, 49F
怎麼這麼多人知道git
推
03/08 13:10,
5年前
, 50F
03/08 13:10, 50F
不用學,這沒用到理論
推
03/08 13:17,
5年前
, 51F
03/08 13:17, 51F
推
03/08 13:20,
5年前
, 52F
03/08 13:20, 52F
推
03/08 13:29,
5年前
, 53F
03/08 13:29, 53F
→
03/08 13:29,
5年前
, 54F
03/08 13:29, 54F
凸了墓
推
03/08 14:02,
5年前
, 55F
03/08 14:02, 55F
推
03/08 14:16,
5年前
, 56F
03/08 14:16, 56F
推
03/08 14:25,
5年前
, 57F
03/08 14:25, 57F
噓
03/08 14:31,
5年前
, 58F
03/08 14:31, 58F
都蕊咪發搜
推
03/08 15:09,
5年前
, 59F
03/08 15:09, 59F
推
03/08 15:25,
5年前
, 60F
03/08 15:25, 60F
站內信
→
03/08 15:48,
5年前
, 61F
03/08 15:48, 61F
推
03/08 16:13,
5年前
, 62F
03/08 16:13, 62F
大佬跑錯板了
推
03/08 16:15,
5年前
, 63F
03/08 16:15, 63F
推
03/08 17:03,
5年前
, 64F
03/08 17:03, 64F
推
03/08 17:14,
5年前
, 65F
03/08 17:14, 65F
推
03/08 17:43,
5年前
, 66F
03/08 17:43, 66F
感謝建議,但已達到可用標準,懶得再改
推
03/08 17:47,
5年前
, 67F
03/08 17:47, 67F
推
03/08 18:17,
5年前
, 68F
03/08 18:17, 68F
→
03/08 19:17,
5年前
, 69F
03/08 19:17, 69F
推
03/09 00:03,
5年前
, 70F
03/09 00:03, 70F
推
03/09 00:35,
5年前
, 71F
03/09 00:35, 71F
※ 編輯: 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
推
03/09 07:58,
5年前
, 72F
03/09 07:58, 72F
推
03/09 08:41,
5年前
, 73F
03/09 08:41, 73F
推
03/10 08:54,
5年前
, 74F
03/10 08:54, 74F
推
03/10 11:07,
5年前
, 75F
03/10 11:07, 75F
推
03/10 21:23,
5年前
, 76F
03/10 21:23, 76F