我是Python的新手,但想学习一点,所以我决定创建一个程序 与桌面输入中的模板匹配。
有人可以帮忙吗?如何编写与桌面流匹配的模板?
import time
import cv2
import mss
import numpy
template = cv2.imread('template.jpg', 0)
w, h = template.shape[::-1]
with mss.mss() as sct:
# Part of the screen to capture
monitor = {"top": 40, "left": 0, "width": 800, "height": 640}
while "Screen capturing":
last_time = time.time()
# Get raw pixels from the screen, save it to a Numpy array
img = numpy.array(sct.grab(monitor))
# Display the picture
# cv2.imshow("OpenCV/Numpy normal", img)
# Display the picture in grayscale
cv2.imshow('OpenCV/Numpy grayscale', cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY))
# Print fps
print("fps: {}".format(1 / (time.time() - last_time)))
# Search template in stream
# Press "q" to quit
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
答案 0 :(得分:2)
第一件事,我注意到您没有对模板图像进行任何边缘检测。边缘检测不是必需的,但对于找到模板图像的特征很有用。
假设我有以下图片:
要精确地检测上述模板图像,我应该应用边缘检测算法。
template = cv2.imread("three.png")
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 50, 200)
我还应该对桌面流进行边缘检测。
img = sct.grab(mon)
gray = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2GRAY)
edged = cv2.Canny(gray, 50, 200)
检查模板是否与捕获的图像匹配
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
如果模板图像在桌面流中匹配,则获取坐标。
(_, maxLoc, r) = found
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
(endX, endY) = (int((maxLoc[0] + w) * r), int((maxLoc[1] + h) * r))
最后绘制矩形以显示位置:
cv2.rectangle(img, (startX, startY), (endX, endY), (180, 105, 255), 2)
结果:
从上方我们看到,模板3的值在桌面流上是匹配的。
代码:
import time
import cv2
import numpy as np
import imutils
from mss import mss
template = cv2.imread("three.png")
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 50, 200)
(h, w) = template.shape[:2]
start_time = time.time()
mon = {'top': 200, 'left': 200, 'width': 200, 'height': 200}
with mss() as sct:
while True:
last_time = time.time()
img = sct.grab(mon)
img = np.array(img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edged = cv2.Canny(gray, 50, 200)
found = None
for scale in np.linspace(0.2, 1.0, 20)[::-1]:
resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
r = gray.shape[1] / float(resized.shape[1])
if resized.shape[0] < h or resized.shape[1] < w:
break
edged = cv2.Canny(resized, 50, 200)
cv2.imwrite("canny_image.png", edged)
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
if found is None or maxVal > found[0]:
found = (maxVal, maxLoc, r)
(_, maxLoc, r) = found
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
(endX, endY) = (int((maxLoc[0] + w) * r), int((maxLoc[1] + h) * r))
cv2.rectangle(img, (startX, startY), (endX, endY), (180, 105, 255), 2)
print('The loop took: {0}'.format(time.time()-last_time))
cv2.imshow('test', np.array(img))
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
答案 1 :(得分:0)
以下是执行匹配模板的基本代码。将其放在img = numpy.array(sct.grab(monitor))
下,它将在每一帧运行。
# create grayscale of image - because template is also grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# perform match
res = cv2.matchTemplate(gray,template ,cv2.TM_CCOEFF)
# get coordinates of best match
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = min_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
# draw red rectangle over original screen capture
cv2.rectangle(img,top_left, bottom_right,(0,0,255),3)
# display image
cv2.imshow('Result',img)
您可以找到有关matchTemplate here
的更多信息答案 2 :(得分:0)
让 untitled.png 成为存储图像的文件
这是一个正在运行的程序。我使用以下内容将它们放在一起,
Taking screenshots with OpenCV and Python
OpenCV python: ValueError: too many values to unpack
import os
import cv2 as cv
import numpy as np
import pyautogui
import time
import winsound # for sound
from matplotlib import pyplot as plt
os.chdir("C:\\Users\\Mike\\\Desktop")
img = cv.imread('untitled.png',0)
img_piece = cv.cvtColor(img, cv.COLOR_RGB2BGR)
c, w, h = img_piece.shape[::-1]
while 1:
pic = pyautogui.screenshot()
template = cv.cvtColor(np.array(pic), cv.COLOR_RGB2BGR)
meth = 'cv.TM_CCOEFF'
method = eval(meth)
# Apply template Matching
res = cv.matchTemplate(img_piece,template,method)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv.rectangle(img,top_left, bottom_right, 255, 2)
if max_val > 66000000.0:
print(max_val, top_left, bottom_right)
winsound.Beep(888, 111)
if 1:
plt.subplot(121),plt.imshow(res,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
break
time.sleep(1)