特征匹配

特征匹配是 mower 中最方便的识别方法。在截图中匹配目标图像时,首先提取截图与目标图像的特征点,然后找出匹配的特征点对,利用匹配结果在截图中定位目标图像。

特征与特征点

arknights_mower.utils.matcher 中提供 keypoints()keypoints_scale_invariant() 函数,可用于提取特征点。接受的参数为需要提取特征点的灰度图像。返回值为特征点元组与描述子矩阵构成的元组。

keypoints_scale_invariant() 提取的特征点与描述子具有尺度不变性,可用于匹配尺度不确定或发生变化的图像,但速度相较 keypoints() 更慢。

拐角、复杂的图案与纹理(包括文字)处可以提取到较多的特征点;在空白处很难提取到特征点。

使用示例
In [1]:
import cv2
from matplotlib import pyplot as plt
from arknights_mower.utils.image import loadimg
from arknights_mower.utils.matcher import keypoints
In [2]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/201/20240713031749.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 11:45:32,901 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/201/20240713031749.png
No description has been provided for this image
In [3]:
kp, des = keypoints(sc)
print(len(kp))
img = cv2.drawKeypoints(sc, kp, None, (0, 255, 0), flags=0)
plt.imshow(img)
plt.show()
7464
No description has been provided for this image
In [4]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/103/20240713152407.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 11:45:33,699 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/103/20240713152407.png
No description has been provided for this image
In [5]:
kp, des = keypoints(sc)
print(len(kp))
img = cv2.drawKeypoints(sc, kp, None, (0, 255, 0), flags=0)
plt.imshow(img)
plt.show()
2016
No description has been provided for this image

特征点的匹配

arknights_mower.utils.matcher 中的 flann 可用于匹配特征点。

对于目标图像中的每个特征点 $A$,使用 flann.knnMatch(k=2) 找出截图中与之距离最近的和第二近的两个特征点 $B_1$、$B_2$. 如果 $A$ 与 $B_1$ 的距离 $\text{d}(A, B_1)$ 和 $A$ 与 $B_2$ 的距离 $\text{d}(A, B_2)$ 的比值 $\frac{\text{d}(A, B_1)}{\text{d}(A, B_2)} <$ GOOD_DISTANCE_LIMIT,就认为 $A$ 与 $B_1$ 是一对"好"的匹配。

下面的例子展示了如何利用特征匹配在终端页面定位活动入口。其中 res 图像来自明日方舟网站,尺寸与游戏内截图未必一致,因此对于 res 使用 keypoints_scale_invariant() 提取特征点。对于截图,使用 keypoints() 提取特征点,仍然可以得到很好的匹配结果。

