【问题标题】:(-215:Assertion failed) corr.rows <= img.rows + templ.rows - 1 && corr.cols <= img.cols + templ.cols - 1 in function 'cv::crossCorr' (matchTemplate)(-215: 断言失败) corr.rows <= img.rows + templ.rows - 1 && corr.cols <= img.cols + templ.cols - 1 in function 'cv::crossCorr' (matchTemplate)
【发布时间】:2021-10-07 02:00:56
【问题描述】:

我在尝试获取应用程序的实时视频流时遇到了win32gui 的问题。我已经看到我可以使用 PIL 的 ImageGrab 并且基于此视频 Computer Screen Recording using Python & OpenCV 我想我可以使用它而不是 win32gui

我正在尝试通过编写一个机器人来学习 python,下面的代码应该从指定的文件夹中获取图像,将它们加载到一个数组中,将它们转换为 OpenCV 可以使用的格式,然后尝试找到它们中的任何一个或全部在我的应用程序窗口haystack

我在谷歌上找不到任何关于我遇到的错误的详细信息:

C:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips>C:/Users/coyle/AppData/Local/Programs/Python/Python39/python.exe c:/Users/coyle/OneDrive/froggy-pirate-master/avoidShips/avoidships4.py
Traceback (most recent call last):
  File "c:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips\avoidships4.py", line 41, in <module>
    loadImages()
  File "c:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips\avoidships4.py", line 22, in loadImages
    return matchTemplate(image_list)
  File "c:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips\avoidships4.py", line 32, in matchTemplate
    result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)
cv2.error: OpenCV(4.5.1) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-wvn_it83\opencv\modules\imgproc\src\templmatch.cpp:588: error: (-215:Assertion failed) corr.rows <= img.rows + templ.rows - 1 && corr.cols <= img.cols + templ.cols - 1 in function 'cv::crossCorr'

还有我的代码:

def loadImages():
    # Intialise empty array
    image_list = []
    # Get list of all images in directory
    directory = glob.glob(r"C:\Users\*.png")

    # Add images to image_list
    for img in directory:
        ship_img = cv.imread(img, 0)
        image_list.append(ship_img)
    return matchTemplate(image_list)

def matchTemplate(image_list):
    # Video Loop
    while True:
        haystack_img = ImageGrab.grab()
        haystack_img_np = np.array(haystack_img)
        haystack = cv.cvtColor(haystack_img_np, cv.COLOR_BGR2GRAY)
        
        # Object Detection
        for ships in image_list:
            needle_img = cv.imread(str(image_list), cv.IMREAD_UNCHANGED)
            result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)
            cv.imshow('Result', haystack)

            if cv.waitKey(1) == 27:
                break

        cv.destroyAllWindows()

loadImages()
matchTemplate()

作为测试,我尝试过使用静态图像做同样的事情,它确实有效,所以我不确定我哪里出错了。

import cv2 as cv
import glob

# load source images
directory = glob.glob(r'C:\Users\*.jpg')
# empty list to store the source images
image_list = []

for img in directory:
    ships_img = cv.imread(img, 0)
    image_list.append(ships_img)

haystack_img = cv.imread(r'C:\Users\both.jpg')
haystack_img = cv.cvtColor(haystack_img, cv.COLOR_BGR2GRAY)

#loop for matching
for ships in image_list:
    
    #save the dimensions of the needle images
    (H, W) = ships.shape[:2]
    result = cv.matchTemplate(haystack_img, ships, cv.TM_CCOEFF)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
    top_left = max_loc
    
    bottom_right = (top_left[0] + W, top_left[1] + H)
    cv.rectangle(haystack_img, top_left, bottom_right, 255, 2)

cv.imshow('Result', haystack_img)
cv.waitKey(0)

【问题讨论】:

  • 异常说模板太大,或者干草堆太小。在异常发生时检查 haystack 和 needle_img 的形状(总是在调用之前打印它们)
  • 上一个问题(没有接受的答案和很多混乱......),标题与我给出的这个问题相同:stackoverflow.com/questions/68225508/…
  • 在将ImageGrab 转换为我的np 数组并且python 窗口正确打开后,我被cv.imshow("Screen", haystack_img_np) 倾倒,但它立即(不显示任何内容)没有响应。任何想法@ChristophRackwitz
  • 我在新脚本中的函数之外做了一些测试(函数似乎总是给我带来问题),问题肯定是result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)当我按照你的建议打印(needle_img)时我回来了none,所以我认为我的问题是我如何读取图像,因为image_list 在调试器中显示为数组,即array([[70, 70, 70, ..., 46, 46, 46],
  • 所以?继续调查 None 结果。使用os.path.isfile。继续前进。

标签: python opencv computer-vision


【解决方案1】:

我无法对其进行测试,但您只需尝试加载内存中已有的图像

你有

needle_img = cv.imread(str(image_list), cv.IMREAD_UNCHANGED)

但是image_list 已经加载了图像,而不是文件名。
除了imread() 需要sinlge filename 但你尝试使用它与一些list 转换为字符串。

你应该直接使用

needle_img = ships

我觉得应该是的

def loadImages():
    # Intialise empty array
    image_list = []
    
    # Get list of all images in directory
    directory = glob.glob(r"C:\Users\*.png")

    # Add images to image_list
    for img in directory:
        ship_img = cv.imread(img, 0)  # <-- here you load all images
        image_list.append(ship_img)
        
    return image_list   # I preferr to send back data instead of running `matchTemplate`


def matchTemplate(image_list):
    # Video Loop
    while True:
        haystack_img = ImageGrab.grab()
        haystack_img_np = np.array(haystack_img)
        haystack = cv.cvtColor(haystack_img_np, cv.COLOR_BGR2GRAY)
        
        # Object Detection
        for ships in image_list:
            # you don't have to load images because you already have them in `image_list`
            #needle_img = cv.imread(str(image_list), cv.IMREAD_UNCHANGED)
            
            needle_img = ships
            
            result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)
            cv.imshow('Result', haystack)

            if cv.waitKey(1) == 27:
                break

        cv.destroyAllWindows()

# --- main ---

image_list = loadImages()
matchTemplate(image_list)

顺便说一句:

在正常的open()read() 中,如果打开或读取文件有问题,则会出现错误,但在 OpenCV 中,imread() 在无法加载图像时不会引发错误,但会给出None - 但是您不检查是否收到None - 而且您不知道加载它有问题 - 稍后当您尝试在下一个命令(matchTemplate)中使用此值时,它会显示错误。但真正的问题是imread()

【讨论】:

  • 感谢@Furas 提供的详细信息,我今天稍后再看一下,但现在一切都说得通!谢谢!
  • 是的,成功了。这一切都说得通。它正在工作!不知道如何加快窗口捕获,它非常慢。谢谢!
猜你喜欢
  • 2021-09-14
  • 2020-10-23
  • 2020-08-21
  • 1970-01-01
  • 2020-12-13
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多