ValueError: too many values to unpack (expected 4) during ORB detection
ValueError: too many values to unpack (expected 4) during ORB detection
我正在检测星空背景上的 Unicode 字词。它们看起来都有点像下面的示例图片。我有一个包含 183 张图像的文件夹,如果检测到其中任何图像,我想单击屏幕上的按钮。如果没有检测到图像,我想重复这个过程。
到目前为止,我在模板匹配方面取得了最大的成功。我将图像加载到一个数组中,遍历整个数组,如果有 returns >90% 匹配,我单击按钮。
然而,这会返回大量误报。为了改进我的检测,我已经尝试过;
- Canny 边缘检测
- HSV 阈值
- 匹配模板
- SIFT 和 SURF
- 并且,使用 ORB 描述符进行暴力匹配
远射的最佳结果是使用 ORB,毫无疑问,甚至没有接近。
我已经关注 this tutorial and all of the tutorials on opencv.org,但是 我收到以下错误,这似乎是相当随机的。通常是当后台应用程序图像发生显着变化时,但我不知道为什么这很重要。
Traceback (most recent call last):
File "c:\Users\keypoint_detection_test1.py", line 63, in <module>
keypoint_detection(ships_to_avoid)
File "c:\Users\keypoint_detection_test1.py", line 39, in keypoint_detection
kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_image)
ValueError: too many values to unpack (expected 4)
这个错误是什么意思,我该如何解决?
import cv2 as cv
import os
import glob
# Change the working directory to the folder this script is in.
os.chdir('C:\Users\')
avoid = glob.glob(r"C:\Users\*.png")
def loadImages(directory):
# Intialise empty array
image_list = []
# Add images to array
for i in directory:
img = cv.imread(i, cv.IMREAD_UNCHANGED)
image_list.append((img, i))
return image_list
# initialize the WindowCapture class
wincap = WindowCapture()
def keypoint_detection(image_list):
for i in image_list:
needle_img = i[0]
needle_name = i[1]
# load image to find
objectToFind = Vision(needle_img)
# get an updated image of the screen
keypoint_image = wincap.get_haystack()
# crop the image
x, w, y, h = [600,700,20,50]
keypoint_image = keypoint_image[y:y+h, x:x+w]
kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_image)
match_image = cv.drawMatches(objectToFind.needle_img, kp1, keypoint_image, kp2, matches, None)
if match_points:
# find the center point of all the matched features
center_point = objectToFind.centeroid(match_points)
# account for the width of the needle image that appears on the left
center_point[0] += objectToFind.needle_w
# drawn the found center point on the output image
match_image = objectToFind.draw_crosshairs(match_image, [center_point])
# move somewhere/do something
#py.moveTo(center_point)
# display the processed image
cv.imshow('Keypoint Search', match_image)
# press 'q' with the output window focused to exit.
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
while(True):
ships_to_avoid = loadImages(avoid)
keypoint_detection(ships_to_avoid)
class Vision:
# properties
needle_img = None
needle_w = 0
needle_h = 0
# constructor
def __init__(self, needle_img_path):
self.needle_img = needle_img_path
# Save the dimensions of the needle image
self.needle_w = self.needle_img.shape[1]
self.needle_h = self.needle_img.shape[0]
def match_keypoints(self, original_image, patch_size=32):
min_match_count = 35
orb = cv.ORB_create(edgeThreshold=0, patchSize=patch_size)
keypoints_needle, descriptors_needle = orb.detectAndCompute(self.needle_img, None)
orb2 = cv.ORB_create(edgeThreshold=0, patchSize=patch_size, nfeatures=2000)
keypoints_haystack, descriptors_haystack = orb2.detectAndCompute(original_image, None)
FLANN_INDEX_LSH = 6
index_params = dict(algorithm=FLANN_INDEX_LSH, table_number=6, key_size=12, multi_probe_level=1)
search_params = dict(checks=50)
try:
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(descriptors_needle, descriptors_haystack, k=2)
except cv.error:
return None, None, [], [], None
# store all the good matches as per Lowe's ratio test.
good = []
points = []
for pair in matches:
if len(pair) == 2:
if pair[0].distance < 0.7*pair[1].distance:
good.append(pair[0])
if len(good) > min_match_count:
print('match %03d, kp %03d' % (len(good), len(keypoints_needle)))
for match in good:
points.append(keypoints_haystack[match.trainIdx].pt)
return keypoints_needle, keypoints_haystack, good, points
class WindowCapture:
# properties
w = 0
h = 0
hwnd = None
cropped_x = 0
cropped_y = 0
offset_x = 0
offset_y = 0
# constructor
def __init__(self, window_name=None):
# find the handle for the window we want to capture.
# if no window name is given, capture the entire screen
if window_name is None:
self.hwnd = win32gui.GetDesktopWindow()
else:
self.hwnd = win32gui.FindWindow(None, window_name)
if not self.hwnd:
raise Exception('Window not found: {}'.format(window_name))
# get the window size
window_rect = win32gui.GetWindowRect(self.hwnd)
self.w = window_rect[2] - window_rect[0]
self.h = window_rect[3] - window_rect[1]
# account for the window border and titlebar and cut them off
border_pixels = 0
titlebar_pixels = 0
self.w = self.w - (border_pixels * 2)
self.h = self.h - titlebar_pixels - border_pixels
self.cropped_x = border_pixels
self.cropped_y = titlebar_pixels
self.offset_x = window_rect[0] + self.cropped_x
self.offset_y = window_rect[1] + self.cropped_y
def get_haystack(self):
# get the window image data
wDC = win32gui.GetWindowDC(self.hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)
signedIntsArray = dataBitMap.GetBitmapBits(True)
img = np.fromstring(signedIntsArray, dtype='uint8')
img.shape = (self.h, self.w, 4)
# free resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(self.hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
img = img[...,:3]
img = np.ascontiguousarray(img)
return img
在 match_keypoints
中你有(至少)两个 return
语句。
其中一个,在except
块中returns 5个元素,None, None, [], [], None
.
其他returns 4个元素,return keypoints_needle, keypoints_haystack, good, points
因此,每当 match_keypoints
在那个 try
块中遇到 cv.error
时,它将 return 5 个元素,这比你试图在该行中取消引用多一个那是失败的:kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_image)
Too many values to unpack
是当 returned 元组的元素多于分配的 LHS 上的变量数时发生的错误。
我正在检测星空背景上的 Unicode 字词。它们看起来都有点像下面的示例图片。我有一个包含 183 张图像的文件夹,如果检测到其中任何图像,我想单击屏幕上的按钮。如果没有检测到图像,我想重复这个过程。
到目前为止,我在模板匹配方面取得了最大的成功。我将图像加载到一个数组中,遍历整个数组,如果有 returns >90% 匹配,我单击按钮。
然而,这会返回大量误报。为了改进我的检测,我已经尝试过;
- Canny 边缘检测
- HSV 阈值
- 匹配模板
- SIFT 和 SURF
- 并且,使用 ORB 描述符进行暴力匹配
远射的最佳结果是使用 ORB,毫无疑问,甚至没有接近。
我已经关注 this tutorial and all of the tutorials on opencv.org,但是 我收到以下错误,这似乎是相当随机的。通常是当后台应用程序图像发生显着变化时,但我不知道为什么这很重要。
Traceback (most recent call last):
File "c:\Users\keypoint_detection_test1.py", line 63, in <module>
keypoint_detection(ships_to_avoid)
File "c:\Users\keypoint_detection_test1.py", line 39, in keypoint_detection
kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_image)
ValueError: too many values to unpack (expected 4)
这个错误是什么意思,我该如何解决?
import cv2 as cv
import os
import glob
# Change the working directory to the folder this script is in.
os.chdir('C:\Users\')
avoid = glob.glob(r"C:\Users\*.png")
def loadImages(directory):
# Intialise empty array
image_list = []
# Add images to array
for i in directory:
img = cv.imread(i, cv.IMREAD_UNCHANGED)
image_list.append((img, i))
return image_list
# initialize the WindowCapture class
wincap = WindowCapture()
def keypoint_detection(image_list):
for i in image_list:
needle_img = i[0]
needle_name = i[1]
# load image to find
objectToFind = Vision(needle_img)
# get an updated image of the screen
keypoint_image = wincap.get_haystack()
# crop the image
x, w, y, h = [600,700,20,50]
keypoint_image = keypoint_image[y:y+h, x:x+w]
kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_image)
match_image = cv.drawMatches(objectToFind.needle_img, kp1, keypoint_image, kp2, matches, None)
if match_points:
# find the center point of all the matched features
center_point = objectToFind.centeroid(match_points)
# account for the width of the needle image that appears on the left
center_point[0] += objectToFind.needle_w
# drawn the found center point on the output image
match_image = objectToFind.draw_crosshairs(match_image, [center_point])
# move somewhere/do something
#py.moveTo(center_point)
# display the processed image
cv.imshow('Keypoint Search', match_image)
# press 'q' with the output window focused to exit.
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
while(True):
ships_to_avoid = loadImages(avoid)
keypoint_detection(ships_to_avoid)
class Vision:
# properties
needle_img = None
needle_w = 0
needle_h = 0
# constructor
def __init__(self, needle_img_path):
self.needle_img = needle_img_path
# Save the dimensions of the needle image
self.needle_w = self.needle_img.shape[1]
self.needle_h = self.needle_img.shape[0]
def match_keypoints(self, original_image, patch_size=32):
min_match_count = 35
orb = cv.ORB_create(edgeThreshold=0, patchSize=patch_size)
keypoints_needle, descriptors_needle = orb.detectAndCompute(self.needle_img, None)
orb2 = cv.ORB_create(edgeThreshold=0, patchSize=patch_size, nfeatures=2000)
keypoints_haystack, descriptors_haystack = orb2.detectAndCompute(original_image, None)
FLANN_INDEX_LSH = 6
index_params = dict(algorithm=FLANN_INDEX_LSH, table_number=6, key_size=12, multi_probe_level=1)
search_params = dict(checks=50)
try:
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(descriptors_needle, descriptors_haystack, k=2)
except cv.error:
return None, None, [], [], None
# store all the good matches as per Lowe's ratio test.
good = []
points = []
for pair in matches:
if len(pair) == 2:
if pair[0].distance < 0.7*pair[1].distance:
good.append(pair[0])
if len(good) > min_match_count:
print('match %03d, kp %03d' % (len(good), len(keypoints_needle)))
for match in good:
points.append(keypoints_haystack[match.trainIdx].pt)
return keypoints_needle, keypoints_haystack, good, points
class WindowCapture:
# properties
w = 0
h = 0
hwnd = None
cropped_x = 0
cropped_y = 0
offset_x = 0
offset_y = 0
# constructor
def __init__(self, window_name=None):
# find the handle for the window we want to capture.
# if no window name is given, capture the entire screen
if window_name is None:
self.hwnd = win32gui.GetDesktopWindow()
else:
self.hwnd = win32gui.FindWindow(None, window_name)
if not self.hwnd:
raise Exception('Window not found: {}'.format(window_name))
# get the window size
window_rect = win32gui.GetWindowRect(self.hwnd)
self.w = window_rect[2] - window_rect[0]
self.h = window_rect[3] - window_rect[1]
# account for the window border and titlebar and cut them off
border_pixels = 0
titlebar_pixels = 0
self.w = self.w - (border_pixels * 2)
self.h = self.h - titlebar_pixels - border_pixels
self.cropped_x = border_pixels
self.cropped_y = titlebar_pixels
self.offset_x = window_rect[0] + self.cropped_x
self.offset_y = window_rect[1] + self.cropped_y
def get_haystack(self):
# get the window image data
wDC = win32gui.GetWindowDC(self.hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)
signedIntsArray = dataBitMap.GetBitmapBits(True)
img = np.fromstring(signedIntsArray, dtype='uint8')
img.shape = (self.h, self.w, 4)
# free resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(self.hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
img = img[...,:3]
img = np.ascontiguousarray(img)
return img
在 match_keypoints
中你有(至少)两个 return
语句。
其中一个,在except
块中returns 5个元素,None, None, [], [], None
.
其他returns 4个元素,return keypoints_needle, keypoints_haystack, good, points
因此,每当 match_keypoints
在那个 try
块中遇到 cv.error
时,它将 return 5 个元素,这比你试图在该行中取消引用多一个那是失败的:kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_image)
Too many values to unpack
是当 returned 元组的元素多于分配的 LHS 上的变量数时发生的错误。