使用示例
In [1]:
import cv2
from matplotlib import pyplot as plt
from arknights_mower.utils.image import loadimg
from arknights_mower.utils.matcher import (
    GOOD_DISTANCE_LIMIT,
    flann,
    keypoints,
    keypoints_scale_invariant,
)
In [2]:
res = loadimg("/home/zhao/Documents/hot_update/hortus/terminal.jpg", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
kp1, des1 = keypoints_scale_invariant(res)
img = cv2.drawKeypoints(res, kp1, None, (0, 255, 0), flags=0)
plt.imshow(img)
plt.show()
2024-07-15 12:07:34,522 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/hot_update/hortus/terminal.jpg
No description has been provided for this image
No description has been provided for this image
In [3]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/501/20240705031952.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
kp2, des2 = keypoints(sc)
img = cv2.drawKeypoints(sc, kp2, None, (0, 255, 0), flags=0)
plt.imshow(img)
plt.show()
2024-07-15 12:07:35,018 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/501/20240705031952.png
No description has been provided for this image
No description has been provided for this image
In [4]:
matches = flann.knnMatch(des1, des2, k=2)
good = []
for pair in matches:
    if (len_pair := len(pair)) == 2:
        x, y = pair
        if x.distance < GOOD_DISTANCE_LIMIT * y.distance:
            good.append(x)
    elif len_pair == 1:
        good.append(pair[0])
good = sorted(good, key=lambda x: x.distance)
debug_img = cv2.drawMatches(
    res,
    kp1,
    sc,
    kp2,
    good[:50],
    None,
    (0, 255, 0),
    flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS,
)
plt.imshow(debug_img)
plt.show()
No description has been provided for this image
In [5]:
debug_img = cv2.cvtColor(sc, cv2.COLOR_GRAY2RGB)
center = list(map(int, kp2[good[0].trainIdx].pt))
print(center)
cv2.circle(debug_img, center, 20, (0, 255, 0), 5)
plt.imshow(debug_img)
plt.show()
[463, 273]
No description has been provided for this image
In [6]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/501/20240705071219.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
kp2, des2 = keypoints(sc)
img = cv2.drawKeypoints(sc, kp2, None, (0, 255, 0), flags=0)
plt.imshow(img)
plt.show()
2024-07-15 12:07:36,328 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/501/20240705071219.png
No description has been provided for this image
No description has been provided for this image
In [7]:
matches = flann.knnMatch(des1, des2, k=2)
good = []
for pair in matches:
    if (len_pair := len(pair)) == 2:
        x, y = pair
        if x.distance < GOOD_DISTANCE_LIMIT * y.distance:
            good.append(x)
    elif len_pair == 1:
        good.append(pair[0])
good = sorted(good, key=lambda x: x.distance)
debug_img = cv2.drawMatches(
    res,
    kp1,
    sc,
    kp2,
    good[:50],
    None,
    (0, 255, 0),
    flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS,
)
plt.imshow(debug_img)
plt.show()
No description has been provided for this image
In [8]:
debug_img = cv2.cvtColor(sc, cv2.COLOR_GRAY2RGB)
center = list(map(int, kp2[good[0].trainIdx].pt))
print(center)
cv2.circle(debug_img, center, 20, (0, 255, 0), 5)
plt.imshow(debug_img)
plt.show()
[1173, 209]
No description has been provided for this image

利用特征匹配定位目标图像

arknights_mower.utils.matcher 中的 Matcher 类可用于定位目标图片。

实例化 Matcher 类时,需传入灰度图像 origin。实例化过程中计算 origin 图像的特征点。

Matcher 类的实例方法 match() 接受 6 个参数,其中 query 必选:

  • query:灰度目标图像;
  • draw:控制是否绘制并显示匹配过程;
  • scopeorigin 在此区域内的特征点参与匹配;
  • dpi_aware:匹配尺寸不确定,或尺寸有变化的目标图像时,将此选项设置为 True。默认为 False
  • prescore:SSIM 分数阈值。如果此参数为正值,则根据 SSIM 分数直接决定是否接受匹配结果。
  • judge:在 prescore 为 0 时生效。如果为 True,使用支持向量机判断是否接受匹配结果,否则直接接受匹配结果。

如果匹配成功,match() 返回目标图片在截图中匹配到的区域;否则返回 None

使用示例
In [1]:
from matplotlib import pyplot as plt
from arknights_mower.utils.image import cropimg, loadimg, loadres
from arknights_mower.utils.matcher import Matcher
In [2]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/202/20240714174003.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:27,949 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/202/20240714174003.png
No description has been provided for this image
In [3]:
res = loadres("infra_collect_factory", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:28,274 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/arknights-mower/arknights_mower/resources/infra_collect_factory.png
No description has been provided for this image
In [4]:
matcher = Matcher(sc)
2024-07-15 12:15:28,441 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:77 - __init__ - Matcher init: shape ((1080, 1920))
In [5]:
matcher.match(res, draw=True)
No description has been provided for this image
2024-07-15 12:15:28,781 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[1.0002113191377349, 0.0021223900228503905, 242.8645414564958], [-0.00010565956886722923, 0.9989388049885747, 985.0677292717521]]
No description has been provided for this image
No description has been provided for this image
2024-07-15 12:15:29,228 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[243, 985], [321, 1063]], (0.6619718309859155, 0.717948717948718, 1.0, 0.9736551440651242))
Out[5]:
[[243, 985], [321, 1063]]
In [6]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/201/20240714214339.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:29,239 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/201/20240714214339.png
No description has been provided for this image
In [7]:
res = loadres("control_central", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:29,479 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/arknights-mower/arknights_mower/resources/control_central.png
No description has been provided for this image
In [8]:
matcher = Matcher(sc)
2024-07-15 12:15:29,653 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:77 - __init__ - Matcher init: shape ((1080, 1920))
In [9]:
matcher.match(res, draw=True, dpi_aware=True)
No description has been provided for this image
2024-07-15 12:15:30,082 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[0.7535227826125278, -0.0005473631013470435, 1097.909614955585], [-0.0013096213809555084, 0.754970238050705, 239.22899092320966]]
No description has been provided for this image
No description has been provided for this image
2024-07-15 12:15:30,562 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[1098, 239], [1294, 360]], (0.0953819594302978, 0.8839385106013371, 0.9375, 0.8595908226210209))
Out[9]:
[[1098, 239], [1294, 360]]
In [10]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/1105/20240712065207.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:30,575 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/1105/20240712065207.png
No description has been provided for this image
In [11]:
res = loadimg("/home/zhao/Documents/mower-profile/screenshot/1106/20240712065212.png", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:30,821 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/1106/20240712065212.png
No description has been provided for this image
In [12]:
res = cropimg(res, ((1020, 230), (1210, 280)))
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
No description has been provided for this image
In [13]:
matcher = Matcher(sc)
2024-07-15 12:15:31,162 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:77 - __init__ - Matcher init: shape ((1080, 1920))
In [14]:
matcher.match(res, draw=True, dpi_aware=True)
No description has been provided for this image
2024-07-15 12:15:31,483 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[1.1167040828189694, -0.018270101836457227, 1014.5181388435077], [-0.0008505324769905506, 1.1183497106314426, 610.7774407553333]]
No description has been provided for this image
No description has been provided for this image
2024-07-15 12:15:31,865 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[1015, 611], [1227, 667]], (0.050080775444264945, 0.6736842105263158, 0.875, 0.6841249306767808))
Out[14]:
[[1015, 611], [1227, 667]]
In [15]:
sc = loadimg("/home/zhao/Documents/Desktop/crc/108/20240222230009.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:31,876 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/Desktop/crc/108/20240222230009.png
No description has been provided for this image
In [16]:
res = loadres("login_captcha", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 12:15:32,137 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/arknights-mower/arknights_mower/resources/login_captcha.png
No description has been provided for this image
In [17]:
matcher = Matcher(sc)
2024-07-15 12:15:32,268 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:77 - __init__ - Matcher init: shape ((1080, 1920))
In [18]:
matcher.match(res, draw=True, dpi_aware=True)
No description has been provided for this image
2024-07-15 12:15:32,606 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[0.860710131969706, 0.004565988396697833, 646.7586268579719], [0.002056726918675809, 0.8712260893573366, 639.807371571572]]
No description has been provided for this image
No description has been provided for this image
2024-07-15 12:15:33,141 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[647, 640], [778, 865]], (0.1348314606741573, 0.8102526539250424, 1.0, 0.9463482497394052))
Out[18]:
[[647, 640], [778, 865]]

