Python - 如何从列表中提取元组?
Python - how do I extract a tuple from a list?
我的变量中存储了两个坐标 points
: [(100, 50)]
我试图用 pyautogui.moveTo(points)
移动鼠标,但出现错误:
pyautogui.PyAutoGUIException: The supplied sequence must have exactly 2 or exactly 4 elements (0 were received).
我假设这意味着我传递的是单个列表对象而不是坐标。
表达式 [(100, 50)]
是什么意思,我如何将 x 和 y 转换为两个元素。
我从中获取 points
的源代码:
import cv2 as cv
import numpy as np
class Vision:
# properties
needle_img = None
needle_w = 0
needle_h = 0
method = None
# constructor
def __init__(self, needle_img_path, method=cv.TM_CCOEFF_NORMED):
self.needle_img = cv.imread(needle_img_path, cv.IMREAD_UNCHANGED)
# Save the dimensions of the needle image
self.needle_w = self.needle_img.shape[1]
self.needle_h = self.needle_img.shape[0]
self.method = method
def find(self, haystack_img, threshold=0.5, debug_mode=None):
# run the OpenCV algorithm
result = cv.matchTemplate(haystack_img, self.needle_img, self.method)
# Get the all the positions from the match result that exceed our threshold
locations = np.where(result >= threshold)
locations = list(zip(*locations[::-1]))
for loc in locations:
rect = [int(loc[0]), int(loc[1]), self.needle_w, self.needle_h]
# Add every box to the list twice in order to retain single (non-overlapping) boxes
rectangles.append(rect)
rectangles.append(rect)
# Apply group rectangles
rectangles, weights = cv.groupRectangles(rectangles, groupThreshold=1, eps=0.5)
points = []
if len(rectangles):
line_color = (0, 255, 0)
line_type = cv.LINE_4
marker_color = (255, 0, 255)
marker_type = cv.MARKER_CROSS
# Loop over all the rectangles
for (x, y, w, h) in rectangles:
# Determine the center position
center_x = x + int(w/2)
center_y = y + int(h/2)
# Save the points
points.append((center_x, center_y))
if debug_mode == 'rectangles':
# Determine the box position
top_left = (x, y)
bottom_right = (x + w, y + h)
# Draw the box
cv.rectangle(haystack_img, top_left, bottom_right, color=line_color,
lineType=line_type, thickness=2)
elif debug_mode == 'points':
# Draw the center point
cv.drawMarker(haystack_img, (center_x, center_y),
color=marker_color, markerType=marker_type,
markerSize=40, thickness=2)
if debug_mode:
cv.imshow('Matches', haystack_img)
return points
What does the expression [(100, 50)] mean and how I can I transform x and y into two elements.
[...]
创建一个列表,其中包含您放入其中的任何内容。 (100, 50)
创建一个包含整数 100
和 50
的元组。所以你有一个列表,其中包含一个包含两个数字的元组。
I assume this means I'm passing a single list object rather than the coordinates.
你是对的,有点。问题不在于您要传递单个列表对象,您需要 传递单个列表,或者更确切地说,序列 对象。问题是该列表对象仅包含 一个元素:元组。
您可以通过查看列表的 len
来检查:
>>> l = [(100, 50)]
>>> len(l)
1
按照您打算使用它的方式,pyautogui.moveTo(points)
想要一个包含 两个 元素的序列(列表或元组)。这些元素就是你要移动到的点的坐标。
列表里面的元组就是这个二元序列,所以需要传的就是:
pyautogui.moveTo(points[0])
我的变量中存储了两个坐标 points
: [(100, 50)]
我试图用 pyautogui.moveTo(points)
移动鼠标,但出现错误:
pyautogui.PyAutoGUIException: The supplied sequence must have exactly 2 or exactly 4 elements (0 were received).
我假设这意味着我传递的是单个列表对象而不是坐标。
表达式 [(100, 50)]
是什么意思,我如何将 x 和 y 转换为两个元素。
我从中获取 points
的源代码:
import cv2 as cv
import numpy as np
class Vision:
# properties
needle_img = None
needle_w = 0
needle_h = 0
method = None
# constructor
def __init__(self, needle_img_path, method=cv.TM_CCOEFF_NORMED):
self.needle_img = cv.imread(needle_img_path, cv.IMREAD_UNCHANGED)
# Save the dimensions of the needle image
self.needle_w = self.needle_img.shape[1]
self.needle_h = self.needle_img.shape[0]
self.method = method
def find(self, haystack_img, threshold=0.5, debug_mode=None):
# run the OpenCV algorithm
result = cv.matchTemplate(haystack_img, self.needle_img, self.method)
# Get the all the positions from the match result that exceed our threshold
locations = np.where(result >= threshold)
locations = list(zip(*locations[::-1]))
for loc in locations:
rect = [int(loc[0]), int(loc[1]), self.needle_w, self.needle_h]
# Add every box to the list twice in order to retain single (non-overlapping) boxes
rectangles.append(rect)
rectangles.append(rect)
# Apply group rectangles
rectangles, weights = cv.groupRectangles(rectangles, groupThreshold=1, eps=0.5)
points = []
if len(rectangles):
line_color = (0, 255, 0)
line_type = cv.LINE_4
marker_color = (255, 0, 255)
marker_type = cv.MARKER_CROSS
# Loop over all the rectangles
for (x, y, w, h) in rectangles:
# Determine the center position
center_x = x + int(w/2)
center_y = y + int(h/2)
# Save the points
points.append((center_x, center_y))
if debug_mode == 'rectangles':
# Determine the box position
top_left = (x, y)
bottom_right = (x + w, y + h)
# Draw the box
cv.rectangle(haystack_img, top_left, bottom_right, color=line_color,
lineType=line_type, thickness=2)
elif debug_mode == 'points':
# Draw the center point
cv.drawMarker(haystack_img, (center_x, center_y),
color=marker_color, markerType=marker_type,
markerSize=40, thickness=2)
if debug_mode:
cv.imshow('Matches', haystack_img)
return points
What does the expression [(100, 50)] mean and how I can I transform x and y into two elements.
[...]
创建一个列表,其中包含您放入其中的任何内容。 (100, 50)
创建一个包含整数 100
和 50
的元组。所以你有一个列表,其中包含一个包含两个数字的元组。
I assume this means I'm passing a single list object rather than the coordinates.
你是对的,有点。问题不在于您要传递单个列表对象,您需要 传递单个列表,或者更确切地说,序列 对象。问题是该列表对象仅包含 一个元素:元组。
您可以通过查看列表的 len
来检查:
>>> l = [(100, 50)]
>>> len(l)
1
按照您打算使用它的方式,pyautogui.moveTo(points)
想要一个包含 两个 元素的序列(列表或元组)。这些元素就是你要移动到的点的坐标。
列表里面的元组就是这个二元序列,所以需要传的就是:
pyautogui.moveTo(points[0])