我正在尝试制作钓鱼小游戏的脚本,网上有一个关于albion钓鱼脚本的帖子,问题是在这个游戏中指针很细,并且有很多不同的纹理和颜色,对于简单的灰度匹配工作在滑块的一个部分上很好(例如在水纹理上),有时在其他部分(树木纹理)上工作,在第三个部分(例如天空)上不起作用。如果我更改为较低的阈值,它通常会在不匹配的情况下激活。
import numpy as np
import cv2
from mss.windows import MSS as mss
from PIL import Image
import time
import pyautogui as pg
import cv2
import mss
import numpy
template = cv2.imread("perfect3.png", cv2.IMREAD_GRAYSCALE)
w, h = template.shape[::-1]
fgbg = cv2.createBackgroundSubtractorMOG2(
history=10,
varThreshold=2,
detectShadows=False)
with mss.mss() as sct:
monitor = {"top": 344, "left": 4419, "width": 150, "height": 666}
while "Screen capturing":
last_time = time.time()
img = numpy.array(sct.grab(monitor))
gray_frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(res >= 0.85)
for pt in zip(*loc[::-1]):
cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 3)
print('click')
cv2.imshow("OpenCV/Numpy normal", img)
key = cv2.waitKey(1)
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
没有运气也尝试了边缘检测 cv2.canny。
关键是当鱼在最小的绿色区域时单击按钮。该字段出现在滑块的随机部分中。
有任何想法吗?
=================
更新
正如Furas所说,尝试了配色
# import the necessary packages
from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
from mss.linux import MSS as mss
from PIL import Image
import mss
import numpy
import pyautogui
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
help="max buffer size")
args = vars(ap.parse_args())
# define the lower and upper boundaries of the "green"
# ball in the HSV color space, then initialize the
# list of tracked points
greenLower = (42, 84, 211)
greenUpper = (69, 130, 255)
blueLower = (88, 76, 255)
blueUpper = (151, 76, 255)
pts = deque(maxlen=args["buffer"])
# grab video from screen(monitor area)
with mss.mss() as sct:
monitor = {"top": 325, "left": 4423, "width": 136, "height": 662}
while "Screen capturing":
#last_time = time.time()
#vs = numpy.array(sct.grab(monitor))
#print("fps: {}".format(1 / (time.time() - last_time)))
vs = sct.grab(monitor)
# grab the current frame
#frame = vs
frame = np.array(vs)
# resize the frame, blur it, and convert it to the HSV
# color space
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
# construct a mask for the color "green", then perform
# a series of dilations and erosions to remove any small
# blobs left in the mask
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
mask2 = cv2.inRange(hsv, blueLower, blueUpper)
mask2 = cv2.erode(mask2, None, iterations=2)
mask2 = cv2.dilate(mask2, None, iterations=2)
# find contours in the mask and initialize the current
# (x, y) center of the ball
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
cnts2 = cv2.findContours(mask2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts2 = imutils.grab_contours(cnts2)
center2 = None
# only proceed if at least one contour was found
if len(cnts) > 0:
# find the largest contour in the mask, then use
# it to compute the minimum enclosing rectangle and
# centroid
c = max(cnts, key=cv2.contourArea)
(x, y, w, h) = cv2.boundingRect(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
c2 = max(cnts2, key=cv2.contourArea)
(x2, y2, w2, h2) = cv2.boundingRect(c2)
M2 = cv2.moments(c2)
center2 = (int(M2["m10"] / M2["m00"]), int(M2["m01"] / M2["m00"]))
# draw the rectangle and centroid on the frame,
# then update the list of tracked points
cv2.rectangle(frame, (int(x), int(y)), (int(x+w), int(y+h)),(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
cv2.rectangle(frame, (int(x2), int(y2)), (int(x2+w2), int(y2+h2)),(0, 255, 255), 2)
cv2.circle(frame, center2, 5, (0, 0, 255), -1)
# update the points queue
pts.appendleft(center)
if y-15 < y2 < y+15:
pyautogui.click(4908, 984)
time.sleep(2)
y2 = 0
cv2.imshow("frame", frame)
key = cv2.waitKey(1)
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
但在回合之前或回合之间我得到错误
Traceback (most recent call last):
File "C:\Users\Game\Desktop\Py\Fish.py", line 74, in <module>
c2 = max(cnts2, key=cv2.contourArea)
ValueError: max() arg is an empty sequence
如何解决?
按照弗拉斯的建议,将两个面具合二为一
mask = cv2.bitwise_or(mask1, mask2)
但是我可以用什么来找到绿地和鱼的最大值?到目前为止,它是 2 个掩码、2 个 cnts 和 2 个最大值。
使用 mss sct.grab 我没有那么好的 FPS(平均 25fps)还有其他更好的捕捉方法吗?
非常感谢!