利用特征匹配求解单应性矩阵

游戏首页的界面随重力改变角度,为识别界面上的数字,可使用特征匹配求解单应性矩阵,将界面内容变换至平面,再进行进一步的识别。

使用示例
In [1]:
import cv2
import numpy as np
from matplotlib import pyplot as plt
from arknights_mower.utils.image import cropimg, loadimg, loadres
from arknights_mower.utils.matcher import (
    GOOD_DISTANCE_LIMIT,
    flann,
    keypoints_scale_invariant,
)
In [2]:
res = loadres("sanity", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-16 21:01:18,429 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/arknights-mower/arknights_mower/resources/sanity.png
No description has been provided for this image
In [3]:
sc = loadimg("/home/zhao/Downloads/Screenshot_20240716-180721.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-16 21:01:18,783 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Downloads/Screenshot_20240716-180721.png
No description has been provided for this image
In [4]:
img = cropimg(sc, ((1400, 000), (2000, 800)))
plt.imshow(img, cmap="gray", vmin=0, vmax=255)
plt.show()
No description has been provided for this image
In [5]:
kp1, des1 = keypoints_scale_invariant(res)
kp2, des2 = keypoints_scale_invariant(img)
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
matches = flann.knnMatch(des1, des2, k=2)
good = []
for pair in matches:
    if (len_pair := len(pair)) == 2:
        m, n = pair
        if m.distance < GOOD_DISTANCE_LIMIT * n.distance:
            good.append(m)
    elif len_pair == 1:
        good.append(pair[0])
print(len(good))
src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()
240
In [6]:
h, w = res.shape
pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
disp = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
disp = cv2.polylines(disp, [np.int32(dst)], True, (255, 0, 0), 2, cv2.LINE_AA)
good = sorted(good, key=lambda x: x.distance)
disp = cv2.drawMatches(
    res,
    kp1,
    disp,
    kp2,
    good[:50],
    None,
    (0, 255, 0),
    flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS,
)
plt.imshow(disp)
plt.show()
No description has been provided for this image
In [7]:
M
Out[7]:
array([[ 5.45219656e-01, -1.40243401e-02,  5.38688840e+01],
       [-6.00027151e-02,  6.48058168e-01,  2.06700298e+02],
       [-1.17835742e-04, -1.26823789e-05,  1.00000000e+00]])
In [8]:
offset = (80, 250)
A = np.array([[1, 0, -offset[0]], [0, 1, -offset[1]], [0, 0, 1]])
In [9]:
disp = cv2.warpPerspective(img, M.dot(A), (800, 1100), None, cv2.WARP_INVERSE_MAP)
plt.subplot(1, 2, 1)
plt.imshow(img, cmap="gray", vmin=0, vmax=255)
plt.subplot(1, 2, 2)
plt.imshow(disp, cmap="gray", vmin=0, vmax=255)
plt.show()
No description has been provided for this image

注意事项

性能

从截图提取特征点一般会花费数十毫秒,一次 FLANN 匹配也可能花费几毫秒到几十毫秒。大量使用特征匹配会导致脚本很慢。但是,对于不限制区域的匹配,特征匹配往往比在整个截图上进行模板匹配更快。

示例:生息演算地图匹配地点
In [1]:
from matplotlib import pyplot as plt
from arknights_mower.utils.matcher import Matcher
from arknights_mower.utils.image import loadimg, loadres
In [2]:
sc = loadimg("/home/zhao/Documents/Desktop/ra_map.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-16 17:47:39,468 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/Desktop/ra_map.png
No description has been provided for this image
In [3]:
res = loadres("ra/map/资源区_射程以内", True)
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-16 17:47:39,726 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/arknights-mower/arknights_mower/resources/ra/map/资源区_射程以内.png
No description has been provided for this image
In [4]:
matcher = Matcher(sc)
2024-07-16 17:47:39,863 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:77 - __init__ - Matcher init: shape ((900, 1370))
In [5]:
matcher.match(res, draw=True)
No description has been provided for this image
2024-07-16 17:47:40,242 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[1.0012251734016322, -0.005298719241620122, 667.1395609672389], [0.0004466367175678509, 1.00531283833583, 454.08088001521105]]
No description has been provided for this image
No description has been provided for this image
2024-07-16 17:47:40,604 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[667, 454], [925, 582]], (0.5030120481927711, 0.8988326848249028, 0.875, 0.8695953607668526))
Out[5]:
[[667, 454], [925, 582]]
In [6]:
import cv2
from arknights_mower.utils.vector import va
In [7]:
result = cv2.matchTemplate(sc, res, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
print(max_val)
h, w = res.shape
scope = max_loc, va(max_loc, (w, h))
print(scope)
img = cv2.cvtColor(sc, cv2.COLOR_GRAY2RGB)
cv2.rectangle(img, scope[0], scope[1], (0, 255, 0), 3)
plt.imshow(img)
plt.show()
0.9816110134124756
((667, 454), (924, 582))
No description has been provided for this image
In [8]:
from arknights_mower.utils.log import logger
logger.setLevel("INFO")
In [9]:
%timeit matcher = Matcher(sc)
3.91 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [10]:
%timeit matcher.match(res)
4.38 ms ± 34.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [11]:
%%timeit
result = cv2.matchTemplate(sc, res, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
30.7 ms ± 1.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

目标图像截取

目标图像应尽量满足特征点数量多、尺寸小、与其它目标图像有较大区别。例如对于按钮,只截取按钮中独特的图案,或在文字中截取 3-5 字的关键词,相比截取整个按钮,往往能得到更好的效果。

随机性

FLANN 和 RANSAC 算法具有一定的随机性。若结果变化较大,可考虑重新截取目标图像,或换用其它匹配方式。

多目标

当目标图像在截图中多次出现时,目标图像的特征点与截图对应特征点的若干对匹配距离相近。在应用比例测试筛选特征点时,这些匹配都会被过滤掉,导致目标图像多次出现时无法匹配到结果。

如果要处理目标多次出现的情况,如果能够预知出现的范围,可以指定 scope 参数进行限制。

查看例子
In [1]:
from matplotlib import pyplot as plt
from arknights_mower.utils.image import loadimg, cropimg
from arknights_mower.utils.matcher import Matcher
In [2]:
sc = loadimg("/home/zhao/Documents/mower-profile/screenshot/1106/20240712065212.png", True)
plt.imshow(sc, cmap="gray", vmin=0, vmax=255)
plt.show()
2024-07-15 15:57:57,310 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/image.py:44 - loadimg - /home/zhao/Documents/mower-profile/screenshot/1106/20240712065212.png
No description has been provided for this image
In [3]:
res = cropimg(sc, ((322, 530), (363, 572)))
plt.imshow(res, cmap="gray", vmin=0, vmax=255)
plt.show()
No description has been provided for this image
In [4]:
matcher = Matcher(sc)
2024-07-15 15:57:58,037 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:77 - __init__ - Matcher init: shape ((1080, 1920))
In [5]:
matcher.match(res, draw=True)
No description has been provided for this image
2024-07-15 15:57:58,600 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:185 - score - not enough good matches are found: 2 / 23
In [6]:
matcher.match(res, draw=True, scope=((1360, 466), (1830, 940)))
2024-07-15 15:57:58,621 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:143 - score - match crop: ((1360, 466), (1830, 940)), 6310 -> 941
No description has been provided for this image
2024-07-15 15:57:59,123 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[1.0, -0.0, 1381.0], [-0.0, 1.0, 530.0]]
No description has been provided for this image
No description has been provided for this image
2024-07-15 15:57:59,910 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[1381, 530], [1422, 572]], (0.43478260869565216, 0.43902439024390244, 1.0, 0.9991145602006186))
Out[6]:
[[1381, 530], [1422, 572]]
In [7]:
matcher.match(res, draw=True, scope=((300, 465), (700, 940)))
2024-07-15 15:57:59,931 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:143 - score - match crop: ((300, 465), (700, 940)), 6310 -> 990
No description has been provided for this image
2024-07-15 15:58:00,444 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:202 - score - transform matrix: [[1.0, 0.0, 322.0], [0.0, 1.0, 530.0]]
No description has been provided for this image
No description has been provided for this image
2024-07-15 15:58:01,216 - DEBUG - /home/zhao/Documents/arknights-mower/arknights_mower/utils/matcher.py:113 - match - match success: ([[322, 530], [363, 572]], (0.6086956521739131, 0.4634146341463415, 1.0, 1.0))
Out[7]:
[[322, 530], [363, 572]]